diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-10-08 07:24:58 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-10-08 07:24:58 +0000 |
commit | 251b4ff2578e26959a4c036140ccd61c5e9292f2 (patch) | |
tree | cacc1f2c9bfb3174e9914422eef9de64890b06cd /lib/Sema/SemaTemplateInstantiateDecl.cpp | |
parent | e9374d5e2c0915bd883dfa988db2451b844390d8 (diff) |
For instantiations of static data members of class templates, keep
track of the kind of specialization or instantiation. Also, check the
scope of the specialization and ensure that a specialization
declaration without an initializer is not a definition.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83533 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index fcacb4a3f0..bafcea054e 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -155,6 +155,12 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { Owner->addDecl(Var); } + // Link instantiations of static data members back to the template from + // which they were instantiated. + if (Var->isStaticDataMember()) + SemaRef.Context.setInstantiatedFromStaticDataMember(Var, D, + TSK_ImplicitInstantiation); + if (D->getInit()) { OwningExprResult Init = SemaRef.SubstExpr(D->getInit(), TemplateArgs); @@ -191,11 +197,6 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { } else if (!Var->isStaticDataMember() || Var->isOutOfLine()) SemaRef.ActOnUninitializedDecl(Sema::DeclPtrTy::make(Var), false); - // Link instantiations of static data members back to the template from - // which they were instantiated. - if (Var->isStaticDataMember()) - SemaRef.Context.setInstantiatedFromStaticDataMember(Var, D); - return Var; } @@ -977,6 +978,10 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, assert(!Function->getBody() && "Already instantiated!"); + // Never instantiate an explicit specialization. + if (Function->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) + return; + // Find the function body that we'll be substituting. const FunctionDecl *PatternDecl = 0; if (FunctionTemplateDecl *Primary = Function->getPrimaryTemplate()) { @@ -1084,7 +1089,6 @@ void Sema::InstantiateStaticDataMemberDefinition( return; // Find the out-of-line definition of this static data member. - // FIXME: Do we have to look for specializations separately? VarDecl *Def = Var->getInstantiatedFromStaticDataMember(); bool FoundOutOfLineDef = false; assert(Def && "This data member was not instantiated from a template?"); @@ -1106,7 +1110,17 @@ void Sema::InstantiateStaticDataMemberDefinition( return; } - // FIXME: extern templates + // Never instantiate an explicit specialization. + if (Def->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) + return; + + // C++0x [temp.explicit]p9: + // Except for inline functions, other explicit instantiation declarations + // have the effect of suppressing the implicit instantiation of the entity + // to which they refer. + if (Def->getTemplateSpecializationKind() + == TSK_ExplicitInstantiationDeclaration) + return; InstantiatingTemplate Inst(*this, PointOfInstantiation, Var); if (Inst) |