diff options
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 110 |
1 files changed, 63 insertions, 47 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 4a26efcc9431..f627f6017f38 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1195,7 +1195,8 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { // Look for a previous declaration of the template in the owning // context. LookupResult R(SemaRef, Pattern->getDeclName(), Pattern->getLocation(), - Sema::LookupOrdinaryName, Sema::ForRedeclaration); + Sema::LookupOrdinaryName, + SemaRef.forRedeclarationInCurContext()); SemaRef.LookupQualifiedName(R, DC); if (R.isSingleResult()) { @@ -1650,11 +1651,13 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, } FunctionDecl *Function; - if (auto *DGuide = dyn_cast<CXXDeductionGuideDecl>(D)) + if (auto *DGuide = dyn_cast<CXXDeductionGuideDecl>(D)) { Function = CXXDeductionGuideDecl::Create( - SemaRef.Context, DC, D->getInnerLocStart(), DGuide->isExplicit(), - D->getNameInfo(), T, TInfo, D->getSourceRange().getEnd()); - else { + SemaRef.Context, DC, D->getInnerLocStart(), DGuide->isExplicit(), + D->getNameInfo(), T, TInfo, D->getSourceRange().getEnd()); + if (DGuide->isCopyDeductionCandidate()) + cast<CXXDeductionGuideDecl>(Function)->setIsCopyDeductionCandidate(); + } else { Function = FunctionDecl::Create( SemaRef.Context, DC, D->getInnerLocStart(), D->getNameInfo(), T, TInfo, D->getCanonicalDecl()->getStorageClass(), D->isInlineSpecified(), @@ -1685,7 +1688,6 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, Params[P]->setOwningFunction(Function); Function->setParams(Params); - SourceLocation InstantiateAtPOI; if (TemplateParams) { // Our resulting instantiation is actually a function template, since we // are substituting only the outer template parameters. For example, given @@ -1736,7 +1738,8 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, SemaRef, Function->getDeclName(), SourceLocation(), D->isLocalExternDecl() ? Sema::LookupRedeclarationWithLinkage : Sema::LookupOrdinaryName, - Sema::ForRedeclaration); + D->isLocalExternDecl() ? Sema::ForExternalRedeclaration + : SemaRef.forRedeclarationInCurContext()); if (DependentFunctionTemplateSpecializationInfo *Info = D->getDependentSpecializationInfo()) { @@ -2054,7 +2057,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, Method->setInvalidDecl(); LookupResult Previous(SemaRef, NameInfo, Sema::LookupOrdinaryName, - Sema::ForRedeclaration); + Sema::ForExternalRedeclaration); if (!FunctionTemplate || TemplateParams || isFriend) { SemaRef.LookupQualifiedName(Previous, Record); @@ -2493,7 +2496,7 @@ Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) { bool CheckRedeclaration = Owner->isRecord(); LookupResult Prev(SemaRef, NameInfo, Sema::LookupUsingDeclName, - Sema::ForRedeclaration); + Sema::ForVisibleRedeclaration); UsingDecl *NewUD = UsingDecl::Create(SemaRef.Context, Owner, D->getUsingLoc(), @@ -2712,7 +2715,7 @@ Decl *TemplateDeclInstantiator::VisitClassScopeFunctionSpecializationDecl( return nullptr; LookupResult Previous(SemaRef, NewFD->getNameInfo(), Sema::LookupOrdinaryName, - Sema::ForRedeclaration); + Sema::ForExternalRedeclaration); TemplateArgumentListInfo TemplateArgs; TemplateArgumentListInfo *TemplateArgsPtr = nullptr; @@ -2800,8 +2803,9 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl( SemaRef.ActOnOpenMPDeclareReductionCombinerEnd(NewDRD, SubstCombiner); // Initializers instantiation sequence. if (D->getInitializer()) { - SemaRef.ActOnOpenMPDeclareReductionInitializerStart( - /*S=*/nullptr, NewDRD); + VarDecl *OmpPrivParm = + SemaRef.ActOnOpenMPDeclareReductionInitializerStart( + /*S=*/nullptr, NewDRD); const char *Names[] = {"omp_orig", "omp_priv"}; for (auto &Name : Names) { DeclarationName DN(&SemaRef.Context.Idents.get(Name)); @@ -2809,17 +2813,28 @@ Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl( auto Lookup = NewDRD->lookup(DN); if (!OldLookup.empty() && !Lookup.empty()) { assert(Lookup.size() == 1 && OldLookup.size() == 1); - SemaRef.CurrentInstantiationScope->InstantiatedLocal( - OldLookup.front(), Lookup.front()); + auto *OldVD = cast<VarDecl>(OldLookup.front()); + auto *NewVD = cast<VarDecl>(Lookup.front()); + SemaRef.InstantiateVariableInitializer(NewVD, OldVD, TemplateArgs); + SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldVD, NewVD); } } - SubstInitializer = - SemaRef.SubstExpr(D->getInitializer(), TemplateArgs).get(); - SemaRef.ActOnOpenMPDeclareReductionInitializerEnd(NewDRD, - SubstInitializer); + if (D->getInitializerKind() == OMPDeclareReductionDecl::CallInit) { + SubstInitializer = + SemaRef.SubstExpr(D->getInitializer(), TemplateArgs).get(); + } else { + IsCorrect = IsCorrect && OmpPrivParm->hasInit(); + } + SemaRef.ActOnOpenMPDeclareReductionInitializerEnd( + NewDRD, SubstInitializer, OmpPrivParm); } - IsCorrect = IsCorrect && SubstCombiner && - (!D->getInitializer() || SubstInitializer); + IsCorrect = + IsCorrect && SubstCombiner && + (!D->getInitializer() || + (D->getInitializerKind() == OMPDeclareReductionDecl::CallInit && + SubstInitializer) || + (D->getInitializerKind() != OMPDeclareReductionDecl::CallInit && + !SubstInitializer && !SubstInitializer)); } else IsCorrect = false; @@ -3753,7 +3768,8 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, bool Recursive, bool DefinitionRequired, bool AtEndOfTU) { - if (Function->isInvalidDecl() || Function->isDefined()) + if (Function->isInvalidDecl() || Function->isDefined() || + isa<CXXDeductionGuideDecl>(Function)) return; // Never instantiate an explicit specialization except if it is a class scope @@ -4005,6 +4021,8 @@ VarTemplateSpecializationDecl *Sema::BuildVarTemplateInstantiation( VarTemplateSpecializationDecl *Sema::CompleteVarTemplateSpecializationDecl( VarTemplateSpecializationDecl *VarSpec, VarDecl *PatternDecl, const MultiLevelTemplateArgumentList &TemplateArgs) { + assert(PatternDecl->isThisDeclarationADefinition() && + "don't have a definition to instantiate from"); // Do substitution on the type of the declaration TypeSourceInfo *DI = @@ -4016,6 +4034,9 @@ VarTemplateSpecializationDecl *Sema::CompleteVarTemplateSpecializationDecl( // Update the type of this variable template specialization. VarSpec->setType(DI->getType()); + // Convert the declaration into a definition now. + VarSpec->setCompleteDefinition(); + // Instantiate the initializer. InstantiateVariableInitializer(VarSpec, PatternDecl, TemplateArgs); @@ -4063,7 +4084,8 @@ void Sema::BuildVariableInstantiation( *this, NewVar->getDeclName(), NewVar->getLocation(), NewVar->isLocalExternDecl() ? Sema::LookupRedeclarationWithLinkage : Sema::LookupOrdinaryName, - Sema::ForRedeclaration); + NewVar->isLocalExternDecl() ? Sema::ForExternalRedeclaration + : forRedeclarationInCurContext()); if (NewVar->isLocalExternDecl() && OldVar->getPreviousDecl() && (!OldVar->getPreviousDecl()->getDeclContext()->isDependentContext() || @@ -4120,6 +4142,9 @@ void Sema::BuildVariableInstantiation( void Sema::InstantiateVariableInitializer( VarDecl *Var, VarDecl *OldVar, const MultiLevelTemplateArgumentList &TemplateArgs) { + if (ASTMutationListener *L = getASTContext().getASTMutationListener()) + L->VariableDefinitionInstantiated(Var); + // We propagate the 'inline' flag with the initializer, because it // would otherwise imply that the variable is a definition for a // non-static data member. @@ -4129,12 +4154,8 @@ void Sema::InstantiateVariableInitializer( Var->setImplicitlyInline(); if (OldVar->getInit()) { - if (Var->isStaticDataMember() && !OldVar->isOutOfLine()) - PushExpressionEvaluationContext( - Sema::ExpressionEvaluationContext::ConstantEvaluated, OldVar); - else - PushExpressionEvaluationContext( - Sema::ExpressionEvaluationContext::PotentiallyEvaluated, OldVar); + EnterExpressionEvaluationContext Evaluated( + *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated, Var); // Instantiate the initializer. ExprResult Init; @@ -4162,8 +4183,6 @@ void Sema::InstantiateVariableInitializer( // because of a bogus initializer. Var->setInvalidDecl(); } - - PopExpressionEvaluationContext(); } else { if (Var->isStaticDataMember()) { if (!Var->isOutOfLine()) @@ -4188,26 +4207,16 @@ void Sema::InstantiateVariableInitializer( /// /// \param PointOfInstantiation the point at which the instantiation was /// required. Note that this is not precisely a "point of instantiation" -/// for the function, but it's close. +/// for the variable, but it's close. /// -/// \param Var the already-instantiated declaration of a static member -/// variable of a class template specialization. +/// \param Var the already-instantiated declaration of a templated variable. /// /// \param Recursive if true, recursively instantiates any functions that /// are required by this instantiation. /// /// \param DefinitionRequired if true, then we are performing an explicit -/// instantiation where an out-of-line definition of the member variable -/// is required. Complain if there is no such definition. -void Sema::InstantiateStaticDataMemberDefinition( - SourceLocation PointOfInstantiation, - VarDecl *Var, - bool Recursive, - bool DefinitionRequired) { - InstantiateVariableDefinition(PointOfInstantiation, Var, Recursive, - DefinitionRequired); -} - +/// instantiation where a definition of the variable is required. Complain +/// if there is no such definition. void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation, VarDecl *Var, bool Recursive, bool DefinitionRequired, bool AtEndOfTU) { @@ -4264,6 +4273,11 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation, // If this is a static data member template, there might be an // uninstantiated initializer on the declaration. If so, instantiate // it now. + // + // FIXME: This largely duplicates what we would do below. The difference + // is that along this path we may instantiate an initializer from an + // in-class declaration of the template and instantiate the definition + // from a separate out-of-class definition. if (PatternDecl->isStaticDataMember() && (PatternDecl = PatternDecl->getFirstDecl())->hasInit() && !Var->hasInit()) { @@ -4351,10 +4365,12 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation, return; // C++11 [temp.explicit]p10: - // Except for inline functions, [...] explicit instantiation declarations + // Except for inline functions, const variables of literal types, variables + // of reference types, [...] explicit instantiation declarations // have the effect of suppressing the implicit instantiation of the entity // to which they refer. - if (TSK == TSK_ExplicitInstantiationDeclaration) + if (TSK == TSK_ExplicitInstantiationDeclaration && + !Var->isUsableInConstantExpressions(getASTContext())) return; // Make sure to pass the instantiated variable to the consumer at the end. @@ -4427,7 +4443,7 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation, // Merge the definition with the declaration. LookupResult R(*this, Var->getDeclName(), Var->getLocation(), - LookupOrdinaryName, ForRedeclaration); + LookupOrdinaryName, forRedeclarationInCurContext()); R.addDecl(OldVar); MergeVarDecl(Var, R); |