This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
cpplib: Diagnostic improvements
- To: gcc-patches at gcc dot gnu dot org
- Subject: cpplib: Diagnostic improvements
- From: Neil Booth <neil at daikokuya dot demon dot co dot uk>
- Date: Sun, 10 Dec 2000 00:33:34 +0000
Diagnostics were a bit flaky in unusual situations.
I decided that for _Pragma buffers, we want to print the location as
"foo.c:5:8: _Pragma:", where foo.c is file containing the _Pragma (one
buffer below in the stack; hence the complications). For diagnostics
relating to builtins and command line options, I decided to print
"<command line>:" or "<builtin>:"; i.e. no line and column numbers.
The logic in cpperror.c for printing the include stack was made a bit
clearer in the process.
The patch makes the type of a buffer explicit; removing the last
places where cpplib could wrongly assume the type of a buffer.
Also other miscellaneous cleanups.
Neil.
* cpperror.c (print_location): New function.
(print_containing_files): Simplify.
(_cpp_begin_message): Simplify and use print_location.
* cppfiles.c (stack_include_file): Update.
(_cpp_pop_file_buffer): Update.
* cpphash.h (struct cpp_buffer): New members
include_stack_listed and type.
* cpplib.c (_cpp_handle_directive): Buffer->inc is not null.
(run_directive): Take buffer type. cpp_push_buffer cannot fail.
(_cpp_do__Pragma, cpp_define, _cpp_define_builtin, cpp_undef,
handle_assertion): Update.
(cpp_push_buffer): Take a buffer type and file name.
(cpp_pop_buffer): Update. Clear include_stack_listed.
* cpplib.h (input_stack_listing_current): Remove.
(enum cpp_buffer_type): New.
(cpp_push_buffer): New prototype.
* cppmacro.c (builtin_macro): Simplify; buffer cannot be null.
* fix-header.c (read_scan_file): Update.
* gcc.dg/cpp/if-2.c: Separate tests so that which failed is obvious.
Index: cpperror.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpperror.c,v
retrieving revision 1.41
diff -u -p -r1.41 cpperror.c
--- cpperror.c 2000/11/17 19:21:15 1.41
+++ cpperror.c 2000/12/10 00:13:57
@@ -29,30 +29,23 @@ Foundation, 59 Temple Place - Suite 330,
#include "cpphash.h"
#include "intl.h"
-static void print_containing_files PARAMS ((cpp_reader *, cpp_buffer *));
-static void print_file_and_line PARAMS ((const char *, unsigned int,
- unsigned int));
-
+static void print_containing_files PARAMS ((cpp_buffer *));
+static void print_location PARAMS ((cpp_reader *,
+ const char *,
+ const cpp_lexer_pos *));
#define v_message(msgid, ap) \
do { vfprintf (stderr, _(msgid), ap); putc ('\n', stderr); } while (0)
/* Print the file names and line numbers of the #include
commands which led to the current file. */
-
static void
-print_containing_files (pfile, ip)
- cpp_reader *pfile;
+print_containing_files (ip)
cpp_buffer *ip;
{
int first = 1;
- /* If stack of files hasn't changed since we last printed
- this info, don't repeat it. */
- if (pfile->input_stack_listing_current)
- return;
-
/* Find the other, outer source files. */
- for (ip = CPP_PREV_BUFFER (ip); ip != NULL; ip = CPP_PREV_BUFFER (ip))
+ for (ip = ip->prev; ip; ip = ip->prev)
{
if (first)
{
@@ -78,27 +71,69 @@ print_containing_files (pfile, ip)
fprintf (stderr, _(",\n from %s:%u"),
ip->nominal_fname, CPP_BUF_LINE (ip) - 1);
}
- if (first == 0)
- fputs (":\n", stderr);
-
- /* Record we have printed the status as of this time. */
- pfile->input_stack_listing_current = 1;
+ fputs (":\n", stderr);
}
static void
-print_file_and_line (filename, line, col)
+print_location (pfile, filename, pos)
+ cpp_reader *pfile;
const char *filename;
- unsigned int line, col;
+ const cpp_lexer_pos *pos;
{
- if (filename == 0 || *filename == '\0')
- filename = "<stdin>";
+ cpp_buffer *buffer = pfile->buffer;
- if (line == 0)
- fprintf (stderr, "%s: ", filename);
- else if (col == 0)
- fprintf (stderr, "%s:%u: ", filename, line);
+ if (!buffer)
+ fprintf (stderr, "%s: ", progname);
else
- fprintf (stderr, "%s:%u:%u: ", filename, line, col);
+ {
+ unsigned int line, col;
+ enum cpp_buffer_type type = buffer->type;
+
+ /* For _Pragma buffers, we want to print the location as
+ "foo.c:5:8: _Pragma:", where foo.c is the containing buffer.
+ For diagnostics relating to command line options, we want to
+ print "<command line>:" with no line number. */
+ if (type == BUF_CL_OPTION || type == BUF_BUILTIN)
+ line = 0;
+ else
+ {
+ if (type == BUF_PRAGMA)
+ {
+ buffer = buffer->prev;
+ line = CPP_BUF_LINE (buffer);
+ col = CPP_BUF_COL (buffer);
+ }
+ else
+ {
+ if (pos == 0)
+ pos = cpp_get_line (pfile);
+ line = pos->line;
+ col = pos->col;
+ }
+
+ /* Don't repeat the include stack unnecessarily. */
+ if (buffer->prev && ! buffer->include_stack_listed)
+ {
+ buffer->include_stack_listed = 1;
+ print_containing_files (buffer);
+ }
+ }
+
+ if (filename == 0)
+ filename = buffer->nominal_fname;
+ if (*filename == '\0')
+ filename = _("<stdin>");
+
+ if (line == 0)
+ fprintf (stderr, "%s: ", filename);
+ else if (CPP_OPTION (pfile, show_column) == 0)
+ fprintf (stderr, "%s:%u: ", filename, line);
+ else
+ fprintf (stderr, "%s:%u:%u: ", filename, line, col);
+
+ if (type == BUF_PRAGMA)
+ fprintf (stderr, "_Pragma: ");
+ }
}
/* Set up for an error message: print the file and line, bump the error
@@ -112,7 +147,6 @@ _cpp_begin_message (pfile, code, file, p
const char *file;
const cpp_lexer_pos *pos;
{
- cpp_buffer *ip = CPP_BUFFER (pfile);
int is_warning = 0;
switch (code)
@@ -170,20 +204,8 @@ _cpp_begin_message (pfile, code, file, p
pfile->errors = CPP_FATAL_LIMIT;
break;
}
-
- if (ip)
- {
- if (file == NULL)
- file = ip->nominal_fname;
- if (pos == 0)
- pos = cpp_get_line (pfile);
- print_containing_files (pfile, ip);
- print_file_and_line (file, pos->line,
- CPP_OPTION (pfile, show_column) ? pos->col : 0);
- }
- else
- fprintf (stderr, "%s: ", progname);
+ print_location (pfile, file, pos);
if (is_warning)
fputs (_("warning: "), stderr);
Index: cppfiles.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cppfiles.c,v
retrieving revision 1.91
diff -u -p -r1.91 cppfiles.c
--- cppfiles.c 2000/12/09 12:06:36 1.91
+++ cppfiles.c 2000/12/10 00:14:00
@@ -264,9 +264,8 @@ stack_include_file (pfile, inc)
read_include_file (pfile, inc);
/* Push a null buffer. */
- fp = cpp_push_buffer (pfile, NULL, 0);
+ fp = cpp_push_buffer (pfile, NULL, 0, BUF_FILE, inc->name);
fp->inc = inc;
- fp->nominal_fname = inc->name;
fp->buf = inc->buffer;
fp->rlimit = fp->buf;
if (! DO_NOT_REREAD (inc))
@@ -287,7 +286,6 @@ stack_include_file (pfile, inc)
pfile->mi_state = MI_OUTSIDE;
pfile->mi_cmacro = 0;
pfile->include_depth++;
- pfile->input_stack_listing_current = 0;
_cpp_do_file_change (pfile, FC_ENTER, filename, lineno);
@@ -775,7 +773,6 @@ _cpp_pop_file_buffer (pfile, buf)
pfile->system_include_depth--;
if (pfile->include_depth)
pfile->include_depth--;
- pfile->input_stack_listing_current = 0;
/* Record the inclusion-preventing macro and its definedness. */
if (pfile->mi_state == MI_OUTSIDE && inc->cmacro != NEVER_REREAD)
Index: cpphash.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpphash.h,v
retrieving revision 1.87
diff -u -p -r1.87 cpphash.h
--- cpphash.h 2000/12/09 12:06:37 1.87
+++ cpphash.h 2000/12/10 00:14:01
@@ -122,6 +122,13 @@ struct cpp_buffer
/* 1 = system header file, 2 = C system header file used for C++. */
unsigned char sysp;
+
+ /* Nonzero means we have printed (while error reporting) a list of
+ containing files that matches the current status. */
+ unsigned char include_stack_listed;
+
+ /* Buffer type. */
+ ENUM_BITFIELD (cpp_buffer_type) type : 8;
};
/* Character classes. Based on the more primitive macros in safe-ctype.h.
Index: cpplib.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpplib.c,v
retrieving revision 1.230
diff -u -p -r1.230 cpplib.c
--- cpplib.c 2000/12/09 12:06:37 1.230
+++ cpplib.c 2000/12/10 00:14:08
@@ -84,8 +84,8 @@ static void check_eol PARAMS ((cpp_read
static void start_directive PARAMS ((cpp_reader *));
static void end_directive PARAMS ((cpp_reader *, int));
static void run_directive PARAMS ((cpp_reader *, int,
- const char *, size_t,
- const char *));
+ enum cpp_buffer_type,
+ const char *, size_t));
static int glue_header_name PARAMS ((cpp_reader *, cpp_token *));
static int parse_include PARAMS ((cpp_reader *, cpp_token *));
static void push_conditional PARAMS ((cpp_reader *, int, int,
@@ -299,8 +299,7 @@ _cpp_handle_directive (pfile, indented)
dir = &dtable[T_LINE];
pfile->state.line_extension = 1;
_cpp_push_token (pfile, &dname, &pfile->directive_pos);
- if (CPP_PEDANTIC (pfile) && buffer->inc
- && ! CPP_OPTION (pfile, preprocessed))
+ if (CPP_PEDANTIC (pfile) && ! CPP_OPTION (pfile, preprocessed))
cpp_pedwarn (pfile, "# followed by integer");
}
}
@@ -374,47 +373,34 @@ _cpp_handle_directive (pfile, indented)
/* Directive handler wrapper used by the command line option
processor. */
static void
-run_directive (pfile, dir_no, buf, count, name)
+run_directive (pfile, dir_no, type, buf, count)
cpp_reader *pfile;
int dir_no;
+ enum cpp_buffer_type type;
const char *buf;
size_t count;
- const char *name;
{
unsigned int output_line = pfile->lexer_pos.output_line;
- cpp_buffer *buffer = cpp_push_buffer (pfile, (const U_CHAR *) buf, count);
-
- if (buffer)
- {
- const struct directive *dir = &dtable[dir_no];
+ cpp_buffer *buffer;
- if (name)
- buffer->nominal_fname = name;
- else
- buffer->nominal_fname = _("<command line>");
+ buffer = cpp_push_buffer (pfile, (const U_CHAR *) buf, count, type, 0);
- /* For _Pragma, the text is passed through preprocessing stage 3
- only, i.e. no trigraphs, no escaped newline removal, and no
- macro expansion. Do the same for command-line directives. */
- buffer->from_stage3 = 1;
-
- if (dir_no == T_PRAGMA)
- {
- /* A kludge to avoid line markers for _Pragma. */
- pfile->lexer_pos.output_line = output_line;
- /* Avoid interpretation of directives in a _Pragma string. */
- pfile->state.next_bol = 0;
- }
+ if (dir_no == T_PRAGMA)
+ {
+ /* A kludge to avoid line markers for _Pragma. */
+ pfile->lexer_pos.output_line = output_line;
+ /* Avoid interpretation of directives in a _Pragma string. */
+ pfile->state.next_bol = 0;
+ }
- start_directive (pfile);
- pfile->state.prevent_expansion++;
- (void) (*dir->handler) (pfile);
- pfile->state.prevent_expansion--;
- check_eol (pfile);
- end_directive (pfile, 1);
+ start_directive (pfile);
+ pfile->state.prevent_expansion++;
+ (void) (*dtable[dir_no].handler) (pfile);
+ pfile->state.prevent_expansion--;
+ check_eol (pfile);
+ end_directive (pfile, 1);
- cpp_pop_buffer (pfile);
- }
+ cpp_pop_buffer (pfile);
}
/* Checks for validity the macro name in #define, #undef, #ifdef and
@@ -1165,7 +1151,7 @@ _cpp_do__Pragma (pfile)
}
buffer = destringize (&string.val.str, &len);
- run_directive (pfile, T_PRAGMA, (char *) buffer, len, _("<_Pragma>"));
+ run_directive (pfile, T_PRAGMA, BUF_PRAGMA, (char *) buffer, len);
free ((PTR) buffer);
}
@@ -1633,7 +1619,7 @@ cpp_define (pfile, str)
buf[count++] = '1';
}
- run_directive (pfile, T_DEFINE, buf, count, 0);
+ run_directive (pfile, T_DEFINE, BUF_CL_OPTION, buf, count);
}
/* Slight variant of the above for use by initialize_builtins, which (a)
@@ -1644,7 +1630,7 @@ _cpp_define_builtin (pfile, str)
cpp_reader *pfile;
const char *str;
{
- run_directive (pfile, T_DEFINE, str, strlen (str), _("<builtin>"));
+ run_directive (pfile, T_DEFINE, BUF_BUILTIN, str, strlen (str));
}
/* Process MACRO as if it appeared as the body of an #undef. */
@@ -1653,7 +1639,7 @@ cpp_undef (pfile, macro)
cpp_reader *pfile;
const char *macro;
{
- run_directive (pfile, T_UNDEF, macro, strlen (macro), 0);
+ run_directive (pfile, T_UNDEF, BUF_CL_OPTION, macro, strlen (macro));
}
/* Process the string STR as if it appeared as the body of a #assert. */
@@ -1696,37 +1682,51 @@ handle_assertion (pfile, str, type)
str = buf;
}
- run_directive (pfile, type, str, count, 0);
+ run_directive (pfile, type, BUF_CL_OPTION, str, count);
}
/* Push a new buffer on the buffer stack. Buffer can be NULL, but
then LEN should be 0. Returns the new buffer; it doesn't fail. */
cpp_buffer *
-cpp_push_buffer (pfile, buffer, len)
+cpp_push_buffer (pfile, buffer, len, type, filename)
cpp_reader *pfile;
const U_CHAR *buffer;
size_t len;
+ enum cpp_buffer_type type;
+ const char *filename;
{
cpp_buffer *new = xobnew (pfile->buffer_ob, cpp_buffer);
/* Clears, amongst other things, if_stack and mi_cmacro. */
memset (new, 0, sizeof (cpp_buffer));
+
+ switch (type)
+ {
+ case BUF_FILE: new->nominal_fname = filename; break;
+ case BUF_BUILTIN: new->nominal_fname = _("<builtin>"); break;
+ case BUF_CL_OPTION: new->nominal_fname = _("<command line>"); break;
+ case BUF_PRAGMA: new->nominal_fname = _("<_Pragma>"); break;
+ }
+ new->type = type;
new->line_base = new->buf = new->cur = buffer;
new->rlimit = buffer + len;
new->prev = pfile->buffer;
new->pfile = pfile;
- /* Preprocessed files don't do trigraph and escaped newline processing. */
- new->from_stage3 = CPP_OPTION (pfile, preprocessed);
+
/* No read ahead or extra char initially. */
new->read_ahead = EOF;
new->extra_char = EOF;
+ /* Preprocessed files, builtins, _Pragma and command line options
+ don't do trigraph and escaped newline processing. */
+ new->from_stage3 = type != BUF_FILE || CPP_OPTION (pfile, preprocessed);
+
pfile->state.next_bol = 1;
pfile->buffer_stack_depth++;
pfile->lexer_pos.output_line = 1;
-
pfile->buffer = new;
+
return new;
}
@@ -1738,7 +1738,7 @@ cpp_pop_buffer (pfile)
const char *filename = buffer->nominal_fname;
unsigned int lineno = buffer->lineno;
struct if_stack *ifs = buffer->if_stack;
- int wfb = (buffer->inc != 0);
+ int file_buffer_p = buffer->type == BUF_FILE;
/* Walk back up the conditional stack till we reach its level at
entry to this file, issuing error messages. */
@@ -1746,15 +1746,18 @@ cpp_pop_buffer (pfile)
cpp_error_with_line (pfile, ifs->pos.line, ifs->pos.col,
"unterminated #%s", dtable[ifs->type].name);
- if (wfb)
+ if (file_buffer_p)
_cpp_pop_file_buffer (pfile, buffer);
pfile->buffer = buffer->prev;
obstack_free (pfile->buffer_ob, buffer);
pfile->buffer_stack_depth--;
- if (pfile->buffer && wfb)
- _cpp_do_file_change (pfile, FC_LEAVE, filename, lineno);
+ if (pfile->buffer && file_buffer_p)
+ {
+ _cpp_do_file_change (pfile, FC_LEAVE, filename, lineno);
+ pfile->buffer->include_stack_listed = 0;
+ }
return pfile->buffer;
}
Index: cpplib.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cpplib.h,v
retrieving revision 1.148
diff -u -p -r1.148 cpplib.h
--- cpplib.h 2000/12/07 23:17:55 1.148
+++ cpplib.h 2000/12/10 00:14:09
@@ -606,10 +606,6 @@ struct cpp_reader
preprocessor. */
struct spec_nodes spec_nodes;
- /* Nonzero means we have printed (while error reporting) a list of
- containing files that matches the current status. */
- unsigned char input_stack_listing_current;
-
/* We're printed a warning recommending against using #import. */
unsigned char import_warning;
@@ -634,6 +630,10 @@ struct cpp_reader
/* Name under which this program was invoked. */
extern const char *progname;
+/* Where does this buffer come from? A file, a builtin macro, a
+ command-line option, or a _Pragma operator. */
+enum cpp_buffer_type {BUF_FILE, BUF_BUILTIN, BUF_CL_OPTION, BUF_PRAGMA};
+
/* The structure of a node in the hash table. The hash table has
entries for all identifiers: either macros defined by #define
commands (type NT_MACRO), assertions created with #assert
@@ -729,7 +729,9 @@ extern void cpp_undef PARAMS ((cpp_read
extern void cpp_unassert PARAMS ((cpp_reader *, const char *));
extern cpp_buffer *cpp_push_buffer PARAMS ((cpp_reader *,
- const unsigned char *, size_t));
+ const unsigned char *, size_t,
+ enum cpp_buffer_type,
+ const char *));
extern cpp_buffer *cpp_pop_buffer PARAMS ((cpp_reader *));
extern int cpp_defined PARAMS ((cpp_reader *, const unsigned char *, int));
Index: cppmacro.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cppmacro.c,v
retrieving revision 1.35
diff -u -p -r1.35 cppmacro.c
--- cppmacro.c 2000/12/09 12:06:37 1.35
+++ cppmacro.c 2000/12/10 00:14:13
@@ -148,28 +148,22 @@ builtin_macro (pfile, token)
{
unsigned char flags = token->flags & PREV_WHITE;
cpp_hashnode *node = token->val.node;
- cpp_buffer *ip;
switch (node->value.builtin)
{
case BT_FILE:
case BT_BASE_FILE:
{
- const char *file;
+ const char *name;
+ cpp_buffer *buffer = pfile->buffer;
- ip = CPP_BUFFER (pfile);
- if (ip == 0)
- file = "";
- else
- {
- if (node->value.builtin == BT_BASE_FILE)
- while (CPP_PREV_BUFFER (ip) != NULL)
- ip = CPP_PREV_BUFFER (ip);
+ if (node->value.builtin == BT_BASE_FILE)
+ while (buffer->prev)
+ buffer = buffer->prev;
- file = ip->nominal_fname;
- }
+ name = buffer->nominal_fname;
make_string_token (pfile->string_pool, token,
- (const U_CHAR *) file, strlen (file));
+ (const unsigned char *) name, strlen (name));
}
break;
Index: fix-header.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fix-header.c,v
retrieving revision 1.56
diff -u -p -r1.56 fix-header.c
--- fix-header.c 2000/12/07 07:14:42 1.56
+++ fix-header.c 2000/12/10 00:14:17
@@ -651,7 +651,8 @@ read_scan_file (in_fname, argc, argv)
int seen_filbuf = 0;
/* Scan the macro expansion of "getchar();". */
- cpp_push_buffer (scan_in, getchar_call, sizeof(getchar_call) - 1);
+ cpp_push_buffer (scan_in, getchar_call, sizeof(getchar_call) - 1,
+ BUF_FILE, in_fname);
for (;;)
{
cpp_token t;
Index: testsuite/gcc.dg/cpp/if-2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/cpp/if-2.c,v
retrieving revision 1.1
diff -u -p -r1.1 if-2.c
--- if-2.c 2000/06/27 22:26:11 1.1
+++ if-2.c 2000/12/10 00:14:37
@@ -5,8 +5,12 @@
#error a,1,0x12 /* { dg-bogus "#error" "basic charconst recognition" } */
#endif
-#if 'a' != L'a' || L'\xfeed' != 0xfeed
-#error L'a',0xfeed /* { dg-bogus "#error" "wide charconst recognition" } */
+#if 'a' != L'a'
+#error L'a' /* { dg-bogus "error" "wide charconst recognition 1" } */
+#endif
+
+#if L'\xfeed' != 0xfeed
+#error 0xfeed /* { dg-bogus "error" "wide charconst recognition 2" } */
#endif
#if 'abcd' /* { dg-warning "multi-character character constant" "multi-character charconst" } */