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 | 48c89f4aa708e28310cb0c94b2d9d044b0ab806c (patch) | |
tree | 5eae1b37444f8cc0ed855d1ce1ab7145101f88fa /lib | |
parent | 80971bdba20b5b280a00b7b9829026b33d3206f9 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102247 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 42 | ||||
-rw-r--r-- | lib/Sema/SemaCXXScopeSpec.cpp | 10 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 7 |
4 files changed, 56 insertions, 5 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index a034a325f4..6669d40cca 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/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; diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp index e9d206e53b..89f8aec6e0 100644 --- a/lib/Sema/SemaCXXScopeSpec.cpp +++ b/lib/Sema/SemaCXXScopeSpec.cpp @@ -235,6 +235,16 @@ bool Sema::RequireCompleteDeclContext(CXXScopeSpec &SS) { return false; DeclContext *DC = computeDeclContext(SS, true); + if (!DC) { + // It's dependent. + assert(isDependentScopeSpecifier(SS) && + "No context for non-dependent scope specifier?"); + Diag(SS.getRange().getBegin(), diag::err_dependent_nested_name_spec) + << SS.getRange(); + SS.setScopeRep(0); + return true; + } + if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) { // If this is a dependent type, then we consider it complete. if (Tag->isDependentContext()) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index b8ff182be0..bf2cba10c7 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -5313,7 +5313,7 @@ CreateNewDecl: void Sema::ActOnTagStartDefinition(Scope *S, DeclPtrTy TagD) { AdjustDeclIfTemplate(TagD); TagDecl *Tag = cast<TagDecl>(TagD.getAs<Decl>()); - + // Enter the tag context. PushDeclContext(S, Tag); } diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 1075f41399..14d04563d6 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -5117,6 +5117,13 @@ Sema::ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK, } assert(Keyword != ETK_None && "Invalid tag kind!"); + if (TUK == TUK_Declaration || TUK == TUK_Definition) { + Diag(NameLoc, diag::err_dependent_tag_decl) + << (TUK == TUK_Definition) << TagDecl::getTagKindForTypeSpec(TagSpec) + << SS.getRange(); + return true; + } + return Context.getDependentNameType(Keyword, NNS, Name).getAsOpaquePtr(); } |