diff options
author | John McCall <rjmccall@apple.com> | 2010-03-17 00:38:33 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-03-17 00:38:33 +0000 |
commit | db7bb4a4e7d9744cbc994c90932e6f056228e1ff (patch) | |
tree | 589a856734356eea69c640b850113437cbb7f183 | |
parent | 19b43e1ba9324cb08b730fa38d9be865e63771a2 (diff) |
Clean up after ourselves when there's an error parsing the base clause.
Fixes the crash-on-invalid in PR6629.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98698 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Parse/Action.h | 8 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 7 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 4 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 12 |
4 files changed, 29 insertions, 2 deletions
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index f211b5ca3a..2954b946b4 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -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, diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 11f84edcf1..9e232cbf32 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -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, diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index a18d5f11af..9251ab77e8 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -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, diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 5db817192f..f4b9cf4cde 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -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, |