[cfe-commits] r106496 - /cfe/trunk/lib/Parse/ParseDeclCXX.cpp

Douglas Gregor dgregor at apple.com
Mon Jun 21 15:31:09 PDT 2010


Author: dgregor
Date: Mon Jun 21 17:31:09 2010
New Revision: 106496

URL: http://llvm.org/viewvc/llvm-project?rev=106496&view=rev
Log:
When semantic analysis fail to introduce a class or class template,
just skip over the body of the class or class template: it's a
semantic disaster that's likely to cause invariants to break. Fixes
part of <rdar://problem/8104754>.

Modified:
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=106496&r1=106495&r2=106496&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Mon Jun 21 17:31:09 2010
@@ -1563,40 +1563,45 @@
   else
     CurAS = AS_public;
 
-  // While we still have something to read, read the member-declarations.
-  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
-    // Each iteration of this loop reads one member-declaration.
-
-    // Check for extraneous top-level semicolon.
-    if (Tok.is(tok::semi)) {
-      Diag(Tok, diag::ext_extra_struct_semi)
-        << DeclSpec::getSpecifierName((DeclSpec::TST)TagType)
-        << FixItHint::CreateRemoval(Tok.getLocation());
-      ConsumeToken();
-      continue;
-    }
+  SourceLocation RBraceLoc;
+  if (TagDecl) {
+    // While we still have something to read, read the member-declarations.
+    while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
+      // Each iteration of this loop reads one member-declaration.
+
+      // Check for extraneous top-level semicolon.
+      if (Tok.is(tok::semi)) {
+        Diag(Tok, diag::ext_extra_struct_semi)
+          << DeclSpec::getSpecifierName((DeclSpec::TST)TagType)
+          << FixItHint::CreateRemoval(Tok.getLocation());
+        ConsumeToken();
+        continue;
+      }
 
-    AccessSpecifier AS = getAccessSpecifierIfPresent();
-    if (AS != AS_none) {
-      // Current token is a C++ access specifier.
-      CurAS = AS;
-      SourceLocation ASLoc = Tok.getLocation();
-      ConsumeToken();
-      if (Tok.is(tok::colon))
-        Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation());
-      else
-        Diag(Tok, diag::err_expected_colon);
-      ConsumeToken();
-      continue;
-    }
+      AccessSpecifier AS = getAccessSpecifierIfPresent();
+      if (AS != AS_none) {
+        // Current token is a C++ access specifier.
+        CurAS = AS;
+        SourceLocation ASLoc = Tok.getLocation();
+        ConsumeToken();
+        if (Tok.is(tok::colon))
+          Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation());
+        else
+          Diag(Tok, diag::err_expected_colon);
+        ConsumeToken();
+        continue;
+      }
 
-    // FIXME: Make sure we don't have a template here.
+      // FIXME: Make sure we don't have a template here.
 
-    // Parse all the comma separated declarators.
-    ParseCXXClassMemberDeclaration(CurAS);
-  }
+      // Parse all the comma separated declarators.
+      ParseCXXClassMemberDeclaration(CurAS);
+    }
 
-  SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
+    RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
+  } else {
+    SkipUntil(tok::r_brace, false, false);
+  }
 
   // If attributes exist after class contents, parse them.
   llvm::OwningPtr<AttributeList> AttrList;
@@ -1615,7 +1620,7 @@
   //
   // FIXME: Only function bodies and constructor ctor-initializers are
   // parsed correctly, fix the rest.
-  if (NonNestedClass) {
+  if (TagDecl && NonNestedClass) {
     // We are not inside a nested class. This class and its nested classes
     // are complete and we can parse the delayed portions of method
     // declarations and the lexed inline method definitions.





More information about the cfe-commits mailing list