]> granicus.if.org Git - clang/commitdiff
Clean up after ourselves when there's an error parsing the base clause.
authorJohn McCall <rjmccall@apple.com>
Wed, 17 Mar 2010 00:38:33 +0000 (00:38 +0000)
committerJohn McCall <rjmccall@apple.com>
Wed, 17 Mar 2010 00:38:33 +0000 (00:38 +0000)
Fixes the crash-on-invalid in PR6629.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98698 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Parse/Action.h
lib/Parse/ParseDeclCXX.cpp
lib/Sema/Sema.h
lib/Sema/SemaDecl.cpp

index f211b5ca3a69d89474f77dc5c62121e6013355d7..2954b946b4991883ecabfb481b18657c654b3df3 100644 (file)
@@ -727,9 +727,17 @@ public:
 
   /// ActOnTagFinishDefinition - Invoked once we have finished parsing
   /// the definition of a tag (enumeration, class, struct, or union).
+  ///
+  /// The scope is the scope of the tag definition.
   virtual void ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagDecl,
                                         SourceLocation RBraceLoc) { }
 
+  /// ActOnTagDefinitionError - Invoked if there's an unrecoverable
+  /// error parsing the definition of a tag.
+  ///
+  /// The scope is the scope of the tag definition.
+  virtual void ActOnTagDefinitionError(Scope *S, DeclPtrTy TagDecl) { }
+
   virtual DeclPtrTy ActOnEnumConstant(Scope *S, DeclPtrTy EnumDecl,
                                       DeclPtrTy LastEnumConstant,
                                       SourceLocation IdLoc, IdentifierInfo *Id,
index 11f84edcf18c3a13317fbe09712c652522c98168..9e232cbf325d2715fb7cc2de73bb1e4e93bc8a40 100644 (file)
@@ -1520,6 +1520,9 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
 
     if (!Tok.is(tok::l_brace)) {
       Diag(Tok, diag::err_expected_lbrace_after_base_specifiers);
+
+      if (TagDecl)
+        Actions.ActOnTagDefinitionError(CurScope, TagDecl);
       return;
     }
   }
@@ -1596,11 +1599,11 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
     ParseLexedMethodDefs(getCurrentClass());
   }
 
+  Actions.ActOnTagFinishDefinition(CurScope, TagDecl, RBraceLoc);
+
   // Leave the class scope.
   ParsingDef.Pop();
   ClassScope.Exit();
-
-  Actions.ActOnTagFinishDefinition(CurScope, TagDecl, RBraceLoc);
 }
 
 /// ParseConstructorInitializer - Parse a C++ constructor initializer,
index a18d5f11af39486a68d8052e49e9432d1457b125..9251ab77e8e29e692c9c8c349d5a22f8d48794f2 100644 (file)
@@ -939,6 +939,10 @@ public:
   virtual void ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagDecl,
                                         SourceLocation RBraceLoc);
 
+  /// ActOnTagDefinitionError - Invoked when there was an unrecoverable
+  /// error parsing the definition of a tag.
+  virtual void ActOnTagDefinitionError(Scope *S, DeclPtrTy TagDecl);
+
   EnumConstantDecl *CheckEnumConstant(EnumDecl *Enum,
                                       EnumConstantDecl *LastEnumConst,
                                       SourceLocation IdLoc,
index 5db817192f68e7b53fa745d2cf3a5b4e62c0ad88..f4b9cf4cdeb27a43f4e1813df60531aa149e9917 100644 (file)
@@ -5118,6 +5118,18 @@ void Sema::ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagD,
   Consumer.HandleTagDeclDefinition(Tag);
 }
 
+void Sema::ActOnTagDefinitionError(Scope *S, DeclPtrTy TagD) {
+  AdjustDeclIfTemplate(TagD);
+  TagDecl *Tag = cast<TagDecl>(TagD.getAs<Decl>());
+
+  Tag->setInvalidDecl();
+
+  if (isa<CXXRecordDecl>(Tag))
+    FieldCollector->FinishClass();
+
+  PopDeclContext();  
+}
+
 // Note that FieldName may be null for anonymous bitfields.
 bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
                           QualType FieldTy, const Expr *BitWidth,