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
This commit is contained in:
John McCall 2010-03-17 00:38:33 +00:00
Родитель 19b43e1ba9
Коммит db7bb4a4e7
4 изменённых файлов: 29 добавлений и 2 удалений

Просмотреть файл

@ -727,9 +727,17 @@ public:
/// ActOnTagFinishDefinition - Invoked once we have finished parsing /// ActOnTagFinishDefinition - Invoked once we have finished parsing
/// the definition of a tag (enumeration, class, struct, or union). /// 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, virtual void ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagDecl,
SourceLocation RBraceLoc) { } 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, virtual DeclPtrTy ActOnEnumConstant(Scope *S, DeclPtrTy EnumDecl,
DeclPtrTy LastEnumConstant, DeclPtrTy LastEnumConstant,
SourceLocation IdLoc, IdentifierInfo *Id, SourceLocation IdLoc, IdentifierInfo *Id,

Просмотреть файл

@ -1520,6 +1520,9 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
if (!Tok.is(tok::l_brace)) { if (!Tok.is(tok::l_brace)) {
Diag(Tok, diag::err_expected_lbrace_after_base_specifiers); Diag(Tok, diag::err_expected_lbrace_after_base_specifiers);
if (TagDecl)
Actions.ActOnTagDefinitionError(CurScope, TagDecl);
return; return;
} }
} }
@ -1596,11 +1599,11 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
ParseLexedMethodDefs(getCurrentClass()); ParseLexedMethodDefs(getCurrentClass());
} }
Actions.ActOnTagFinishDefinition(CurScope, TagDecl, RBraceLoc);
// Leave the class scope. // Leave the class scope.
ParsingDef.Pop(); ParsingDef.Pop();
ClassScope.Exit(); ClassScope.Exit();
Actions.ActOnTagFinishDefinition(CurScope, TagDecl, RBraceLoc);
} }
/// ParseConstructorInitializer - Parse a C++ constructor initializer, /// ParseConstructorInitializer - Parse a C++ constructor initializer,

Просмотреть файл

@ -939,6 +939,10 @@ public:
virtual void ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagDecl, virtual void ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagDecl,
SourceLocation RBraceLoc); 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 *CheckEnumConstant(EnumDecl *Enum,
EnumConstantDecl *LastEnumConst, EnumConstantDecl *LastEnumConst,
SourceLocation IdLoc, SourceLocation IdLoc,

Просмотреть файл

@ -5118,6 +5118,18 @@ void Sema::ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagD,
Consumer.HandleTagDeclDefinition(Tag); 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. // Note that FieldName may be null for anonymous bitfields.
bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName, bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
QualType FieldTy, const Expr *BitWidth, QualType FieldTy, const Expr *BitWidth,