diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-04-24 16:38:41 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-04-24 16:38:41 +0000 |
commit | ba41d01b5970dc9d741bf6c9b308f6e75121d942 (patch) | |
tree | f27d0e3c2b88b1d64c44b08d5e54763c4bf1c5c0 /clang/lib/Parse/ParseDecl.cpp | |
parent | b34f88205f992c806a1a6dce399f62c53e01b124 (diff) | |
download | bcm5719-llvm-ba41d01b5970dc9d741bf6c9b308f6e75121d942.tar.gz bcm5719-llvm-ba41d01b5970dc9d741bf6c9b308f6e75121d942.zip |
Be more careful around dependent nested-name-specifiers, complaining
when they are not complete (since we could not match them up to
anything) and ensuring that enum parsing can cope with dependent
elaborated-type-specifiers. Fixes PR6915 and PR6649.
llvm-svn: 102247
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index a034a325f4f..6669d40cca0 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -1934,21 +1934,55 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, TUK = Action::TUK_Reference; bool Owned = false; bool IsDependent = false; + SourceLocation TSTLoc = NameLoc.isValid()? NameLoc : StartLoc; + const char *PrevSpec = 0; + unsigned DiagID; DeclPtrTy TagDecl = Actions.ActOnTag(CurScope, DeclSpec::TST_enum, TUK, StartLoc, SS, Name, NameLoc, Attr.get(), AS, Action::MultiTemplateParamsArg(Actions), Owned, IsDependent); - assert(!IsDependent && "didn't expect dependent enum"); + if (IsDependent) { + // This enum has a dependent nested-name-specifier. Handle it as a + // dependent tag. + if (!Name) { + DS.SetTypeSpecError(); + Diag(Tok, diag::err_expected_type_name_after_typename); + return; + } + + TypeResult Type = Actions.ActOnDependentTag(CurScope, DeclSpec::TST_enum, + TUK, SS, Name, StartLoc, + NameLoc); + if (Type.isInvalid()) { + DS.SetTypeSpecError(); + return; + } + + if (DS.SetTypeSpecType(DeclSpec::TST_typename, TSTLoc, PrevSpec, DiagID, + Type.get(), false)) + Diag(StartLoc, DiagID) << PrevSpec; + + return; + } + if (!TagDecl.get()) { + // The action failed to produce an enumeration tag. If this is a + // definition, consume the entire definition. + if (Tok.is(tok::l_brace)) { + ConsumeBrace(); + SkipUntil(tok::r_brace); + } + + DS.SetTypeSpecError(); + return; + } + if (Tok.is(tok::l_brace)) ParseEnumBody(StartLoc, TagDecl); // FIXME: The DeclSpec should keep the locations of both the keyword and the // name (if there is one). - SourceLocation TSTLoc = NameLoc.isValid()? NameLoc : StartLoc; - const char *PrevSpec = 0; - unsigned DiagID; if (DS.SetTypeSpecType(DeclSpec::TST_enum, TSTLoc, PrevSpec, DiagID, TagDecl.getAs<void>(), Owned)) Diag(StartLoc, DiagID) << PrevSpec; |