diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 37 |
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); |