From db7bb4a4e7d9744cbc994c90932e6f056228e1ff Mon Sep 17 00:00:00 2001 From: John McCall Date: Wed, 17 Mar 2010 00:38:33 +0000 Subject: [PATCH] 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 --- include/clang/Parse/Action.h | 8 ++++++++ lib/Parse/ParseDeclCXX.cpp | 7 +++++-- lib/Sema/Sema.h | 4 ++++ 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(TagD.getAs()); + + Tag->setInvalidDecl(); + + if (isa(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, -- 2.40.0