summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp7
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp5
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp37
3 files changed, 21 insertions, 28 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 9dad47fb8f5..9f2e757dc2f 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -5333,18 +5333,13 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// If we are providing an explicit specialization of a static variable
// template, make a note of that.
if (PrevVarTemplate && PrevVarTemplate->getInstantiatedFromMemberTemplate())
- NewTemplate->setMemberSpecialization();
+ PrevVarTemplate->setMemberSpecialization();
// Set the lexical context of this template
NewTemplate->setLexicalDeclContext(CurContext);
if (NewVD->isStaticDataMember() && NewVD->isOutOfLine())
NewTemplate->setAccess(NewVD->getAccess());
- if (PrevVarTemplate)
- mergeDeclAttributes(NewVD, PrevVarTemplate->getTemplatedDecl());
-
- AddPushedVisibilityAttribute(NewVD);
-
PushOnScopeChains(NewTemplate, S);
AddToScope = false;
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 5d0169173cd..f4f43ab05b6 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2391,7 +2391,7 @@ DeclResult Sema::ActOnVarTemplateSpecialization(
// If we are providing an explicit specialization of a member variable
// template specialization, make a note of that.
if (PrevPartial && PrevPartial->getInstantiatedFromMember())
- Partial->setMemberSpecialization();
+ PrevPartial->setMemberSpecialization();
// Check that all of the template parameters of the variable template
// partial specialization are deducible from the template
@@ -2477,6 +2477,9 @@ DeclResult Sema::ActOnVarTemplateSpecialization(
ForRedeclaration);
PrevSpec.addDecl(PrevDecl);
D.setRedeclaration(CheckVariableDeclaration(Specialization, PrevSpec));
+ } else if (Specialization->isStaticDataMember() &&
+ Specialization->isOutOfLine()) {
+ Specialization->setAccess(VarTemplate->getAccess());
}
// Link instantiations of static data members back to the template from
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index b53c197d526..8d066a0ac2b 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -952,7 +952,6 @@ TemplateDeclInstantiator::VisitClassTemplatePartialSpecializationDecl(
Decl *TemplateDeclInstantiator::VisitVarTemplateDecl(VarTemplateDecl *D) {
assert(D->getTemplatedDecl()->isStaticDataMember() &&
"Only static data member templates are allowed.");
- // FIXME: Also only when instantiating a class?
// Create a local instantiation scope for this variable template, which
// will contain the instantiations of the template parameters.
@@ -971,28 +970,11 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateDecl(VarTemplateDecl *D) {
PrevVarTemplate = dyn_cast<VarTemplateDecl>(Found.front());
}
- // FIXME: This, and ForVarTemplate, is a hack that is probably unnecessary.
- // We should use a simplified version of VisitVarDecl.
VarDecl *VarInst =
cast_or_null<VarDecl>(VisitVarDecl(Pattern, /*ForVarTemplate=*/ true));
DeclContext *DC = Owner;
- /* FIXME: This should be handled in VisitVarDecl, as used to produce
- VarInst above.
- // Instantiate the qualifier.
- NestedNameSpecifierLoc QualifierLoc = Pattern->getQualifierLoc();
- if (QualifierLoc) {
- QualifierLoc =
- SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, TemplateArgs);
- if (!QualifierLoc)
- return 0;
- }
-
- if (QualifierLoc)
- VarInst->setQualifierInfo(QualifierLoc);
- */
-
VarTemplateDecl *Inst = VarTemplateDecl::Create(
SemaRef.Context, DC, D->getLocation(), D->getIdentifier(), InstParams,
VarInst, PrevVarTemplate);
@@ -1028,7 +1010,6 @@ Decl *TemplateDeclInstantiator::VisitVarTemplatePartialSpecializationDecl(
VarTemplatePartialSpecializationDecl *D) {
assert(D->isStaticDataMember() &&
"Only static data member templates are allowed.");
- // FIXME: Also only when instantiating a class?
VarTemplateDecl *VarTemplate = D->getSpecializedTemplate();
@@ -2669,11 +2650,18 @@ TemplateDeclInstantiator::InstantiateVarTemplatePartialSpecialization(
InstPartialSpec->setTypeAsWritten(WrittenTy);
InstPartialSpec->setAccess(PartialSpec->getAccess());
- // FIXME: How much of BuildVariableInstantiation() should go in here?
// Add this partial specialization to the set of variable template partial
// specializations. The instantiation of the initializer is not necessary.
VarTemplate->AddPartialSpecialization(InstPartialSpec, /*InsertPos=*/0);
+
+ // Set the initializer, to use as pattern for initialization.
+ if (VarDecl *Def = PartialSpec->getDefinition(SemaRef.getASTContext()))
+ PartialSpec = cast<VarTemplatePartialSpecializationDecl>(Def);
+ SemaRef.BuildVariableInstantiation(InstPartialSpec, PartialSpec, TemplateArgs,
+ LateAttrs, StartingScope);
+ InstPartialSpec->setInit(PartialSpec->getInit());
+
return InstPartialSpec;
}
@@ -3303,8 +3291,10 @@ VarTemplateSpecializationDecl *Sema::CompleteVarTemplateSpecializationDecl(
const MultiLevelTemplateArgumentList &TemplateArgs) {
// Do substitution on the type of the declaration
+ MultiLevelTemplateArgumentList Innermost;
+ Innermost.addOuterTemplateArguments(TemplateArgs.getInnermost());
TypeSourceInfo *DI =
- SubstType(PatternDecl->getTypeSourceInfo(), TemplateArgs,
+ SubstType(PatternDecl->getTypeSourceInfo(), Innermost,
PatternDecl->getTypeSpecStartLoc(), PatternDecl->getDeclName());
if (!DI)
return 0;
@@ -3386,6 +3376,11 @@ void Sema::BuildVariableInstantiation(
if (isa<VarTemplateSpecializationDecl>(NewVar)) {
// Do not instantiate the variable just yet.
+ } else if (ForVarTemplate) {
+ assert(!NewVar->getInit() &&
+ "A variable should not have an initializer if it is templated"
+ " and we are instantiating its template");
+ NewVar->setInit(OldVar->getInit());
} else
InstantiateVariableInitializer(NewVar, OldVar, TemplateArgs);
OpenPOWER on IntegriCloud