[cfe-commits] r61650 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseExpr.cpp lib/Parse/ParseExprCXX.cpp lib/Parse/Parser.cpp

Chris Lattner sabre at nondot.org
Sun Jan 4 15:23:14 PST 2009


Author: lattner
Date: Sun Jan  4 17:23:14 2009
New Revision: 61650

URL: http://llvm.org/viewvc/llvm-project?rev=61650&view=rev
Log:
my previous patch caused sema to drop the global qualifier, make
sure to pass it down.  This makes the code a bit gross, I will clean
it up in subsequent commits.




Modified:
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/ParseExpr.cpp
    cfe/trunk/lib/Parse/ParseExprCXX.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=61650&r1=61649&r2=61650&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Sun Jan  4 17:23:14 2009
@@ -267,7 +267,9 @@
   /// (if they are typenames). For example, in C we do not expect identifiers
   /// inside expressions to be treated as typenames so it will not be called
   /// for expressions in C.
-  void TryAnnotateTypeOrScopeToken();
+  ///
+  /// This returns true if the token was annotated.
+  bool TryAnnotateTypeOrScopeToken(const Token *GlobalQualifier = 0);
 
   /// TryAnnotateCXXScopeToken - Like TryAnnotateTypeOrScopeToken but only
   /// annotates C++ scope specifiers.
@@ -607,7 +609,11 @@
 
   /// MaybeParseCXXScopeSpecifier - Parse global scope or nested-name-specifier.
   /// Returns true if a nested-name-specifier was parsed from the token stream.
-  bool MaybeParseCXXScopeSpecifier(CXXScopeSpec &SS);
+  ///
+  /// If GlobalQualifier is non-null, then it is a :: token we should use as the
+  /// global qualifier.
+  bool MaybeParseCXXScopeSpecifier(CXXScopeSpec &SS,
+                                   const Token *GlobalQualifier = 0);
   
   //===--------------------------------------------------------------------===//
   // C++ 5.2p1: C++ Casts

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

==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Sun Jan  4 17:23:14 2009
@@ -478,12 +478,14 @@
                                // constant: enumeration-constant
     // Turn a potentially qualified name into a annot_qualtypename or
     // annot_cxxscope if it would be valid.  This handles things like x::y, etc.
-    TryAnnotateTypeOrScopeToken();
+    if (getLang().CPlusPlus) {
+      TryAnnotateTypeOrScopeToken();
     
-    // If TryAnnotateTypeOrScopeToken modified the current token, then tail
-    // recurse.
-    if (Tok.getKind() != tok::identifier)
-      return ParseCastExpression(isUnaryExpression);
+      // If TryAnnotateTypeOrScopeToken modified the current token, then tail
+      // recurse.
+      if (Tok.getKind() != tok::identifier)
+        return ParseCastExpression(isUnaryExpression);
+    }
 
     // Consume the identifier so that we can see if it is followed by a '('.
     // Function designators are allowed to be undeclared (C99 6.5.1p2), so we
@@ -630,23 +632,22 @@
     // ::new -> [C++] new-expression
     // ::delete -> [C++] delete-expression
     // ::foo::bar -> global qualified name etc. 
-    SourceLocation ScopeLoc = ConsumeToken();
+    Token ColonColonTok = Tok;
+    ConsumeToken();
     if (Tok.is(tok::kw_new))
-      return ParseCXXNewExpression(true, ScopeLoc);
+      return ParseCXXNewExpression(true, ColonColonTok.getLocation());
     if (Tok.is(tok::kw_delete))
-      return ParseCXXDeleteExpression(true, ScopeLoc);
+      return ParseCXXDeleteExpression(true, ColonColonTok.getLocation());
     // Turn the qualified name into a annot_qualtypename or annot_cxxscope if
     // it would be valid.
-    TryAnnotateTypeOrScopeToken();
-      
-    // If we still have a :: as our current token, then this is not a type
-    // name or scope specifier.
-    if (Tok.getKind() == tok::coloncolon) {
-      Diag(Tok, diag::err_expected_expression);
-      return ExprError();
+    if (TryAnnotateTypeOrScopeToken(&ColonColonTok)) {
+      // If so, retry (tail recurse).
+      return ParseCastExpression(isUnaryExpression);
     }
-    // Otherwise, retry (tail recurse).
-    return ParseCastExpression(isUnaryExpression);
+      
+    // This is not a type name or scope specifier, it is an invalid expression.
+    Diag(ColonColonTok, diag::err_expected_expression);
+    return ExprError();
   }
 
   case tok::kw_new: // [C++] new-expression

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

==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Sun Jan  4 17:23:14 2009
@@ -29,37 +29,49 @@
 ///         nested-name-specifier identifier '::'
 ///         nested-name-specifier 'template'[opt] simple-template-id '::' [TODO]
 ///
-bool Parser::MaybeParseCXXScopeSpecifier(CXXScopeSpec &SS) {
+bool Parser::MaybeParseCXXScopeSpecifier(CXXScopeSpec &SS,
+                                         const Token *GlobalQualifier) {
   assert(getLang().CPlusPlus &&
          "Call sites of this function should be guarded by checking for C++.");
 
   if (Tok.is(tok::annot_cxxscope)) {
+    assert(GlobalQualifier == 0 &&
+           "Cannot have :: followed by a resolve annotation scope");
     SS.setScopeRep(Tok.getAnnotationValue());
     SS.setRange(Tok.getAnnotationRange());
     ConsumeToken();
     return true;
   }
   
-  if (Tok.isNot(tok::coloncolon) &&
+  if (GlobalQualifier == 0 &&
+      Tok.isNot(tok::coloncolon) &&
       (Tok.isNot(tok::identifier) || NextToken().isNot(tok::coloncolon)))
     return false;
 
   // ::new and ::delete aren't nested-name-specifiers, so parsing the :: as
   // a scope specifier only makes things more complicated.
-  if (Tok.is(tok::coloncolon)) {
+  if (GlobalQualifier == 0 && Tok.is(tok::coloncolon)) {
     Token Next = NextToken();
     if (Next.is(tok::kw_new) || Next.is(tok::kw_delete))
       return false;
   }
 
-  SS.setBeginLoc(Tok.getLocation());
+  if (GlobalQualifier) {
+    // Pre-parsed '::'.
+    SS.setBeginLoc(GlobalQualifier->getLocation());
+    SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, 
+                                               GlobalQualifier->getLocation()));
+    SS.setEndLoc(GlobalQualifier->getLocation());
+  } else {
+    SS.setBeginLoc(Tok.getLocation());
 
-  // '::'
-  if (Tok.is(tok::coloncolon)) {
-    // Global scope.
-    SourceLocation CCLoc = ConsumeToken();
-    SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc));
-    SS.setEndLoc(CCLoc);
+    // '::'
+    if (Tok.is(tok::coloncolon)) {
+      // Global scope.
+      SourceLocation CCLoc = ConsumeToken();
+      SS.setScopeRep(Actions.ActOnCXXGlobalScopeSpecifier(CurScope, CCLoc));
+      SS.setEndLoc(CCLoc);
+    }
   }
 
   // nested-name-specifier:

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

==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Sun Jan  4 17:23:14 2009
@@ -741,14 +741,16 @@
 /// will not be called twice, once to check whether we have a declaration
 /// specifier, and another one to get the actual type inside
 /// ParseDeclarationSpecifiers).
-void Parser::TryAnnotateTypeOrScopeToken() {
+///
+/// This returns true if the token was annotated.
+bool Parser::TryAnnotateTypeOrScopeToken(const Token *GlobalQualifier) {
   // FIXME: what about template-ids?
   if (Tok.is(tok::annot_qualtypename) || Tok.is(tok::annot_cxxscope))
-    return;
+    return false;
 
   CXXScopeSpec SS;
   if (getLang().CPlusPlus)
-    MaybeParseCXXScopeSpecifier(SS);
+    MaybeParseCXXScopeSpecifier(SS, GlobalQualifier);
 
   if (Tok.is(tok::identifier)) {
     DeclTy *Template = 0;
@@ -772,7 +774,7 @@
         // In case the tokens were cached, have Preprocessor replace
         // them with the annotation token.
         PP.AnnotateCachedTokens(Tok);
-        return;
+        return true;
       }
     }
 
@@ -785,7 +787,7 @@
   // names a type.
 
   if (SS.isEmpty())
-    return;
+    return false;
   
   // A C++ scope specifier that isn't followed by a typename.
   // Push the current token back into the token stream (or revert it if it is
@@ -801,6 +803,7 @@
   // In case the tokens were cached, have Preprocessor replace them with the
   // annotation token.
   PP.AnnotateCachedTokens(Tok);
+  return true;
 }
 
 /// TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only





More information about the cfe-commits mailing list