This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

cpplib: Diagnostic improvements


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" } */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]