summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-10-08 07:24:58 +0000
committerDouglas Gregor <dgregor@apple.com>2009-10-08 07:24:58 +0000
commit86d142a80113e9e1d11996f7d5bd9baecfd5a69f (patch)
treebcd566f2c7f57438bf8210308e750e62486114f4 /clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
parent662efc91852b5fb3abda0ecc4ad3550c2f8a799f (diff)
downloadbcm5719-llvm-86d142a80113e9e1d11996f7d5bd9baecfd5a69f.tar.gz
bcm5719-llvm-86d142a80113e9e1d11996f7d5bd9baecfd5a69f.zip
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. llvm-svn: 83533
Diffstat (limited to 'clang/lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp28
1 files changed, 21 insertions, 7 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index fcacb4a3f00..bafcea054e1 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/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)
OpenPOWER on IntegriCloud