summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-03-17 00:38:33 +0000
committerJohn McCall <rjmccall@apple.com>2010-03-17 00:38:33 +0000
commit2ff380a43a1718ad961cef957d3b1d21bea18e69 (patch)
tree28e5615abf3f4c28a737f43516f737b04a0b8d4d
parent81dfb30e4c85f4b779a2cc75fedebeff2b9f89ae (diff)
downloadbcm5719-llvm-2ff380a43a1718ad961cef957d3b1d21bea18e69.tar.gz
bcm5719-llvm-2ff380a43a1718ad961cef957d3b1d21bea18e69.zip
Clean up after ourselves when there's an error parsing the base clause.
Fixes the crash-on-invalid in PR6629. llvm-svn: 98698
-rw-r--r--clang/include/clang/Parse/Action.h8
-rw-r--r--clang/lib/Parse/ParseDeclCXX.cpp7
-rw-r--r--clang/lib/Sema/Sema.h4
-rw-r--r--clang/lib/Sema/SemaDecl.cpp12
4 files changed, 29 insertions, 2 deletions
diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h
index f211b5ca3a6..2954b946b49 100644
--- a/clang/include/clang/Parse/Action.h
+++ b/clang/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/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 11f84edcf18..9e232cbf325 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/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/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index a18d5f11af3..9251ab77e8e 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/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/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 5db817192f6..f4b9cf4cdeb 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/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,
OpenPOWER on IntegriCloud