Parse: Recover more gracefully from extra :: tokens before a {
authorDavid Majnemer <david.majnemer@gmail.com>
Mon, 29 Dec 2014 23:12:23 +0000 (23:12 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Mon, 29 Dec 2014 23:12:23 +0000 (23:12 +0000)
Instead of crashing, recover by eating the extra trailing scope
qualifier.  This means we will treat 'struct A:: {' as 'struct A {'.

llvm-svn: 224966

clang/lib/Parse/ParseExprCXX.cpp
clang/test/CXX/dcl.decl/dcl.meaning/p1.cpp

index 55f9245..a6162e2 100644 (file)
@@ -442,7 +442,17 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
         Next.setKind(tok::coloncolon);
       }
     }
-    
+
+    if (Next.is(tok::coloncolon) && GetLookAheadToken(2).is(tok::l_brace)) {
+      // It is invalid to have :: {, consume the scope qualifier and pretend
+      // like we never saw it.
+      Token Identifier = Tok; // Stash away the identifier.
+      ConsumeToken();         // Eat the identifier, current token is now '::'.
+      Diag(PP.getLocForEndOfTokenConsumeToken(), diag::err_expected) << tok::identifier;
+      UnconsumeToken(Identifier); // Stick the identifier back.
+      Next = NextToken();         // Point Next at the '{' token.
+    }
+
     if (Next.is(tok::coloncolon)) {
       if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde) &&
           !Actions.isNonTypeNestedNameSpecifier(
index 349f0d7..cefee7b 100644 (file)
@@ -27,6 +27,7 @@ namespace NS {
   struct X;
   template<typename T> struct Y;
   template<typename T> void wibble(T);
+  struct Z;
 }
 namespace NS {
   // Under DR482, these are all valid, except for forward-declaring a struct
@@ -45,3 +46,4 @@ namespace NS {
 }
 
 struct ::{} a; // expected-error{{expected identifier}}
+struct NS::Z:: {} b; // expected-error{{expected identifier}}