diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp | 268 |
1 files changed, 127 insertions, 141 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp index 6ac7175..82ff7c0 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -200,13 +200,19 @@ bool Sema::ActiveTemplateInstantiation::isInstantiationRecord() const { llvm_unreachable("Invalid InstantiationKind!"); } -void Sema::InstantiatingTemplate::Initialize( - ActiveTemplateInstantiation::InstantiationKind Kind, +Sema::InstantiatingTemplate::InstantiatingTemplate( + Sema &SemaRef, ActiveTemplateInstantiation::InstantiationKind Kind, SourceLocation PointOfInstantiation, SourceRange InstantiationRange, Decl *Entity, NamedDecl *Template, ArrayRef<TemplateArgument> TemplateArgs, - sema::TemplateDeductionInfo *DeductionInfo) { - SavedInNonInstantiationSFINAEContext = - SemaRef.InNonInstantiationSFINAEContext; + sema::TemplateDeductionInfo *DeductionInfo) + : SemaRef(SemaRef), SavedInNonInstantiationSFINAEContext( + SemaRef.InNonInstantiationSFINAEContext) { + // Don't allow further instantiation if a fatal error has occcured. Any + // diagnostics we might have raised will not be visible. + if (SemaRef.Diags.hasFatalErrorOccurred()) { + Invalid = true; + return; + } Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange); if (!Invalid) { ActiveTemplateInstantiation Inst; @@ -225,124 +231,98 @@ void Sema::InstantiatingTemplate::Initialize( } } -Sema::InstantiatingTemplate:: -InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, - Decl *Entity, - SourceRange InstantiationRange) - : SemaRef(SemaRef) -{ - Initialize(ActiveTemplateInstantiation::TemplateInstantiation, - PointOfInstantiation, InstantiationRange, Entity); -} - -Sema::InstantiatingTemplate:: -InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, - FunctionDecl *Entity, ExceptionSpecification, - SourceRange InstantiationRange) - : SemaRef(SemaRef) -{ - Initialize(ActiveTemplateInstantiation::ExceptionSpecInstantiation, - PointOfInstantiation, InstantiationRange, Entity); -} - -Sema::InstantiatingTemplate:: -InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, - TemplateDecl *Template, - ArrayRef<TemplateArgument> TemplateArgs, - SourceRange InstantiationRange) - : SemaRef(SemaRef) -{ - Initialize(ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation, - PointOfInstantiation, InstantiationRange, - Template, nullptr, TemplateArgs); -} - -Sema::InstantiatingTemplate:: -InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, - FunctionTemplateDecl *FunctionTemplate, - ArrayRef<TemplateArgument> TemplateArgs, - ActiveTemplateInstantiation::InstantiationKind Kind, - sema::TemplateDeductionInfo &DeductionInfo, - SourceRange InstantiationRange) - : SemaRef(SemaRef) -{ - Initialize(Kind, PointOfInstantiation, InstantiationRange, - FunctionTemplate, nullptr, TemplateArgs, &DeductionInfo); -} - -Sema::InstantiatingTemplate:: -InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, - ClassTemplatePartialSpecializationDecl *PartialSpec, - ArrayRef<TemplateArgument> TemplateArgs, - sema::TemplateDeductionInfo &DeductionInfo, - SourceRange InstantiationRange) - : SemaRef(SemaRef) -{ - Initialize(ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution, - PointOfInstantiation, InstantiationRange, - PartialSpec, nullptr, TemplateArgs, &DeductionInfo); -} +Sema::InstantiatingTemplate::InstantiatingTemplate( + Sema &SemaRef, SourceLocation PointOfInstantiation, Decl *Entity, + SourceRange InstantiationRange) + : InstantiatingTemplate(SemaRef, + ActiveTemplateInstantiation::TemplateInstantiation, + PointOfInstantiation, InstantiationRange, Entity) {} + +Sema::InstantiatingTemplate::InstantiatingTemplate( + Sema &SemaRef, SourceLocation PointOfInstantiation, FunctionDecl *Entity, + ExceptionSpecification, SourceRange InstantiationRange) + : InstantiatingTemplate( + SemaRef, ActiveTemplateInstantiation::ExceptionSpecInstantiation, + PointOfInstantiation, InstantiationRange, Entity) {} + +Sema::InstantiatingTemplate::InstantiatingTemplate( + Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateDecl *Template, + ArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange) + : InstantiatingTemplate( + SemaRef, + ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation, + PointOfInstantiation, InstantiationRange, Template, nullptr, + TemplateArgs) {} + +Sema::InstantiatingTemplate::InstantiatingTemplate( + Sema &SemaRef, SourceLocation PointOfInstantiation, + FunctionTemplateDecl *FunctionTemplate, + ArrayRef<TemplateArgument> TemplateArgs, + ActiveTemplateInstantiation::InstantiationKind Kind, + sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange) + : InstantiatingTemplate(SemaRef, Kind, PointOfInstantiation, + InstantiationRange, FunctionTemplate, nullptr, + TemplateArgs, &DeductionInfo) {} + +Sema::InstantiatingTemplate::InstantiatingTemplate( + Sema &SemaRef, SourceLocation PointOfInstantiation, + ClassTemplatePartialSpecializationDecl *PartialSpec, + ArrayRef<TemplateArgument> TemplateArgs, + sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange) + : InstantiatingTemplate( + SemaRef, + ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution, + PointOfInstantiation, InstantiationRange, PartialSpec, nullptr, + TemplateArgs, &DeductionInfo) {} Sema::InstantiatingTemplate::InstantiatingTemplate( Sema &SemaRef, SourceLocation PointOfInstantiation, VarTemplatePartialSpecializationDecl *PartialSpec, ArrayRef<TemplateArgument> TemplateArgs, sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange) - : SemaRef(SemaRef) -{ - Initialize(ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution, - PointOfInstantiation, InstantiationRange, - PartialSpec, nullptr, TemplateArgs, &DeductionInfo); -} - -Sema::InstantiatingTemplate:: -InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, - ParmVarDecl *Param, - ArrayRef<TemplateArgument> TemplateArgs, - SourceRange InstantiationRange) - : SemaRef(SemaRef) -{ - Initialize(ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation, - PointOfInstantiation, InstantiationRange, - Param, nullptr, TemplateArgs); -} - - -Sema::InstantiatingTemplate:: -InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, - NamedDecl *Template, NonTypeTemplateParmDecl *Param, - ArrayRef<TemplateArgument> TemplateArgs, - SourceRange InstantiationRange) - : SemaRef(SemaRef) -{ - Initialize(ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution, - PointOfInstantiation, InstantiationRange, - Param, Template, TemplateArgs); -} - -Sema::InstantiatingTemplate:: -InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, - NamedDecl *Template, TemplateTemplateParmDecl *Param, - ArrayRef<TemplateArgument> TemplateArgs, - SourceRange InstantiationRange) - : SemaRef(SemaRef) -{ - Initialize(ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution, - PointOfInstantiation, InstantiationRange, - Param, Template, TemplateArgs); -} - -Sema::InstantiatingTemplate:: -InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, - TemplateDecl *Template, NamedDecl *Param, - ArrayRef<TemplateArgument> TemplateArgs, - SourceRange InstantiationRange) - : SemaRef(SemaRef) -{ - Initialize(ActiveTemplateInstantiation::DefaultTemplateArgumentChecking, - PointOfInstantiation, InstantiationRange, - Param, Template, TemplateArgs); -} + : InstantiatingTemplate( + SemaRef, + ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution, + PointOfInstantiation, InstantiationRange, PartialSpec, nullptr, + TemplateArgs, &DeductionInfo) {} + +Sema::InstantiatingTemplate::InstantiatingTemplate( + Sema &SemaRef, SourceLocation PointOfInstantiation, ParmVarDecl *Param, + ArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange) + : InstantiatingTemplate( + SemaRef, + ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation, + PointOfInstantiation, InstantiationRange, Param, nullptr, + TemplateArgs) {} + +Sema::InstantiatingTemplate::InstantiatingTemplate( + Sema &SemaRef, SourceLocation PointOfInstantiation, NamedDecl *Template, + NonTypeTemplateParmDecl *Param, ArrayRef<TemplateArgument> TemplateArgs, + SourceRange InstantiationRange) + : InstantiatingTemplate( + SemaRef, + ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution, + PointOfInstantiation, InstantiationRange, Param, Template, + TemplateArgs) {} + +Sema::InstantiatingTemplate::InstantiatingTemplate( + Sema &SemaRef, SourceLocation PointOfInstantiation, NamedDecl *Template, + TemplateTemplateParmDecl *Param, ArrayRef<TemplateArgument> TemplateArgs, + SourceRange InstantiationRange) + : InstantiatingTemplate( + SemaRef, + ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution, + PointOfInstantiation, InstantiationRange, Param, Template, + TemplateArgs) {} + +Sema::InstantiatingTemplate::InstantiatingTemplate( + Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateDecl *Template, + NamedDecl *Param, ArrayRef<TemplateArgument> TemplateArgs, + SourceRange InstantiationRange) + : InstantiatingTemplate( + SemaRef, ActiveTemplateInstantiation::DefaultTemplateArgumentChecking, + PointOfInstantiation, InstantiationRange, Param, Template, + TemplateArgs) {} void Sema::InstantiatingTemplate::Clear() { if (!Invalid) { @@ -734,6 +714,20 @@ namespace { } void transformedLocalDecl(Decl *Old, Decl *New) { + // If we've instantiated the call operator of a lambda or the call + // operator template of a generic lambda, update the "instantiation of" + // information. + auto *NewMD = dyn_cast<CXXMethodDecl>(New); + if (NewMD && isLambdaCallOperator(NewMD)) { + auto *OldMD = dyn_cast<CXXMethodDecl>(Old); + if (auto *NewTD = NewMD->getDescribedFunctionTemplate()) + NewTD->setInstantiatedFromMemberTemplate( + OldMD->getDescribedFunctionTemplate()); + else + NewMD->setInstantiationOfMemberFunction(OldMD, + TSK_ImplicitInstantiation); + } + SemaRef.CurrentInstantiationScope->InstantiatedLocal(Old, New); } @@ -836,28 +830,6 @@ namespace { return TreeTransform<TemplateInstantiator>::TransformLambdaExpr(E); } - ExprResult TransformLambdaScope(LambdaExpr *E, - CXXMethodDecl *NewCallOperator, - ArrayRef<InitCaptureInfoTy> InitCaptureExprsAndTypes) { - CXXMethodDecl *const OldCallOperator = E->getCallOperator(); - // In the generic lambda case, we set the NewTemplate to be considered - // an "instantiation" of the OldTemplate. - if (FunctionTemplateDecl *const NewCallOperatorTemplate = - NewCallOperator->getDescribedFunctionTemplate()) { - - FunctionTemplateDecl *const OldCallOperatorTemplate = - OldCallOperator->getDescribedFunctionTemplate(); - NewCallOperatorTemplate->setInstantiatedFromMemberTemplate( - OldCallOperatorTemplate); - } else - // For a non-generic lambda we set the NewCallOperator to - // be an instantiation of the OldCallOperator. - NewCallOperator->setInstantiationOfMemberFunction(OldCallOperator, - TSK_ImplicitInstantiation); - - return inherited::TransformLambdaScope(E, NewCallOperator, - InitCaptureExprsAndTypes); - } TemplateParameterList *TransformTemplateParameterList( TemplateParameterList *OrigTPL) { if (!OrigTPL || !OrigTPL->size()) return OrigTPL; @@ -1767,7 +1739,7 @@ Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation, const MultiLevelTemplateArgumentList &TemplateArgs) { bool Invalid = false; SmallVector<CXXBaseSpecifier*, 4> InstantiatedBases; - for (const auto Base : Pattern->bases()) { + for (const auto &Base : Pattern->bases()) { if (!Base.getType()->isDependentType()) { if (const CXXRecordDecl *RD = Base.getType()->getAsCXXRecordDecl()) { if (RD->isInvalidDecl()) @@ -2063,6 +2035,10 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, SourceLocation(), SourceLocation(), nullptr); CheckCompletedCXXClass(Instantiation); + // Default arguments are parsed, if not instantiated. We can go instantiate + // default arg exprs for default constructors if necessary now. + ActOnFinishCXXMemberDefaultArgs(Instantiation); + // Instantiate late parsed attributes, and attach them to their decls. // See Sema::InstantiateAttrs for (LateInstantiatedAttrVec::iterator I = LateAttrs.begin(), @@ -2257,7 +2233,7 @@ bool Sema::InstantiateInClassInitializer( EnterExpressionEvaluationContext EvalContext(*this, Sema::PotentiallyEvaluated); - LocalInstantiationScope Scope(*this); + LocalInstantiationScope Scope(*this, true); // Instantiate the initializer. ActOnStartCXXInClassMemberInitializer(); @@ -2812,6 +2788,16 @@ LocalInstantiationScope::findInstantiationOf(const Decl *D) { isa<TemplateTemplateParmDecl>(D)) return nullptr; + // Local types referenced prior to definition may require instantiation. + if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) + if (RD->isLocalClass()) + return nullptr; + + // Enumeration types referenced prior to definition may appear as a result of + // error recovery. + if (isa<EnumDecl>(D)) + return nullptr; + // If we didn't find the decl, then we either have a sema bug, or we have a // forward reference to a label declaration. Return null to indicate that // we have an uninstantiated label. |