[cfe-commits] r103783 - in /cfe/trunk: lib/Parse/ParseDecl.cpp test/Parser/recovery.c

Chris Lattner sabre at nondot.org
Fri May 14 10:44:56 PDT 2010


Author: lattner
Date: Fri May 14 12:44:56 2010
New Revision: 103783

URL: http://llvm.org/viewvc/llvm-project?rev=103783&view=rev
Log:
Improve error recovery in C/ObjC when the first argument of a function
declarator is incorrect.  Not being a typename causes the parser to 
dive down into the K&R identifier list handling stuff, which is almost
never the right thing to do.

Before:

r.c:3:17: error: expected ')'
void bar(intptr y);
                ^
r.c:3:9: note: to match this '('
void bar(intptr y);
        ^
r.c:3:10: error: a parameter list without types is only allowed in a function definition
void bar(intptr y);
         ^

After:

r.c:3:10: error: unknown type name 'intptr'; did you mean 'intptr_t'?
void bar(intptr y);
         ^~~~~~
         intptr_t
r.c:1:13: note: 'intptr_t' declared here
typedef int intptr_t;
            ^

This fixes rdar://7980651 - poor recovery for bad type in the first arg of a C function


Modified:
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/test/Parser/recovery.c

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=103783&r1=103782&r2=103783&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Fri May 14 12:44:56 2010
@@ -2941,12 +2941,29 @@
       // Identifier list.  Note that '(' identifier-list ')' is only allowed for
       // normal declarators, not for abstract-declarators.  Get the first
       // identifier.
-      IdentifierInfo *FirstIdent = Tok.getIdentifierInfo();
-      SourceLocation FirstIdentLoc = Tok.getLocation();
+      Token FirstTok = Tok;
       ConsumeToken();  // eat the first identifier.
-
-      return ParseFunctionDeclaratorIdentifierList(LParenLoc, FirstIdent,
-                                                   FirstIdentLoc, D);
+      
+      // Identifier lists follow a really simple grammar: the identifiers can
+      // be followed *only* by a ", moreidentifiers" or ")".  However, K&R
+      // identifier lists are really rare in the brave new modern world, and it
+      // is very common for someone to typo a type in a non-k&r style list.  If
+      // we are presented with something like: "void foo(intptr x, float y)",
+      // we don't want to start parsing the function declarator as though it is
+      // a K&R style declarator just because intptr is an invalid type.
+      //
+      // To handle this, we check to see if the token after the first identifier
+      // is a "," or ")".  Only if so, do we parse it as an identifier list.
+      if (Tok.is(tok::comma) || Tok.is(tok::r_paren))
+        return ParseFunctionDeclaratorIdentifierList(LParenLoc,
+                                                   FirstTok.getIdentifierInfo(),
+                                                     FirstTok.getLocation(), D);
+      
+      // If we get here, the code is invalid.  Push the first identifier back
+      // into the token stream and parse the first argument as an (invalid)
+      // normal argument declarator.
+      PP.EnterToken(Tok);
+      Tok = FirstTok;
     }
   }
 

Modified: cfe/trunk/test/Parser/recovery.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/recovery.c?rev=103783&r1=103782&r2=103783&view=diff
==============================================================================
--- cfe/trunk/test/Parser/recovery.c (original)
+++ cfe/trunk/test/Parser/recovery.c Fri May 14 12:44:56 2010
@@ -73,3 +73,8 @@
   int X;
   X = 4 // expected-error{{expected ';' after expression}}
 }
+
+
+// rdar://7980651
+typedef int intptr_t;  // expected-note {{'intptr_t' declared here}}
+void bar(intptr y);     // expected-error {{unknown type name 'intptr'; did you mean 'intptr_t'?}}





More information about the cfe-commits mailing list