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]
Other format: [Raw text]

PATCH for more precise column numbers in C/C++ parsers


Here is a patch to set the correct column numbers for variables
for both C and C++.  Example:

$ cat /tmp/foo.c
int f (int x)
{
  int   a22  ,  b1 , * b2 ;
  int   b1;
  return aaa + a22;
}
$ ./cc1plus /tmp/foo.c -o /tmp/foo.s -quiet -Wall
/tmp/foo.c: In function ‘int f(int)’:
/tmp/foo.c:4:9: error: redeclaration of ‘int b1’
/tmp/foo.c:3:17: error: ‘int b1’ previously declared here
/tmp/foo.c:5:10: error: ‘aaa’ was not declared in this scope
/tmp/foo.c:3:17: warning: unused variable ‘b1’
/tmp/foo.c:3:24: warning: unused variable ‘b2’

There are two parts to this patch:

The "generic" fix is to copy the cpp_token's location to the
c_token/cp_token, rather than use input_location.  The latter is
wrong, because of look-ahead.

The "specific" fix is to set DECL_SOURCE_LOCATION from the
location of the declared *namee*, rather than some random token
that is part of the declaration.  This part of the patch is
probably incomplete.  I've only tested local variable declarations,
though it is likely other declarations that use grokdeclarator
would work.

I do *not* consider it my job to hunt down and fix other places
in the front-ends where the wrong location is being used for
declarations or expressions.  I've provided a generic fix,
and fixed one of the places.  I'm guessing that in most cases
we're not talking about *wrong* locations, so much as imprecise
locations - i.e. quality-of-implementation issues rather than bugs.

I'm hoping that front-end maintainers and others will make a habit
of testing with --enable-mapped-location, and if people see
a bad line/column number fixing them or entering them in bugzilla.

While there is no explicit dependency on --enable-mapped-location,
note that location_t only contains a column number is that case.

Note that java is still broken with --enable-mapped-location.
I'll be working on that shortly.

I've done a bootstrap and make check and things seem sane.
However, I haven't yet done a test to see there are no regressions;
I thought I'd see if people have comments on the patch first.
--
	--Per Bothner
per@bothner.com   http://per.bothner.com/
2005-03-07  Per Bothner  <per@bothner.com>

	* c-tree.h (struct c_declarator): New id_loc field.
	* c-pragma.h (c_lex_with_flags): Take position reference.
	* c-lex.c (c_lex_with_flags): Set passed-in location from cpp token.
	(c_lex): Pass dummy location to c_lex_with_flags.
	* c-parser.c (c_lex_one_token): Set c_token's location using
	c_lex_with_flags, instead of input_location, which might be "ahead".
	(c_parser_direct_declarator): Set declarator's id_loc from
	c_token's id_loc.
	* c-decl.c (grokdeclarator): Set DECL_SOURCE_LOCATION from
	declarator's id_loc, rather than probably-imprecise input_location.
	(build_id_declarator): Initialize c_declarator's id_loc field.

2005-03-07  Per Bothner  <per@bothner.com>

	* cp-tree.h (struct cp_declarator): New id_loc field.
	* cp/parser.c (cp_lexer_get_preprocessor_token): Set cp_token's
	location using c_lex_with_flags, instead of input_location.
	(cp_parser_direct_declarator): Set declarator's id_loc from
	cp_token's id_loc.

Index: c-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-tree.h,v
retrieving revision 1.195
diff -u -p -r1.195 c-tree.h
--- c-tree.h	2 Mar 2005 02:50:18 -0000	1.195
+++ c-tree.h	8 Mar 2005 02:14:12 -0000
@@ -287,6 +287,7 @@ struct c_declarator {
   enum c_declarator_kind kind;
   /* Except for cdk_id, the contained declarator.  For cdk_id, NULL.  */
   struct c_declarator *declarator;
+  location_t id_loc; /* Currently only set for cdk_id. */
   union {
     /* For identifiers, an IDENTIFIER_NODE or NULL_TREE if an abstract
        declarator.  */
Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.633
diff -u -p -r1.633 c-decl.c
--- c-decl.c	7 Mar 2005 21:14:08 -0000	1.633
+++ c-decl.c	8 Mar 2005 02:14:19 -0000
@@ -4584,6 +4584,7 @@ grokdeclarator (const struct c_declarato
 	  }
 
 	decl = build_decl (VAR_DECL, declarator->u.id, type);
+	DECL_SOURCE_LOCATION (decl) = declarator->id_loc;
 	if (size_varies)
 	  C_DECL_VARIABLE_SIZE (decl) = 1;
 
@@ -6709,6 +6710,8 @@ build_id_declarator (tree ident)
   ret->kind = cdk_id;
   ret->declarator = 0;
   ret->u.id = ident;
+  /* Default value - may get reset to a more precise location. */
+  ret->id_loc = input_location;
   return ret;
 }
 
Index: c-lex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-lex.c,v
retrieving revision 1.242
diff -u -p -r1.242 c-lex.c
--- c-lex.c	27 Oct 2004 17:24:20 -0000	1.242
+++ c-lex.c	8 Mar 2005 02:14:20 -0000
@@ -332,7 +332,7 @@ cb_undef (cpp_reader * ARG_UNUSED (pfile
    non-NULL.  */
 
 enum cpp_ttype
-c_lex_with_flags (tree *value, unsigned char *cpp_flags)
+c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags)
 {
   static bool no_more_pch;
   const cpp_token *tok;
@@ -344,6 +344,7 @@ c_lex_with_flags (tree *value, unsigned 
   type = tok->type;
   
  retry_after_at:
+  *loc = tok->src_loc;
   switch (type)
     {
     case CPP_PADDING:
@@ -487,7 +488,8 @@ c_lex_with_flags (tree *value, unsigned 
 enum cpp_ttype
 c_lex (tree *value)
 {
-  return c_lex_with_flags (value, NULL);
+  location_t loc;
+  return c_lex_with_flags (value, &loc, NULL);
 }
 
 /* Returns the narrowest C-visible unsigned type, starting with the
Index: c-parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-parser.c,v
retrieving revision 2.4
diff -u -p -r2.4 c-parser.c
--- c-parser.c	7 Mar 2005 21:14:08 -0000	2.4
+++ c-parser.c	8 Mar 2005 02:14:21 -0000
@@ -295,8 +295,7 @@ static void
 c_lex_one_token (c_token *token)
 {
   timevar_push (TV_LEX);
-  token->type = c_lex (&token->value);
-  token->location = input_location;
+  token->type = c_lex_with_flags (&token->value, &token->location, NULL);
   token->in_system_header = in_system_header;
   switch (token->type)
     {
@@ -2179,6 +2178,7 @@ c_parser_direct_declarator (c_parser *pa
       struct c_declarator *inner
 	= build_id_declarator (c_parser_peek_token (parser)->value);
       *seen_id = true;
+      inner->id_loc = c_parser_peek_token (parser)->location;
       c_parser_consume_token (parser);
       return c_parser_direct_declarator_inner (parser, *seen_id, inner);
     }
Index: c-pragma.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-pragma.h,v
retrieving revision 1.45
diff -u -p -r1.45 c-pragma.h
--- c-pragma.h	29 Nov 2004 18:53:54 -0000	1.45
+++ c-pragma.h	8 Mar 2005 02:14:21 -0000
@@ -65,7 +65,7 @@ extern tree maybe_apply_renaming_pragma 
 extern void add_to_renaming_pragma_list (tree, tree);
 
 extern enum cpp_ttype c_lex (tree *);
-extern enum cpp_ttype c_lex_with_flags (tree *, unsigned char *);
+extern enum cpp_ttype c_lex_with_flags (tree *, location_t *, unsigned char *);
 
 /* If 1, then lex strings into the execution character set.  
    If 0, lex strings into the host character set.
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1107
diff -u -p -r1.1107 cp-tree.h
--- cp/cp-tree.h	1 Mar 2005 09:57:38 -0000	1.1107
+++ cp/cp-tree.h	8 Mar 2005 02:14:22 -0000
@@ -3597,6 +3597,7 @@ struct cp_declarator {
   /* For all but cdk_id and cdk_error, the contained declarator.  For
      cdk_id and cdk_error, guaranteed to be NULL.  */
   cp_declarator *declarator;
+  location_t id_loc; /* Currently only set for cdk_id. */
   union {
     /* For identifiers.  */
     struct {
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.319
diff -u -p -r1.319 parser.c
--- cp/parser.c	24 Feb 2005 21:55:15 -0000	1.319
+++ cp/parser.c	8 Mar 2005 02:14:34 -0000
@@ -380,8 +380,8 @@ cp_lexer_get_preprocessor_token (cp_lexe
   static int is_extern_c = 0;
 
    /* Get a new token from the preprocessor.  */
-  token->type = c_lex_with_flags (&token->value, &token->flags);
-  token->location = input_location;
+  token->type
+    = c_lex_with_flags (&token->value, &token->location, &token->flags);
   token->in_system_header = in_system_header;
 
   /* On some systems, some header files are surrounded by an 
@@ -11188,6 +11188,7 @@ cp_parser_direct_declarator (cp_parser* 
 
 	  declarator = make_id_declarator (qualifying_scope, 
 					   unqualified_name);
+	  declarator->id_loc = token->location;
 	  if (unqualified_name)
 	    {
 	      tree class_type;

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