[cfe-commits] r102247 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Parse/ParseDecl.cpp lib/Sema/SemaCXXScopeSpec.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaTemplate.cpp test/SemaTemplate/elaborated-type-specifier.cpp
Douglas Gregor
dgregor at apple.com
Sat Apr 24 09:38:41 PDT 2010
Author: dgregor
Date: Sat Apr 24 11:38:41 2010
New Revision: 102247
URL: http://llvm.org/viewvc/llvm-project?rev=102247&view=rev
Log:
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.
Added:
cfe/trunk/test/SemaTemplate/elaborated-type-specifier.cpp (with props)
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=102247&r1=102246&r2=102247&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sat Apr 24 11:38:41 2010
@@ -513,6 +513,9 @@
// C++ name lookup
def err_incomplete_nested_name_spec : Error<
"incomplete type %0 named in nested name specifier">;
+def err_dependent_nested_name_spec : Error<
+ "nested name specifier for a declaration cannot depend on a template "
+ "parameter">;
def err_nested_name_member_ref_lookup_ambiguous : Error<
"lookup of %0 in member access expression is ambiguous">;
def note_ambig_member_ref_object_type : Note<
@@ -1590,6 +1593,9 @@
def err_tag_reference_conflict : Error<
"implicit declaration introduced by elaborated type conflicts with "
"%select{a declaration|a typedef|a template}0 of the same name">;
+def err_dependent_tag_decl : Error<
+ "%select{declaration|definition}0 of %select{struct|union|class|enum}1 "
+ "in a dependent scope">;
def err_tag_definition_of_typedef : Error<
"definition of type %0 conflicts with typedef of the same name">;
def err_conflicting_types : Error<"conflicting types for %0">;
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=102247&r1=102246&r2=102247&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Sat Apr 24 11:38:41 2010
@@ -1934,21 +1934,55 @@
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;
Modified: cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp?rev=102247&r1=102246&r2=102247&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp Sat Apr 24 11:38:41 2010
@@ -235,6 +235,16 @@
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())
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=102247&r1=102246&r2=102247&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sat Apr 24 11:38:41 2010
@@ -5313,7 +5313,7 @@
void Sema::ActOnTagStartDefinition(Scope *S, DeclPtrTy TagD) {
AdjustDeclIfTemplate(TagD);
TagDecl *Tag = cast<TagDecl>(TagD.getAs<Decl>());
-
+
// Enter the tag context.
PushDeclContext(S, Tag);
}
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=102247&r1=102246&r2=102247&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Sat Apr 24 11:38:41 2010
@@ -5117,6 +5117,13 @@
}
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();
}
Added: cfe/trunk/test/SemaTemplate/elaborated-type-specifier.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/elaborated-type-specifier.cpp?rev=102247&view=auto
==============================================================================
--- cfe/trunk/test/SemaTemplate/elaborated-type-specifier.cpp (added)
+++ cfe/trunk/test/SemaTemplate/elaborated-type-specifier.cpp Sat Apr 24 11:38:41 2010
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace PR6915 {
+ template <typename T>
+ class D {
+ enum T::X v; // expected-error{{use of 'X' with tag type that does not match previous declaration}} \
+ // expected-error{{no enum named 'X' in 'PR6915::D3'}}
+ };
+
+ struct D1 {
+ enum X { value };
+ };
+ struct D2 {
+ class X { }; // expected-note{{previous use is here}}
+ };
+ struct D3 { };
+
+ template class D<D1>;
+ template class D<D2>; // expected-note{{in instantiation of}}
+ template class D<D3>; // expected-note{{in instantiation of}}
+}
+
+template<typename T>
+struct DeclOrDef {
+ enum T::foo; // expected-error{{nested name specifier for a declaration cannot depend on a template parameter}}
+ enum T::bar { // expected-error{{nested name specifier for a declaration cannot depend on a template parameter}}
+ value
+ };
+};
+
+namespace PR6649 {
+ template <typename T> struct foo {
+ class T::bar; // expected-error{{nested name specifier for a declaration cannot depend on a template parameter}}
+ };
+}
Propchange: cfe/trunk/test/SemaTemplate/elaborated-type-specifier.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/SemaTemplate/elaborated-type-specifier.cpp
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cfe/trunk/test/SemaTemplate/elaborated-type-specifier.cpp
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the cfe-commits
mailing list