[cfe-commits] r153427 - in /cfe/trunk: lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaCXX/enum-scoped.cpp
Richard Smith
richard-llvm at metafoo.co.uk
Sun Mar 25 21:58:10 PDT 2012
Author: rsmith
Date: Sun Mar 25 23:58:10 2012
New Revision: 153427
URL: http://llvm.org/viewvc/llvm-project?rev=153427&view=rev
Log:
Handle instantiations of redeclarations of forward-declared enumerations within
templated functions. Build a redeclaration chain, and only instantiate the
definition of the enum when visiting the defining declaration.
Modified:
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/SemaCXX/enum-scoped.cpp
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=153427&r1=153426&r2=153427&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Sun Mar 25 23:58:10 2012
@@ -558,9 +558,18 @@
}
Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
+ EnumDecl *PrevDecl = 0;
+ if (D->getPreviousDecl()) {
+ NamedDecl *Prev = SemaRef.FindInstantiatedDecl(D->getLocation(),
+ D->getPreviousDecl(),
+ TemplateArgs);
+ if (!Prev) return 0;
+ PrevDecl = cast<EnumDecl>(Prev);
+ }
+
EnumDecl *Enum = EnumDecl::Create(SemaRef.Context, Owner, D->getLocStart(),
D->getLocation(), D->getIdentifier(),
- /*PrevDecl=*/0, D->isScoped(),
+ PrevDecl, D->isScoped(),
D->isScopedUsingClassTag(), D->isFixed());
if (D->isFixed()) {
if (TypeSourceInfo *TI = D->getIntegerTypeSourceInfo()) {
@@ -610,8 +619,11 @@
// specialization causes the implicit instantiation of the declarations, but
// not the definitions of scoped member enumerations.
// FIXME: There appears to be no wording for what happens for an enum defined
- // within a block scope, but we treat that like a member of a class template.
- if (!Enum->isScoped() && Def)
+ // within a block scope, but we treat that much like a member template. Only
+ // instantiate the definition when visiting the definition in that case, since
+ // we will visit all redeclarations.
+ if (!Enum->isScoped() && Def &&
+ (!D->getDeclContext()->isFunctionOrMethod() || D->isCompleteDefinition()))
InstantiateEnumDefinition(Enum, Def);
return Enum;
Modified: cfe/trunk/test/SemaCXX/enum-scoped.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/enum-scoped.cpp?rev=153427&r1=153426&r2=153427&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/enum-scoped.cpp (original)
+++ cfe/trunk/test/SemaCXX/enum-scoped.cpp Sun Mar 25 23:58:10 2012
@@ -221,3 +221,27 @@
// never instantiate the definitions of S<short>::ET nor S<short>::Eint.
S<short> s; // expected-note {{in instantiation of}}
}
+
+namespace test10 {
+ template<typename T> int f() {
+ enum E : int;
+ enum E : T; // expected-note {{here}}
+ E x;
+ enum E : int { e }; // expected-error {{different underlying}}
+ x = e;
+ return x;
+ }
+ int k = f<int>();
+ int l = f<short>(); // expected-note {{here}}
+
+ template<typename T> int g() {
+ enum class E : int;
+ enum class E : T; // expected-note {{here}}
+ E x;
+ enum class E : int { e }; // expected-error {{different underlying}}
+ x = E::e;
+ return (int)x;
+ }
+ int m = g<int>();
+ int n = g<short>(); // expected-note {{here}}
+}
More information about the cfe-commits
mailing list