diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-03-26 04:58:10 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-03-26 04:58:10 +0000 |
commit | 38f0df352fadc546c5666079fb22de5ec1819d92 (patch) | |
tree | 1713e0b3b1c2a38a49ec508e8f5d92283ed739b3 /lib/Sema/SemaTemplateInstantiateDecl.cpp | |
parent | 4ca93d9978aac02b01814b4f749d6903a1f87ee5 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153427 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index caf134e025..8729a39f9b 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -558,9 +558,18 @@ Decl *TemplateDeclInstantiator::VisitStaticAssertDecl(StaticAssertDecl *D) { } 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 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) { // 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; |