diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 90 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiate.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 28 |
3 files changed, 59 insertions, 69 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 9f2e757dc2f..80863e35e29 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2887,7 +2887,7 @@ void Sema::MergeVarDeclTypes(VarDecl *New, VarDecl *Old, /// definitions here, since the initializer hasn't been attached. /// void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous, - bool IsVariableTemplate, bool MergeTypeWithPrevious) { + bool MergeTypeWithPrevious) { // If the new decl is already invalid, don't do any other checking. if (New->isInvalidDecl()) return; @@ -2896,7 +2896,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous, VarDecl *Old = 0; if (Previous.isSingleResult() && (Old = dyn_cast<VarDecl>(Previous.getFoundDecl()))) { - if (IsVariableTemplate) + if (New->getDescribedVarTemplate()) Old = Old->getDescribedVarTemplate() ? Old : 0; else Old = Old->getDescribedVarTemplate() ? 0 : Old; @@ -3039,6 +3039,11 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous, // Inherit access appropriately. New->setAccess(Old->getAccess()); + + if (VarTemplateDecl *VTD = New->getDescribedVarTemplate()) { + if (New->isStaticDataMember() && New->isOutOfLine()) + VTD->setAccess(New->getAccess()); + } } /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with @@ -4893,10 +4898,9 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, bool IsVariableTemplateSpecialization = false; bool IsPartialSpecialization = false; bool IsVariableTemplate = false; - bool Invalid = false; // TODO: Can we remove this (error-prone)? - TemplateParameterList *TemplateParams = 0; VarTemplateDecl *PrevVarTemplate = 0; - VarDecl *NewVD; + VarDecl *NewVD = 0; + VarTemplateDecl *NewTemplate = 0; if (!getLangOpts().CPlusPlus) { NewVD = VarDecl::Create(Context, DC, D.getLocStart(), D.getIdentifierLoc(), II, @@ -4905,6 +4909,8 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (D.isInvalidType()) NewVD->setInvalidDecl(); } else { + bool Invalid = false; + if (DC->isRecord() && !CurContext->isRecord()) { // This is an out-of-line definition of a static data member. switch (SC) { @@ -4963,10 +4969,11 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, // Match up the template parameter lists with the scope specifier, then // determine whether we have a template or a template specialization. - TemplateParams = MatchTemplateParametersToScopeSpecifier( - D.getDeclSpec().getLocStart(), D.getIdentifierLoc(), - D.getCXXScopeSpec(), TemplateParamLists, - /*never a friend*/ false, IsExplicitSpecialization, Invalid); + TemplateParameterList *TemplateParams = + MatchTemplateParametersToScopeSpecifier( + D.getDeclSpec().getLocStart(), D.getIdentifierLoc(), + D.getCXXScopeSpec(), TemplateParamLists, + /*never a friend*/ false, IsExplicitSpecialization, Invalid); if (TemplateParams) { if (!TemplateParams->size() && D.getName().getKind() != UnqualifiedId::IK_TemplateId) { @@ -5090,13 +5097,24 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, NewVD = VarDecl::Create(Context, DC, D.getLocStart(), D.getIdentifierLoc(), II, R, TInfo, SC); + // If this is supposed to be a variable template, create it as such. + if (IsVariableTemplate) { + NewTemplate = + VarTemplateDecl::Create(Context, DC, D.getIdentifierLoc(), Name, + TemplateParams, NewVD, PrevVarTemplate); + NewVD->setDescribedVarTemplate(NewTemplate); + } + // If this decl has an auto type in need of deduction, make a note of the // Decl so we can diagnose uses of it in its own initializer. if (D.getDeclSpec().containsPlaceholderType() && R->getContainedAutoType()) ParsingInitForAutoVars.insert(NewVD); - if (D.isInvalidType() || Invalid) + if (D.isInvalidType() || Invalid) { NewVD->setInvalidDecl(); + if (NewTemplate) + NewTemplate->setInvalidDecl(); + } SetNestedNameSpecifier(NewVD, D); @@ -5120,6 +5138,8 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, // Set the lexical context. If the declarator has a C++ scope specifier, the // lexical context will be different from the semantic context. NewVD->setLexicalDeclContext(CurContext); + if (NewTemplate) + NewTemplate->setLexicalDeclContext(CurContext); if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec()) { if (NewVD->hasLocalStorage()) { @@ -5178,8 +5198,11 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, << 0 << NewVD->getDeclName() << SourceRange(D.getDeclSpec().getModulePrivateSpecLoc()) << FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc()); - else + else { NewVD->setModulePrivate(); + if (NewTemplate) + NewTemplate->setModulePrivate(); + } } // Handle attributes prior to checking for duplicates in MergeVarDecl @@ -5238,7 +5261,6 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, } // Diagnose shadowed variables before filtering for scope. - // FIXME: Special treatment for static variable template members (?). if (!D.getCXXScopeSpec().isSet()) CheckShadow(S, NewVD, Previous); @@ -5285,15 +5307,12 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, LookupResult PrevDecl(*this, GetNameForDeclarator(D), LookupOrdinaryName, ForRedeclaration); PrevDecl.addDecl(PrevVarTemplate->getTemplatedDecl()); - D.setRedeclaration( - CheckVariableDeclaration(NewVD, PrevDecl, IsVariableTemplate)); + D.setRedeclaration(CheckVariableDeclaration(NewVD, PrevDecl)); } else - D.setRedeclaration( - CheckVariableDeclaration(NewVD, Previous, IsVariableTemplate)); + D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous)); } // This is an explicit specialization of a static data member. Check it. - // FIXME: Special treatment for static variable template members (?). if (IsExplicitSpecialization && !NewVD->isInvalidDecl() && CheckMemberSpecialization(NewVD, Previous)) NewVD->setInvalidDecl(); @@ -5317,40 +5336,17 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, } } - // If this is not a variable template, return it now. - if (!IsVariableTemplate) - return NewVD; - - // If this is supposed to be a variable template, create it as such. - VarTemplateDecl *NewTemplate = - VarTemplateDecl::Create(Context, DC, D.getIdentifierLoc(), Name, - TemplateParams, NewVD, PrevVarTemplate); - NewVD->setDescribedVarTemplate(NewTemplate); - - if (D.getDeclSpec().isModulePrivateSpecified()) - NewTemplate->setModulePrivate(); - // If we are providing an explicit specialization of a static variable // template, make a note of that. if (PrevVarTemplate && PrevVarTemplate->getInstantiatedFromMemberTemplate()) PrevVarTemplate->setMemberSpecialization(); - // Set the lexical context of this template - NewTemplate->setLexicalDeclContext(CurContext); - if (NewVD->isStaticDataMember() && NewVD->isOutOfLine()) - NewTemplate->setAccess(NewVD->getAccess()); - - PushOnScopeChains(NewTemplate, S); - AddToScope = false; - - if (Invalid) { - NewTemplate->setInvalidDecl(); - NewVD->setInvalidDecl(); + if (NewTemplate) { + ActOnDocumentableDecl(NewTemplate); + return NewTemplate; } - ActOnDocumentableDecl(NewTemplate); - - return NewTemplate; + return NewVD; } /// \brief Diagnose variable or built-in function shadowing. Implements @@ -5716,9 +5712,7 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { /// Sets NewVD->isInvalidDecl() if an error was encountered. /// /// Returns true if the variable declaration is a redeclaration. -bool Sema::CheckVariableDeclaration(VarDecl *NewVD, - LookupResult &Previous, - bool IsVariableTemplate) { +bool Sema::CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous) { CheckVariableDeclarationType(NewVD); // If the decl is already known invalid, don't check it. @@ -5768,7 +5762,7 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD, filterNonConflictingPreviousDecls(Context, NewVD, Previous); if (!Previous.empty()) { - MergeVarDecl(NewVD, Previous, IsVariableTemplate, MergeTypeWithPrevious); + MergeVarDecl(NewVD, Previous, MergeTypeWithPrevious); return true; } return false; diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 9f84fc665b1..9b7b4a85966 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -2254,12 +2254,10 @@ namespace { }; } -bool -Sema::InstantiateClassTemplateSpecialization( - SourceLocation PointOfInstantiation, - ClassTemplateSpecializationDecl *ClassTemplateSpec, - TemplateSpecializationKind TSK, - bool Complain) { +bool Sema::InstantiateClassTemplateSpecialization( + SourceLocation PointOfInstantiation, + ClassTemplateSpecializationDecl *ClassTemplateSpec, + TemplateSpecializationKind TSK, bool Complain) { // Perform the actual instantiation on the canonical declaration. ClassTemplateSpec = cast<ClassTemplateSpecializationDecl>( ClassTemplateSpec->getCanonicalDecl()); diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 8d066a0ac2b..37511d0b36e 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -320,10 +320,11 @@ TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) { // FIXME: Revise for static member templates. Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { - return VisitVarDecl(D, /*ForVarTemplate=*/false); + return VisitVarDecl(D, /*InstantiatingVarTemplate=*/false); } -Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D, bool ForVarTemplate) { +Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D, + bool InstantiatingVarTemplate) { // If this is the variable for an anonymous struct or union, // instantiate the anonymous struct/union type first. @@ -361,7 +362,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D, bool ForVarTemplate) { return 0; SemaRef.BuildVariableInstantiation(Var, D, TemplateArgs, LateAttrs, - StartingScope, ForVarTemplate); + StartingScope, InstantiatingVarTemplate); return Var; } @@ -971,7 +972,8 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateDecl(VarTemplateDecl *D) { } VarDecl *VarInst = - cast_or_null<VarDecl>(VisitVarDecl(Pattern, /*ForVarTemplate=*/ true)); + cast_or_null<VarDecl>(VisitVarDecl(Pattern, + /*InstantiatingVarTemplate=*/true)); DeclContext *DC = Owner; @@ -2649,8 +2651,6 @@ TemplateDeclInstantiator::InstantiateVarTemplatePartialSpecialization( InstPartialSpec->setInstantiatedFromMember(PartialSpec); InstPartialSpec->setTypeAsWritten(WrittenTy); - InstPartialSpec->setAccess(PartialSpec->getAccess()); - // 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); @@ -3314,9 +3314,8 @@ VarTemplateSpecializationDecl *Sema::CompleteVarTemplateSpecializationDecl( void Sema::BuildVariableInstantiation( VarDecl *NewVar, VarDecl *OldVar, const MultiLevelTemplateArgumentList &TemplateArgs, - LateInstantiatedAttrVec *LateAttrs, - LocalInstantiationScope *StartingScope, - bool ForVarTemplate) { + LateInstantiatedAttrVec *LateAttrs, LocalInstantiationScope *StartingScope, + bool InstantiatingVarTemplate) { // If we are instantiating a static data member defined // out-of-line, the instantiation will have the same lexical @@ -3354,15 +3353,14 @@ void Sema::BuildVariableInstantiation( } else if (!isa<VarTemplateSpecializationDecl>(NewVar) && OldVar->hasLinkage()) LookupQualifiedName(Previous, NewVar->getDeclContext(), false); - - CheckVariableDeclaration(NewVar, Previous, ForVarTemplate); + CheckVariableDeclaration(NewVar, Previous); if (OldVar->isOutOfLine()) { OldVar->getLexicalDeclContext()->addDecl(NewVar); - if (!ForVarTemplate) + if (!InstantiatingVarTemplate) NewVar->getDeclContext()->makeDeclVisibleInContext(NewVar); } else { - if (!ForVarTemplate) + if (!InstantiatingVarTemplate) NewVar->getDeclContext()->addDecl(NewVar); if (NewVar->getDeclContext()->isFunctionOrMethod()) CurrentInstantiationScope->InstantiatedLocal(OldVar, NewVar); @@ -3370,13 +3368,13 @@ void Sema::BuildVariableInstantiation( // Link instantiations of static data members back to the template from // which they were instantiated. - if (NewVar->isStaticDataMember() && !ForVarTemplate) + if (NewVar->isStaticDataMember() && !InstantiatingVarTemplate) NewVar->setInstantiationOfStaticDataMember(OldVar, TSK_ImplicitInstantiation); if (isa<VarTemplateSpecializationDecl>(NewVar)) { // Do not instantiate the variable just yet. - } else if (ForVarTemplate) { + } else if (InstantiatingVarTemplate) { assert(!NewVar->getInit() && "A variable should not have an initializer if it is templated" " and we are instantiating its template"); |