[cfe-commits] r68288 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseDecl.cpp lib/Parse/ParseDeclCXX.cpp lib/Parse/ParseStmt.cpp lib/Parse/ParseTemplate.cpp lib/Parse/Parser.cpp

Chris Lattner sabre at nondot.org
Wed Apr 1 21:16:50 PDT 2009


Author: lattner
Date: Wed Apr  1 23:16:50 2009
New Revision: 68288

URL: http://llvm.org/viewvc/llvm-project?rev=68288&view=rev
Log:
fix a FIXME, providing accurate source range info for DeclStmt's.  The end
of the range is now the ';' location.  For something like this:

$ cat t2.c 

#define bool int
void f(int x, int y) {
bool b = !x && y;
}

We used to produce:
$ clang-cc t2.c -ast-dump 
typedef char *__builtin_va_list;

void f(int x, int y)
(CompoundStmt 0x2201f10 <t2.c:3:22, line:5:1>
  (DeclStmt 0x2201ef0 <line:2:14>                   <----
    0x2201a20 "int b =
      (BinaryOperator 0x2201ed0 <line:4:10, col:16> 'int' '&&'
        (UnaryOperator 0x2201e90 <col:10, col:11> 'int' prefix '!'
          (DeclRefExpr 0x2201c90 <col:11> 'int' ParmVar='x' 0x2201a50))
        (DeclRefExpr 0x2201eb0 <col:16> 'int' ParmVar='y' 0x2201e10))")


Now we produce:

$ clang-cc t2.c -ast-dump
typedef char *__builtin_va_list;

void f(int x, int y)
(CompoundStmt 0x2201f10 <t2.c:3:22, line:5:1>
  (DeclStmt 0x2201ef0 <line:2:14, line:4:17>         <------
    0x2201a20 "int b =
      (BinaryOperator 0x2201ed0 <col:10, col:16> 'int' '&&'
        (UnaryOperator 0x2201e90 <col:10, col:11> 'int' prefix '!'
          (DeclRefExpr 0x2201c90 <col:11> 'int' ParmVar='x' 0x2201a50))
        (DeclRefExpr 0x2201eb0 <col:16> 'int' ParmVar='y' 0x2201e10))")


Modified:
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/lib/Parse/ParseStmt.cpp
    cfe/trunk/lib/Parse/ParseTemplate.cpp
    cfe/trunk/lib/Parse/Parser.cpp

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=68288&r1=68287&r2=68288&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Wed Apr  1 23:16:50 2009
@@ -809,8 +809,9 @@
   //===--------------------------------------------------------------------===//
   // C99 6.7: Declarations.
   
-  DeclGroupPtrTy ParseDeclaration(unsigned Context);
+  DeclGroupPtrTy ParseDeclaration(unsigned Context, SourceLocation &DeclEnd);
   DeclGroupPtrTy ParseSimpleDeclaration(unsigned Context,
+                                        SourceLocation &DeclEnd,
                                         bool RequireSemi = true);
   DeclGroupPtrTy ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D);
   DeclPtrTy ParseFunctionStatementBody(DeclPtrTy Decl);
@@ -994,14 +995,18 @@
   //===--------------------------------------------------------------------===//
   // C++ 7: Declarations [dcl.dcl]
   
-  DeclPtrTy ParseNamespace(unsigned Context);
+  DeclPtrTy ParseNamespace(unsigned Context, SourceLocation &DeclEnd);
   DeclPtrTy ParseLinkage(unsigned Context);
-  DeclPtrTy ParseUsingDirectiveOrDeclaration(unsigned Context);
-  DeclPtrTy ParseUsingDirective(unsigned Context, SourceLocation UsingLoc);
-  DeclPtrTy ParseUsingDeclaration(unsigned Context, SourceLocation UsingLoc);
-  DeclPtrTy ParseStaticAssertDeclaration();
+  DeclPtrTy ParseUsingDirectiveOrDeclaration(unsigned Context,
+                                             SourceLocation &DeclEnd);
+  DeclPtrTy ParseUsingDirective(unsigned Context, SourceLocation UsingLoc,
+                                SourceLocation &DeclEnd);
+  DeclPtrTy ParseUsingDeclaration(unsigned Context, SourceLocation UsingLoc,
+                                  SourceLocation &DeclEnd);
+  DeclPtrTy ParseStaticAssertDeclaration(SourceLocation &DeclEnd);
   DeclPtrTy ParseNamespaceAlias(SourceLocation NamespaceLoc,
-                                SourceLocation AliasLoc, IdentifierInfo *Alias);
+                                SourceLocation AliasLoc, IdentifierInfo *Alias,
+                                SourceLocation &DeclEnd);
   
   //===--------------------------------------------------------------------===//
   // C++ 9: classes [class] and C structs/unions.
@@ -1035,6 +1040,7 @@
 
   // C++ 14.1: Template Parameters [temp.param]
   DeclPtrTy ParseTemplateDeclarationOrSpecialization(unsigned Context,
+                                                     SourceLocation &DeclEnd,
                                                    AccessSpecifier AS=AS_none);
   bool ParseTemplateParameters(unsigned Depth, 
                                TemplateParameterList &TemplateParams,

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=68288&r1=68287&r2=68288&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Wed Apr  1 23:16:50 2009
@@ -215,7 +215,8 @@
 
 /// ParseDeclaration - Parse a full 'declaration', which consists of
 /// declaration-specifiers, some number of declarators, and a semicolon.
-/// 'Context' should be a Declarator::TheContext value.
+/// 'Context' should be a Declarator::TheContext value.  This returns the
+/// location of the semicolon in DeclEnd.
 ///
 ///       declaration: [C99 6.7]
 ///         block-declaration ->
@@ -228,24 +229,25 @@
 /// [C++0x] static_assert-declaration
 ///         others... [FIXME]
 ///
-Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context) {
+Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context,
+                                                SourceLocation &DeclEnd) {
   DeclPtrTy SingleDecl;
   switch (Tok.getKind()) {
   case tok::kw_export:
   case tok::kw_template:
-    SingleDecl = ParseTemplateDeclarationOrSpecialization(Context);
+    SingleDecl = ParseTemplateDeclarationOrSpecialization(Context, DeclEnd);
     break;
   case tok::kw_namespace:
-    SingleDecl = ParseNamespace(Context);
+    SingleDecl = ParseNamespace(Context, DeclEnd);
     break;
   case tok::kw_using:
-    SingleDecl = ParseUsingDirectiveOrDeclaration(Context);
+    SingleDecl = ParseUsingDirectiveOrDeclaration(Context, DeclEnd);
     break;
   case tok::kw_static_assert:
-    SingleDecl = ParseStaticAssertDeclaration();
+    SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
     break;
   default:
-    return ParseSimpleDeclaration(Context);
+    return ParseSimpleDeclaration(Context, DeclEnd);
   }
   
   // This routine returns a DeclGroup, if the thing we parsed only contains a
@@ -261,6 +263,7 @@
 /// If RequireSemi is false, this does not check for a ';' at the end of the
 /// declaration.
 Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(unsigned Context,
+                                                      SourceLocation &DeclEnd,
                                                       bool RequireSemi) {
   // Parse the common declaration-specifiers piece.
   DeclSpec DS;
@@ -280,6 +283,8 @@
   DeclGroupPtrTy DG =
     ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo);
 
+  DeclEnd = Tok.getLocation();
+  
   // If the client wants to check what comes after the declaration, just return
   // immediately without checking anything!
   if (!RequireSemi) return DG;

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=68288&r1=68287&r2=68288&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Wed Apr  1 23:16:50 2009
@@ -42,7 +42,8 @@
 ///       namespace-alias-definition:  [C++ 7.3.2: namespace.alias]
 ///         'namespace' identifier '=' qualified-namespace-specifier ';'
 ///
-Parser::DeclPtrTy Parser::ParseNamespace(unsigned Context) {
+Parser::DeclPtrTy Parser::ParseNamespace(unsigned Context,
+                                         SourceLocation &DeclEnd) {
   assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
   SourceLocation NamespaceLoc = ConsumeToken();  // eat the 'namespace'.
   
@@ -62,7 +63,7 @@
   
   if (Tok.is(tok::equal))
     // FIXME: Verify no attributes were present.
-    return ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident);
+    return ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd);
   
   if (Tok.isNot(tok::l_brace)) {
     Diag(Tok, Ident ? diag::err_expected_lbrace : 
@@ -88,9 +89,10 @@
   // Leave the namespace scope.
   NamespaceScope.Exit();
 
-  SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
-  Actions.ActOnFinishNamespaceDef(NamespcDecl, RBrace);
+  SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBrace);
+  Actions.ActOnFinishNamespaceDef(NamespcDecl, RBraceLoc);
 
+  DeclEnd = RBraceLoc;
   return NamespcDecl;
 }
 
@@ -99,7 +101,8 @@
 ///
 Parser::DeclPtrTy Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc,
                                               SourceLocation AliasLoc, 
-                                              IdentifierInfo *Alias) {
+                                              IdentifierInfo *Alias,
+                                              SourceLocation &DeclEnd) {
   assert(Tok.is(tok::equal) && "Not equal token");
   
   ConsumeToken(); // eat the '='.
@@ -120,6 +123,7 @@
   SourceLocation IdentLoc = ConsumeToken();
   
   // Eat the ';'.
+  DeclEnd = Tok.getLocation();
   ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
                    "namespace name", tok::semi);
   
@@ -169,7 +173,8 @@
 
 /// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
 /// using-directive. Assumes that current token is 'using'.
-Parser::DeclPtrTy Parser::ParseUsingDirectiveOrDeclaration(unsigned Context) {
+Parser::DeclPtrTy Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
+                                                     SourceLocation &DeclEnd) {
   assert(Tok.is(tok::kw_using) && "Not using token");
 
   // Eat 'using'.
@@ -177,10 +182,10 @@
 
   if (Tok.is(tok::kw_namespace))
     // Next token after 'using' is 'namespace' so it must be using-directive
-    return ParseUsingDirective(Context, UsingLoc);
+    return ParseUsingDirective(Context, UsingLoc, DeclEnd);
 
   // Otherwise, it must be using-declaration.
-  return ParseUsingDeclaration(Context, UsingLoc);
+  return ParseUsingDeclaration(Context, UsingLoc, DeclEnd);
 }
 
 /// ParseUsingDirective - Parse C++ using-directive, assumes
@@ -194,7 +199,8 @@
 ///                 namespace-name attributes[opt] ;
 ///
 Parser::DeclPtrTy Parser::ParseUsingDirective(unsigned Context,
-                                              SourceLocation UsingLoc) {
+                                              SourceLocation UsingLoc,
+                                              SourceLocation &DeclEnd) {
   assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");
 
   // Eat 'namespace'.
@@ -226,6 +232,7 @@
     AttrList = ParseAttributes();
   
   // Eat ';'.
+  DeclEnd = Tok.getLocation();
   ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
                    AttrList ? "attributes list" : "namespace name", tok::semi);
 
@@ -242,7 +249,8 @@
 ///       'using' :: unqualified-id [TODO]
 ///
 Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context,
-                                                SourceLocation UsingLoc) {
+                                                SourceLocation UsingLoc,
+                                                SourceLocation &DeclEnd) {
   assert(false && "Not implemented");
   // FIXME: Implement parsing.
   return DeclPtrTy();
@@ -253,7 +261,7 @@
 ///      static_assert-declaration:
 ///        static_assert ( constant-expression  ,  string-literal  ) ;
 ///
-Parser::DeclPtrTy Parser::ParseStaticAssertDeclaration() {
+Parser::DeclPtrTy Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){
   assert(Tok.is(tok::kw_static_assert) && "Not a static_assert declaration");
   SourceLocation StaticAssertLoc = ConsumeToken();
   
@@ -285,6 +293,7 @@
 
   MatchRHSPunctuation(tok::r_paren, LParenLoc);
   
+  DeclEnd = Tok.getLocation();
   ExpectAndConsume(tok::semi, diag::err_expected_semi_after_static_assert);
 
   return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, move(AssertExpr), 
@@ -668,12 +677,15 @@
 void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
   // static_assert-declaration
   if (Tok.is(tok::kw_static_assert)) {
-    ParseStaticAssertDeclaration();
+    SourceLocation DeclEnd;
+    ParseStaticAssertDeclaration(DeclEnd);
     return;
   }
       
   if (Tok.is(tok::kw_template)) {
-    ParseTemplateDeclarationOrSpecialization(Declarator::MemberContext, AS);
+    SourceLocation DeclEnd;
+    ParseTemplateDeclarationOrSpecialization(Declarator::MemberContext, DeclEnd,
+                                             AS);
     return;
   }
 

Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=68288&r1=68287&r2=68288&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Wed Apr  1 23:16:50 2009
@@ -100,10 +100,9 @@
 
   default: {
     if ((getLang().CPlusPlus || !OnlyStatement) && isDeclarationStatement()) {
-      SourceLocation DeclStart = Tok.getLocation();
-      DeclGroupPtrTy Decl = ParseDeclaration(Declarator::BlockContext);
-      // FIXME: Pass in the right location for the end of the declstmt.
-      return Actions.ActOnDeclStmt(Decl, DeclStart, DeclStart);
+      SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
+      DeclGroupPtrTy Decl = ParseDeclaration(Declarator::BlockContext, DeclEnd);
+      return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
     }
 
     if (Tok.is(tok::r_brace)) {
@@ -442,11 +441,10 @@
 
       // If this is the start of a declaration, parse it as such.
       if (isDeclarationStatement()) {
-        // FIXME: Save the __extension__ on the decl as a node somehow.
-        SourceLocation DeclStart = Tok.getLocation();
-        DeclGroupPtrTy Res = ParseDeclaration(Declarator::BlockContext);
-        // FIXME: Pass in the right location for the end of the declstmt.
-        R = Actions.ActOnDeclStmt(Res, DeclStart, DeclStart);
+        // FIXME: Save the __extension__ on the decl as a node somehow?
+        SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
+        DeclGroupPtrTy Res = ParseDeclaration(Declarator::BlockContext,DeclEnd);
+        R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd);
       } else {
         // Otherwise this was a unary __extension__ marker.
         OwningExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc));
@@ -911,8 +909,9 @@
     if (!C99orCXX)   // Use of C99-style for loops in C90 mode?
       Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
 
-    SourceLocation DeclStart = Tok.getLocation();
-    DeclGroupPtrTy DG = ParseSimpleDeclaration(Declarator::ForContext, false);
+    SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
+    DeclGroupPtrTy DG = ParseSimpleDeclaration(Declarator::ForContext, DeclEnd,
+                                               false);
     FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
     
     if (Tok.is(tok::semi)) {  // for (int x = 4;

Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=68288&r1=68287&r2=68288&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Wed Apr  1 23:16:50 2009
@@ -35,6 +35,7 @@
 ///         'template' '<' '>' declaration
 Parser::DeclPtrTy
 Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context,
+                                                 SourceLocation &DeclEnd,
                                                  AccessSpecifier AS) {
   assert((Tok.is(tok::kw_export) || Tok.is(tok::kw_template)) && 
 	 "Token does not start a template declaration.");
@@ -99,6 +100,9 @@
   // FIXME: Converting DeclGroupPtr to DeclPtr like this is an insanely gruesome
   // hack, will bring up on cfe-dev.
   DeclGroupPtrTy DG = ParseDeclarationOrFunctionDefinition(&ParamLists, AS);
+  // FIXME: Should be ';' location not the token after it.  Resolve with above
+  // fixmes.
+  DeclEnd = Tok.getLocation();
   return DeclPtrTy::make(DG.get());
 }
 

Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=68288&r1=68287&r2=68288&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Wed Apr  1 23:16:50 2009
@@ -423,7 +423,10 @@
   case tok::kw_export:    // As in 'export template'
   case tok::kw_static_assert:
     // A function definition cannot start with a these keywords.
-    return ParseDeclaration(Declarator::FileContext);
+    {
+      SourceLocation DeclEnd;
+      return ParseDeclaration(Declarator::FileContext, DeclEnd);
+    }
   default:
     // We can't tell whether this is a function-definition or declaration yet.
     return ParseDeclarationOrFunctionDefinition();





More information about the cfe-commits mailing list