Fix an assertion-on-error during tentative constructor parsing by
propagating error conditions out of the various annotate-me-a-snowflake
routines.  Generally (but not universally) removes redundant diagnostics
as well as, you know, not crashing on bad code.  On the other hand,
I have just signed myself up to fix fiddly parser errors for the next
week.  Again.

llvm-svn: 97221
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 62b10a3..5dc4bd2 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -859,10 +859,13 @@
       return;
 
     case tok::coloncolon: // ::foo::bar
-      // Annotate C++ scope specifiers.  If we get one, loop.
-      if (TryAnnotateCXXScopeToken(true))
-        continue;
-      goto DoneWithDeclSpec;
+      // C++ scope specifier.  Annotate and loop, or bail out on error.
+      if (TryAnnotateCXXScopeToken(true)) {
+        if (!DS.hasTypeSpecifier())
+          DS.SetTypeSpecError();
+        goto DoneWithDeclSpec;
+      }
+      continue;
 
     case tok::annot_cxxscope: {
       if (DS.hasTypeSpecifier())
@@ -1020,8 +1023,15 @@
     case tok::identifier: {
       // In C++, check to see if this is a scope specifier like foo::bar::, if
       // so handle it as such.  This is important for ctor parsing.
-      if (getLang().CPlusPlus && TryAnnotateCXXScopeToken(true))
-        continue;
+      if (getLang().CPlusPlus) {
+        if (TryAnnotateCXXScopeToken(true)) {
+          if (!DS.hasTypeSpecifier())
+            DS.SetTypeSpecError();
+          goto DoneWithDeclSpec;
+        }
+        if (!Tok.is(tok::identifier))
+          continue;
+      }
 
       // This identifier can only be a typedef name if we haven't already seen
       // a type-specifier.  Without this check we misparse:
@@ -1313,7 +1323,11 @@
 
     // C++ typename-specifier:
     case tok::kw_typename:
-      if (TryAnnotateTypeOrScopeToken())
+      if (TryAnnotateTypeOrScopeToken()) {
+        DS.SetTypeSpecError();
+        goto DoneWithDeclSpec;
+      }
+      if (!Tok.is(tok::kw_typename))
         continue;
       break;
 
@@ -1423,10 +1437,11 @@
     // Annotate typenames and C++ scope specifiers.  If we get one, just
     // recurse to handle whatever we get.
     if (TryAnnotateTypeOrScopeToken())
-      return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID,
-                                        TemplateInfo, SuppressDeclarations);
-    // Otherwise, not a type specifier.
-    return false;
+      return true;
+    if (Tok.is(tok::identifier))
+      return false;
+    return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID,
+                                      TemplateInfo, SuppressDeclarations);
   case tok::coloncolon:   // ::foo::bar
     if (NextToken().is(tok::kw_new) ||    // ::new
         NextToken().is(tok::kw_delete))   // ::delete
@@ -1435,10 +1450,9 @@
     // Annotate typenames and C++ scope specifiers.  If we get one, just
     // recurse to handle whatever we get.
     if (TryAnnotateTypeOrScopeToken())
-      return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID,
-                                        TemplateInfo, SuppressDeclarations);
-    // Otherwise, not a type specifier.
-    return false;
+      return true;
+    return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID,
+                                      TemplateInfo, SuppressDeclarations);
 
   // simple-type-specifier:
   case tok::annot_typename: {
@@ -1848,8 +1862,11 @@
     Attr.reset(ParseGNUAttributes());
 
   CXXScopeSpec SS;
-  if (getLang().CPlusPlus && ParseOptionalCXXScopeSpecifier(SS, 0, false)) {
-    if (Tok.isNot(tok::identifier)) {
+  if (getLang().CPlusPlus) {
+    if (ParseOptionalCXXScopeSpecifier(SS, 0, false))
+      return;
+
+    if (SS.isSet() && Tok.isNot(tok::identifier)) {
       Diag(Tok, diag::err_expected_ident);
       if (Tok.isNot(tok::l_brace)) {
         // Has no name and is not a definition.
@@ -2016,21 +2033,19 @@
     // Annotate typenames and C++ scope specifiers.  If we get one, just
     // recurse to handle whatever we get.
     if (TryAnnotateTypeOrScopeToken())
-      return isTypeSpecifierQualifier();
-    // Otherwise, not a type specifier.
-    return false;
+      return true;
+    if (Tok.is(tok::identifier))
+      return false;
+    return isTypeSpecifierQualifier();
 
   case tok::coloncolon:   // ::foo::bar
     if (NextToken().is(tok::kw_new) ||    // ::new
         NextToken().is(tok::kw_delete))   // ::delete
       return false;
 
-    // Annotate typenames and C++ scope specifiers.  If we get one, just
-    // recurse to handle whatever we get.
     if (TryAnnotateTypeOrScopeToken())
-      return isTypeSpecifierQualifier();
-    // Otherwise, not a type specifier.
-    return false;
+      return true;
+    return isTypeSpecifierQualifier();
 
     // GNU attributes support.
   case tok::kw___attribute:
@@ -2101,14 +2116,15 @@
     if (TryAltiVecVectorToken())
       return true;
     // Fall through.
-
   case tok::kw_typename: // typename T::type
     // Annotate typenames and C++ scope specifiers.  If we get one, just
     // recurse to handle whatever we get.
     if (TryAnnotateTypeOrScopeToken())
-      return isDeclarationSpecifier();
-    // Otherwise, not a declaration specifier.
-    return false;
+      return true;
+    if (Tok.is(tok::identifier))
+      return false;
+    return isDeclarationSpecifier();
+
   case tok::coloncolon:   // ::foo::bar
     if (NextToken().is(tok::kw_new) ||    // ::new
         NextToken().is(tok::kw_delete))   // ::delete
@@ -2117,9 +2133,8 @@
     // Annotate typenames and C++ scope specifiers.  If we get one, just
     // recurse to handle whatever we get.
     if (TryAnnotateTypeOrScopeToken())
-      return isDeclarationSpecifier();
-    // Otherwise, not a declaration specifier.
-    return false;
+      return true;
+    return isDeclarationSpecifier();
 
     // storage-class-specifier
   case tok::kw_typedef:
@@ -2200,7 +2215,10 @@
 
   // Parse the C++ scope specifier.
   CXXScopeSpec SS;
-  ParseOptionalCXXScopeSpecifier(SS, 0, true);
+  if (ParseOptionalCXXScopeSpecifier(SS, 0, true)) {
+    TPA.Revert();
+    return false;
+  }
 
   // Parse the constructor name.
   if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id)) {
@@ -2351,7 +2369,9 @@
       (Tok.is(tok::coloncolon) || Tok.is(tok::identifier) ||
        Tok.is(tok::annot_cxxscope))) {
     CXXScopeSpec SS;
-    if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, true)) {
+    ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, true); // ignore fail
+
+    if (SS.isSet()) {
       if (Tok.isNot(tok::star)) {
         // The scope spec really belongs to the direct-declarator.
         D.getCXXScopeSpec() = SS;
@@ -2507,9 +2527,13 @@
 
   if (getLang().CPlusPlus && D.mayHaveIdentifier()) {
     // ParseDeclaratorInternal might already have parsed the scope.
-    bool afterCXXScope = D.getCXXScopeSpec().isSet() ||
+    bool afterCXXScope = D.getCXXScopeSpec().isSet();
+    if (!afterCXXScope) {
       ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), /*ObjectType=*/0,
                                      true);
+      afterCXXScope = D.getCXXScopeSpec().isSet();
+    }
+
     if (afterCXXScope) {
       if (Actions.ShouldEnterDeclaratorScope(CurScope, D.getCXXScopeSpec()))
         // Change the declaration context for name lookup, until this function
@@ -2799,7 +2823,7 @@
   // K&R-style function:  void foo(a,b,c)
   if (!getLang().CPlusPlus && Tok.is(tok::identifier)
       && !TryAltiVecVectorToken()) {
-    if (!TryAnnotateTypeOrScopeToken()) {
+    if (TryAnnotateTypeOrScopeToken() || !Tok.is(tok::annot_typename)) {
       // K&R identifier lists can't have typedefs as identifiers, per
       // C99 6.7.5.3p11.
       if (RequiresArg) {