10b57cec5SDimitry Andric //===------- SemaTemplateInstantiate.cpp - C++ Template Instantiation ------===/
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //===----------------------------------------------------------------------===/
70b57cec5SDimitry Andric //
80b57cec5SDimitry Andric // This file implements C++ template instantiation.
90b57cec5SDimitry Andric //
100b57cec5SDimitry Andric //===----------------------------------------------------------------------===/
110b57cec5SDimitry Andric
120b57cec5SDimitry Andric #include "TreeTransform.h"
1381ad6265SDimitry Andric #include "clang/AST/ASTConcept.h"
140b57cec5SDimitry Andric #include "clang/AST/ASTConsumer.h"
150b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
160b57cec5SDimitry Andric #include "clang/AST/ASTLambda.h"
170b57cec5SDimitry Andric #include "clang/AST/ASTMutationListener.h"
18bdd1243dSDimitry Andric #include "clang/AST/DeclBase.h"
190b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h"
200b57cec5SDimitry Andric #include "clang/AST/Expr.h"
2181ad6265SDimitry Andric #include "clang/AST/ExprConcepts.h"
220b57cec5SDimitry Andric #include "clang/AST/PrettyDeclStackTrace.h"
236c4b055cSDimitry Andric #include "clang/AST/RecursiveASTVisitor.h"
24bdd1243dSDimitry Andric #include "clang/AST/Type.h"
250fca6ea1SDimitry Andric #include "clang/AST/TypeLoc.h"
2613138422SDimitry Andric #include "clang/AST/TypeVisitor.h"
270b57cec5SDimitry Andric #include "clang/Basic/LangOptions.h"
28a7dea167SDimitry Andric #include "clang/Basic/Stack.h"
295ffd83dbSDimitry Andric #include "clang/Basic/TargetInfo.h"
300b57cec5SDimitry Andric #include "clang/Sema/DeclSpec.h"
3106c3fb27SDimitry Andric #include "clang/Sema/EnterExpressionEvaluationContext.h"
320b57cec5SDimitry Andric #include "clang/Sema/Initialization.h"
330b57cec5SDimitry Andric #include "clang/Sema/Lookup.h"
34bdd1243dSDimitry Andric #include "clang/Sema/Sema.h"
355ffd83dbSDimitry Andric #include "clang/Sema/SemaConcept.h"
365ffd83dbSDimitry Andric #include "clang/Sema/SemaInternal.h"
370b57cec5SDimitry Andric #include "clang/Sema/Template.h"
380b57cec5SDimitry Andric #include "clang/Sema/TemplateDeduction.h"
390b57cec5SDimitry Andric #include "clang/Sema/TemplateInstCallback.h"
400fca6ea1SDimitry Andric #include "llvm/ADT/STLForwardCompat.h"
4106c3fb27SDimitry Andric #include "llvm/ADT/StringExtras.h"
42bdd1243dSDimitry Andric #include "llvm/Support/ErrorHandling.h"
430b57cec5SDimitry Andric #include "llvm/Support/TimeProfiler.h"
44bdd1243dSDimitry Andric #include <optional>
450b57cec5SDimitry Andric
460b57cec5SDimitry Andric using namespace clang;
470b57cec5SDimitry Andric using namespace sema;
480b57cec5SDimitry Andric
490b57cec5SDimitry Andric //===----------------------------------------------------------------------===/
500b57cec5SDimitry Andric // Template Instantiation Support
510b57cec5SDimitry Andric //===----------------------------------------------------------------------===/
520b57cec5SDimitry Andric
53bdd1243dSDimitry Andric namespace {
54bdd1243dSDimitry Andric namespace TemplateInstArgsHelpers {
55bdd1243dSDimitry Andric struct Response {
56bdd1243dSDimitry Andric const Decl *NextDecl = nullptr;
57bdd1243dSDimitry Andric bool IsDone = false;
58bdd1243dSDimitry Andric bool ClearRelativeToPrimary = true;
Done__anondb690eb50111::TemplateInstArgsHelpers::Response59bdd1243dSDimitry Andric static Response Done() {
60bdd1243dSDimitry Andric Response R;
61bdd1243dSDimitry Andric R.IsDone = true;
62bdd1243dSDimitry Andric return R;
63bdd1243dSDimitry Andric }
ChangeDecl__anondb690eb50111::TemplateInstArgsHelpers::Response64bdd1243dSDimitry Andric static Response ChangeDecl(const Decl *ND) {
65bdd1243dSDimitry Andric Response R;
66bdd1243dSDimitry Andric R.NextDecl = ND;
67bdd1243dSDimitry Andric return R;
68bdd1243dSDimitry Andric }
ChangeDecl__anondb690eb50111::TemplateInstArgsHelpers::Response69bdd1243dSDimitry Andric static Response ChangeDecl(const DeclContext *Ctx) {
70bdd1243dSDimitry Andric Response R;
71bdd1243dSDimitry Andric R.NextDecl = Decl::castFromDeclContext(Ctx);
72bdd1243dSDimitry Andric return R;
73bdd1243dSDimitry Andric }
740b57cec5SDimitry Andric
UseNextDecl__anondb690eb50111::TemplateInstArgsHelpers::Response75bdd1243dSDimitry Andric static Response UseNextDecl(const Decl *CurDecl) {
76bdd1243dSDimitry Andric return ChangeDecl(CurDecl->getDeclContext());
77bdd1243dSDimitry Andric }
780b57cec5SDimitry Andric
DontClearRelativeToPrimaryNextDecl__anondb690eb50111::TemplateInstArgsHelpers::Response79bdd1243dSDimitry Andric static Response DontClearRelativeToPrimaryNextDecl(const Decl *CurDecl) {
80bdd1243dSDimitry Andric Response R = Response::UseNextDecl(CurDecl);
81bdd1243dSDimitry Andric R.ClearRelativeToPrimary = false;
82bdd1243dSDimitry Andric return R;
83bdd1243dSDimitry Andric }
84bdd1243dSDimitry Andric };
850fca6ea1SDimitry Andric
860fca6ea1SDimitry Andric // Retrieve the primary template for a lambda call operator. It's
870fca6ea1SDimitry Andric // unfortunate that we only have the mappings of call operators rather
880fca6ea1SDimitry Andric // than lambda classes.
890fca6ea1SDimitry Andric const FunctionDecl *
getPrimaryTemplateOfGenericLambda(const FunctionDecl * LambdaCallOperator)900fca6ea1SDimitry Andric getPrimaryTemplateOfGenericLambda(const FunctionDecl *LambdaCallOperator) {
916c4b055cSDimitry Andric if (!isLambdaCallOperator(LambdaCallOperator))
926c4b055cSDimitry Andric return LambdaCallOperator;
930fca6ea1SDimitry Andric while (true) {
940fca6ea1SDimitry Andric if (auto *FTD = dyn_cast_if_present<FunctionTemplateDecl>(
950fca6ea1SDimitry Andric LambdaCallOperator->getDescribedTemplate());
960fca6ea1SDimitry Andric FTD && FTD->getInstantiatedFromMemberTemplate()) {
970fca6ea1SDimitry Andric LambdaCallOperator =
980fca6ea1SDimitry Andric FTD->getInstantiatedFromMemberTemplate()->getTemplatedDecl();
996c4b055cSDimitry Andric } else if (LambdaCallOperator->getPrimaryTemplate()) {
1006c4b055cSDimitry Andric // Cases where the lambda operator is instantiated in
1016c4b055cSDimitry Andric // TemplateDeclInstantiator::VisitCXXMethodDecl.
1026c4b055cSDimitry Andric LambdaCallOperator =
1036c4b055cSDimitry Andric LambdaCallOperator->getPrimaryTemplate()->getTemplatedDecl();
1040fca6ea1SDimitry Andric } else if (auto *Prev = cast<CXXMethodDecl>(LambdaCallOperator)
1050fca6ea1SDimitry Andric ->getInstantiatedFromMemberFunction())
1060fca6ea1SDimitry Andric LambdaCallOperator = Prev;
1070fca6ea1SDimitry Andric else
1080fca6ea1SDimitry Andric break;
1090fca6ea1SDimitry Andric }
1100fca6ea1SDimitry Andric return LambdaCallOperator;
1110fca6ea1SDimitry Andric }
1120fca6ea1SDimitry Andric
1130fca6ea1SDimitry Andric struct EnclosingTypeAliasTemplateDetails {
1140fca6ea1SDimitry Andric TypeAliasTemplateDecl *Template = nullptr;
1150fca6ea1SDimitry Andric TypeAliasTemplateDecl *PrimaryTypeAliasDecl = nullptr;
1160fca6ea1SDimitry Andric ArrayRef<TemplateArgument> AssociatedTemplateArguments;
1170fca6ea1SDimitry Andric
operator bool__anondb690eb50111::TemplateInstArgsHelpers::EnclosingTypeAliasTemplateDetails1180fca6ea1SDimitry Andric explicit operator bool() noexcept { return Template; }
1190fca6ea1SDimitry Andric };
1200fca6ea1SDimitry Andric
1210fca6ea1SDimitry Andric // Find the enclosing type alias template Decl from CodeSynthesisContexts, as
1220fca6ea1SDimitry Andric // well as its primary template and instantiating template arguments.
1230fca6ea1SDimitry Andric EnclosingTypeAliasTemplateDetails
getEnclosingTypeAliasTemplateDecl(Sema & SemaRef)1240fca6ea1SDimitry Andric getEnclosingTypeAliasTemplateDecl(Sema &SemaRef) {
1250fca6ea1SDimitry Andric for (auto &CSC : llvm::reverse(SemaRef.CodeSynthesisContexts)) {
1260fca6ea1SDimitry Andric if (CSC.Kind != Sema::CodeSynthesisContext::SynthesisKind::
1270fca6ea1SDimitry Andric TypeAliasTemplateInstantiation)
1280fca6ea1SDimitry Andric continue;
1290fca6ea1SDimitry Andric EnclosingTypeAliasTemplateDetails Result;
1300fca6ea1SDimitry Andric auto *TATD = cast<TypeAliasTemplateDecl>(CSC.Entity),
1310fca6ea1SDimitry Andric *Next = TATD->getInstantiatedFromMemberTemplate();
1320fca6ea1SDimitry Andric Result = {
1330fca6ea1SDimitry Andric /*Template=*/TATD,
1340fca6ea1SDimitry Andric /*PrimaryTypeAliasDecl=*/TATD,
1350fca6ea1SDimitry Andric /*AssociatedTemplateArguments=*/CSC.template_arguments(),
1360fca6ea1SDimitry Andric };
1370fca6ea1SDimitry Andric while (Next) {
1380fca6ea1SDimitry Andric Result.PrimaryTypeAliasDecl = Next;
1390fca6ea1SDimitry Andric Next = Next->getInstantiatedFromMemberTemplate();
1400fca6ea1SDimitry Andric }
1410fca6ea1SDimitry Andric return Result;
1420fca6ea1SDimitry Andric }
1430fca6ea1SDimitry Andric return {};
1440fca6ea1SDimitry Andric }
1450fca6ea1SDimitry Andric
1460fca6ea1SDimitry Andric // Check if we are currently inside of a lambda expression that is
1470fca6ea1SDimitry Andric // surrounded by a using alias declaration. e.g.
1480fca6ea1SDimitry Andric // template <class> using type = decltype([](auto) { ^ }());
1490fca6ea1SDimitry Andric // We have to do so since a TypeAliasTemplateDecl (or a TypeAliasDecl) is never
1500fca6ea1SDimitry Andric // a DeclContext, nor does it have an associated specialization Decl from which
1510fca6ea1SDimitry Andric // we could collect these template arguments.
isLambdaEnclosedByTypeAliasDecl(const FunctionDecl * LambdaCallOperator,const TypeAliasTemplateDecl * PrimaryTypeAliasDecl)1520fca6ea1SDimitry Andric bool isLambdaEnclosedByTypeAliasDecl(
1536c4b055cSDimitry Andric const FunctionDecl *LambdaCallOperator,
1540fca6ea1SDimitry Andric const TypeAliasTemplateDecl *PrimaryTypeAliasDecl) {
1556c4b055cSDimitry Andric struct Visitor : RecursiveASTVisitor<Visitor> {
1566c4b055cSDimitry Andric Visitor(const FunctionDecl *CallOperator) : CallOperator(CallOperator) {}
1576c4b055cSDimitry Andric bool VisitLambdaExpr(const LambdaExpr *LE) {
1586c4b055cSDimitry Andric // Return true to bail out of the traversal, implying the Decl contains
1596c4b055cSDimitry Andric // the lambda.
1606c4b055cSDimitry Andric return getPrimaryTemplateOfGenericLambda(LE->getCallOperator()) !=
1616c4b055cSDimitry Andric CallOperator;
1626c4b055cSDimitry Andric }
1636c4b055cSDimitry Andric const FunctionDecl *CallOperator;
1646c4b055cSDimitry Andric };
1656c4b055cSDimitry Andric
1666c4b055cSDimitry Andric QualType Underlying =
1676c4b055cSDimitry Andric PrimaryTypeAliasDecl->getTemplatedDecl()->getUnderlyingType();
1686c4b055cSDimitry Andric
1696c4b055cSDimitry Andric return !Visitor(getPrimaryTemplateOfGenericLambda(LambdaCallOperator))
1706c4b055cSDimitry Andric .TraverseType(Underlying);
1710fca6ea1SDimitry Andric }
1720fca6ea1SDimitry Andric
173bdd1243dSDimitry Andric // Add template arguments from a variable template instantiation.
174bdd1243dSDimitry Andric Response
HandleVarTemplateSpec(const VarTemplateSpecializationDecl * VarTemplSpec,MultiLevelTemplateArgumentList & Result,bool SkipForSpecialization)175bdd1243dSDimitry Andric HandleVarTemplateSpec(const VarTemplateSpecializationDecl *VarTemplSpec,
176bdd1243dSDimitry Andric MultiLevelTemplateArgumentList &Result,
177bdd1243dSDimitry Andric bool SkipForSpecialization) {
178bdd1243dSDimitry Andric // For a class-scope explicit specialization, there are no template arguments
1790b57cec5SDimitry Andric // at this level, but there may be enclosing template arguments.
180bdd1243dSDimitry Andric if (VarTemplSpec->isClassScopeExplicitSpecialization())
181bdd1243dSDimitry Andric return Response::DontClearRelativeToPrimaryNextDecl(VarTemplSpec);
1820b57cec5SDimitry Andric
183bdd1243dSDimitry Andric // We're done when we hit an explicit specialization.
184bdd1243dSDimitry Andric if (VarTemplSpec->getSpecializationKind() == TSK_ExplicitSpecialization &&
185bdd1243dSDimitry Andric !isa<VarTemplatePartialSpecializationDecl>(VarTemplSpec))
186bdd1243dSDimitry Andric return Response::Done();
1870b57cec5SDimitry Andric
1880b57cec5SDimitry Andric // If this variable template specialization was instantiated from a
1890b57cec5SDimitry Andric // specialized member that is a variable template, we're done.
190bdd1243dSDimitry Andric assert(VarTemplSpec->getSpecializedTemplate() && "No variable template?");
191bdd1243dSDimitry Andric llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
192bdd1243dSDimitry Andric Specialized = VarTemplSpec->getSpecializedTemplateOrPartial();
1930b57cec5SDimitry Andric if (VarTemplatePartialSpecializationDecl *Partial =
1940b57cec5SDimitry Andric Specialized.dyn_cast<VarTemplatePartialSpecializationDecl *>()) {
195bdd1243dSDimitry Andric if (!SkipForSpecialization)
196bdd1243dSDimitry Andric Result.addOuterTemplateArguments(
197bdd1243dSDimitry Andric Partial, VarTemplSpec->getTemplateInstantiationArgs().asArray(),
198bdd1243dSDimitry Andric /*Final=*/false);
1990b57cec5SDimitry Andric if (Partial->isMemberSpecialization())
200bdd1243dSDimitry Andric return Response::Done();
2010b57cec5SDimitry Andric } else {
2020b57cec5SDimitry Andric VarTemplateDecl *Tmpl = Specialized.get<VarTemplateDecl *>();
203bdd1243dSDimitry Andric if (!SkipForSpecialization)
204bdd1243dSDimitry Andric Result.addOuterTemplateArguments(
205bdd1243dSDimitry Andric Tmpl, VarTemplSpec->getTemplateInstantiationArgs().asArray(),
206bdd1243dSDimitry Andric /*Final=*/false);
2070b57cec5SDimitry Andric if (Tmpl->isMemberSpecialization())
208bdd1243dSDimitry Andric return Response::Done();
2090b57cec5SDimitry Andric }
210bdd1243dSDimitry Andric return Response::DontClearRelativeToPrimaryNextDecl(VarTemplSpec);
2110b57cec5SDimitry Andric }
2120b57cec5SDimitry Andric
2130b57cec5SDimitry Andric // If we have a template template parameter with translation unit context,
2140b57cec5SDimitry Andric // then we're performing substitution into a default template argument of
2150b57cec5SDimitry Andric // this template template parameter before we've constructed the template
2160b57cec5SDimitry Andric // that will own this template template parameter. In this case, we
2170b57cec5SDimitry Andric // use empty template parameter lists for all of the outer templates
2180b57cec5SDimitry Andric // to avoid performing any substitutions.
219bdd1243dSDimitry Andric Response
HandleDefaultTempArgIntoTempTempParam(const TemplateTemplateParmDecl * TTP,MultiLevelTemplateArgumentList & Result)220bdd1243dSDimitry Andric HandleDefaultTempArgIntoTempTempParam(const TemplateTemplateParmDecl *TTP,
221bdd1243dSDimitry Andric MultiLevelTemplateArgumentList &Result) {
2220b57cec5SDimitry Andric for (unsigned I = 0, N = TTP->getDepth() + 1; I != N; ++I)
223bdd1243dSDimitry Andric Result.addOuterTemplateArguments(std::nullopt);
224bdd1243dSDimitry Andric return Response::Done();
2250b57cec5SDimitry Andric }
2260b57cec5SDimitry Andric
HandlePartialClassTemplateSpec(const ClassTemplatePartialSpecializationDecl * PartialClassTemplSpec,MultiLevelTemplateArgumentList & Result,bool SkipForSpecialization)22706c3fb27SDimitry Andric Response HandlePartialClassTemplateSpec(
22806c3fb27SDimitry Andric const ClassTemplatePartialSpecializationDecl *PartialClassTemplSpec,
22906c3fb27SDimitry Andric MultiLevelTemplateArgumentList &Result, bool SkipForSpecialization) {
23006c3fb27SDimitry Andric if (!SkipForSpecialization)
23106c3fb27SDimitry Andric Result.addOuterRetainedLevels(PartialClassTemplSpec->getTemplateDepth());
23206c3fb27SDimitry Andric return Response::Done();
23306c3fb27SDimitry Andric }
23406c3fb27SDimitry Andric
2350b57cec5SDimitry Andric // Add template arguments from a class template instantiation.
236bdd1243dSDimitry Andric Response
HandleClassTemplateSpec(const ClassTemplateSpecializationDecl * ClassTemplSpec,MultiLevelTemplateArgumentList & Result,bool SkipForSpecialization)237bdd1243dSDimitry Andric HandleClassTemplateSpec(const ClassTemplateSpecializationDecl *ClassTemplSpec,
238bdd1243dSDimitry Andric MultiLevelTemplateArgumentList &Result,
239bdd1243dSDimitry Andric bool SkipForSpecialization) {
240bdd1243dSDimitry Andric if (!ClassTemplSpec->isClassScopeExplicitSpecialization()) {
2410b57cec5SDimitry Andric // We're done when we hit an explicit specialization.
242bdd1243dSDimitry Andric if (ClassTemplSpec->getSpecializationKind() == TSK_ExplicitSpecialization &&
243bdd1243dSDimitry Andric !isa<ClassTemplatePartialSpecializationDecl>(ClassTemplSpec))
244bdd1243dSDimitry Andric return Response::Done();
2450b57cec5SDimitry Andric
246bdd1243dSDimitry Andric if (!SkipForSpecialization)
247bdd1243dSDimitry Andric Result.addOuterTemplateArguments(
248bdd1243dSDimitry Andric const_cast<ClassTemplateSpecializationDecl *>(ClassTemplSpec),
249bdd1243dSDimitry Andric ClassTemplSpec->getTemplateInstantiationArgs().asArray(),
250bdd1243dSDimitry Andric /*Final=*/false);
2510b57cec5SDimitry Andric
2520b57cec5SDimitry Andric // If this class template specialization was instantiated from a
2530b57cec5SDimitry Andric // specialized member that is a class template, we're done.
254bdd1243dSDimitry Andric assert(ClassTemplSpec->getSpecializedTemplate() && "No class template?");
255bdd1243dSDimitry Andric if (ClassTemplSpec->getSpecializedTemplate()->isMemberSpecialization())
256bdd1243dSDimitry Andric return Response::Done();
25706c3fb27SDimitry Andric
25806c3fb27SDimitry Andric // If this was instantiated from a partial template specialization, we need
25906c3fb27SDimitry Andric // to get the next level of declaration context from the partial
26006c3fb27SDimitry Andric // specialization, as the ClassTemplateSpecializationDecl's
26106c3fb27SDimitry Andric // DeclContext/LexicalDeclContext will be for the primary template.
26206c3fb27SDimitry Andric if (auto *InstFromPartialTempl = ClassTemplSpec->getSpecializedTemplateOrPartial()
26306c3fb27SDimitry Andric .dyn_cast<ClassTemplatePartialSpecializationDecl *>())
26406c3fb27SDimitry Andric return Response::ChangeDecl(InstFromPartialTempl->getLexicalDeclContext());
2650b57cec5SDimitry Andric }
266bdd1243dSDimitry Andric return Response::UseNextDecl(ClassTemplSpec);
267bdd1243dSDimitry Andric }
268bdd1243dSDimitry Andric
HandleFunction(Sema & SemaRef,const FunctionDecl * Function,MultiLevelTemplateArgumentList & Result,const FunctionDecl * Pattern,bool RelativeToPrimary,bool ForConstraintInstantiation,bool ForDefaultArgumentSubstitution)2690fca6ea1SDimitry Andric Response HandleFunction(Sema &SemaRef, const FunctionDecl *Function,
270bdd1243dSDimitry Andric MultiLevelTemplateArgumentList &Result,
271bdd1243dSDimitry Andric const FunctionDecl *Pattern, bool RelativeToPrimary,
272*ffc5ee0fSDimitry Andric bool ForConstraintInstantiation,
273*ffc5ee0fSDimitry Andric bool ForDefaultArgumentSubstitution) {
2740b57cec5SDimitry Andric // Add template arguments from a function template specialization.
2750b57cec5SDimitry Andric if (!RelativeToPrimary &&
2760b57cec5SDimitry Andric Function->getTemplateSpecializationKindForInstantiation() ==
2770b57cec5SDimitry Andric TSK_ExplicitSpecialization)
278bdd1243dSDimitry Andric return Response::Done();
2790b57cec5SDimitry Andric
280bdd1243dSDimitry Andric if (!RelativeToPrimary &&
281bdd1243dSDimitry Andric Function->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) {
282e8d8bef9SDimitry Andric // This is an implicit instantiation of an explicit specialization. We
283e8d8bef9SDimitry Andric // don't get any template arguments from this function but might get
284e8d8bef9SDimitry Andric // some from an enclosing template.
285bdd1243dSDimitry Andric return Response::UseNextDecl(Function);
286bdd1243dSDimitry Andric } else if (const TemplateArgumentList *TemplateArgs =
287bdd1243dSDimitry Andric Function->getTemplateSpecializationArgs()) {
2880b57cec5SDimitry Andric // Add the template arguments for this specialization.
289bdd1243dSDimitry Andric Result.addOuterTemplateArguments(const_cast<FunctionDecl *>(Function),
290bdd1243dSDimitry Andric TemplateArgs->asArray(),
291bdd1243dSDimitry Andric /*Final=*/false);
2920b57cec5SDimitry Andric
2930fca6ea1SDimitry Andric if (RelativeToPrimary &&
2940fca6ea1SDimitry Andric (Function->getTemplateSpecializationKind() ==
2950fca6ea1SDimitry Andric TSK_ExplicitSpecialization ||
2960fca6ea1SDimitry Andric (Function->getFriendObjectKind() &&
2970fca6ea1SDimitry Andric !Function->getPrimaryTemplate()->getFriendObjectKind())))
2980fca6ea1SDimitry Andric return Response::UseNextDecl(Function);
2990fca6ea1SDimitry Andric
3000b57cec5SDimitry Andric // If this function was instantiated from a specialized member that is
3010b57cec5SDimitry Andric // a function template, we're done.
3020b57cec5SDimitry Andric assert(Function->getPrimaryTemplate() && "No function template?");
303*ffc5ee0fSDimitry Andric if (!ForDefaultArgumentSubstitution &&
304*ffc5ee0fSDimitry Andric Function->getPrimaryTemplate()->isMemberSpecialization())
305bdd1243dSDimitry Andric return Response::Done();
3060b57cec5SDimitry Andric
3070b57cec5SDimitry Andric // If this function is a generic lambda specialization, we are done.
308bdd1243dSDimitry Andric if (!ForConstraintInstantiation &&
3096c4b055cSDimitry Andric isGenericLambdaCallOperatorOrStaticInvokerSpecialization(Function))
310bdd1243dSDimitry Andric return Response::Done();
3110b57cec5SDimitry Andric
312349cc55cSDimitry Andric } else if (Function->getDescribedFunctionTemplate()) {
313bdd1243dSDimitry Andric assert(
314bdd1243dSDimitry Andric (ForConstraintInstantiation || Result.getNumSubstitutedLevels() == 0) &&
315349cc55cSDimitry Andric "Outer template not instantiated?");
3160b57cec5SDimitry Andric }
317bdd1243dSDimitry Andric // If this is a friend or local declaration and it declares an entity at
3180b57cec5SDimitry Andric // namespace scope, take arguments from its lexical parent
3190b57cec5SDimitry Andric // instead of its semantic parent, unless of course the pattern we're
3200b57cec5SDimitry Andric // instantiating actually comes from the file's context!
321bdd1243dSDimitry Andric if ((Function->getFriendObjectKind() || Function->isLocalExternDecl()) &&
322bdd1243dSDimitry Andric Function->getNonTransparentDeclContext()->isFileContext() &&
3230b57cec5SDimitry Andric (!Pattern || !Pattern->getLexicalDeclContext()->isFileContext())) {
324bdd1243dSDimitry Andric return Response::ChangeDecl(Function->getLexicalDeclContext());
3250b57cec5SDimitry Andric }
3267a6dacacSDimitry Andric
3277a6dacacSDimitry Andric if (ForConstraintInstantiation && Function->getFriendObjectKind())
3287a6dacacSDimitry Andric return Response::ChangeDecl(Function->getLexicalDeclContext());
329bdd1243dSDimitry Andric return Response::UseNextDecl(Function);
330bdd1243dSDimitry Andric }
331bdd1243dSDimitry Andric
HandleFunctionTemplateDecl(const FunctionTemplateDecl * FTD,MultiLevelTemplateArgumentList & Result)33206c3fb27SDimitry Andric Response HandleFunctionTemplateDecl(const FunctionTemplateDecl *FTD,
33306c3fb27SDimitry Andric MultiLevelTemplateArgumentList &Result) {
33406c3fb27SDimitry Andric if (!isa<ClassTemplateSpecializationDecl>(FTD->getDeclContext())) {
3355f757f3fSDimitry Andric Result.addOuterTemplateArguments(
3365f757f3fSDimitry Andric const_cast<FunctionTemplateDecl *>(FTD),
3375f757f3fSDimitry Andric const_cast<FunctionTemplateDecl *>(FTD)->getInjectedTemplateArgs(),
3385f757f3fSDimitry Andric /*Final=*/false);
3395f757f3fSDimitry Andric
34006c3fb27SDimitry Andric NestedNameSpecifier *NNS = FTD->getTemplatedDecl()->getQualifier();
3415f757f3fSDimitry Andric
3425f757f3fSDimitry Andric while (const Type *Ty = NNS ? NNS->getAsType() : nullptr) {
3435f757f3fSDimitry Andric if (NNS->isInstantiationDependent()) {
3440fca6ea1SDimitry Andric if (const auto *TSTy = Ty->getAs<TemplateSpecializationType>()) {
3450fca6ea1SDimitry Andric ArrayRef<TemplateArgument> Arguments = TSTy->template_arguments();
3460fca6ea1SDimitry Andric // Prefer template arguments from the injected-class-type if possible.
3470fca6ea1SDimitry Andric // For example,
3480fca6ea1SDimitry Andric // ```cpp
3490fca6ea1SDimitry Andric // template <class... Pack> struct S {
3500fca6ea1SDimitry Andric // template <class T> void foo();
3510fca6ea1SDimitry Andric // };
3520fca6ea1SDimitry Andric // template <class... Pack> template <class T>
3530fca6ea1SDimitry Andric // ^^^^^^^^^^^^^ InjectedTemplateArgs
3540fca6ea1SDimitry Andric // They're of kind TemplateArgument::Pack, not of
3550fca6ea1SDimitry Andric // TemplateArgument::Type.
3560fca6ea1SDimitry Andric // void S<Pack...>::foo() {}
3570fca6ea1SDimitry Andric // ^^^^^^^
3580fca6ea1SDimitry Andric // TSTy->template_arguments() (which are of PackExpansionType)
3590fca6ea1SDimitry Andric // ```
3600fca6ea1SDimitry Andric // This meets the contract in
3610fca6ea1SDimitry Andric // TreeTransform::TryExpandParameterPacks that the template arguments
3620fca6ea1SDimitry Andric // for unexpanded parameters should be of a Pack kind.
3630fca6ea1SDimitry Andric if (TSTy->isCurrentInstantiation()) {
3640fca6ea1SDimitry Andric auto *RD = TSTy->getCanonicalTypeInternal()->getAsCXXRecordDecl();
3650fca6ea1SDimitry Andric if (ClassTemplateDecl *CTD = RD->getDescribedClassTemplate())
3660fca6ea1SDimitry Andric Arguments = CTD->getInjectedTemplateArgs();
3670fca6ea1SDimitry Andric else if (auto *Specialization =
3680fca6ea1SDimitry Andric dyn_cast<ClassTemplateSpecializationDecl>(RD))
3690fca6ea1SDimitry Andric Arguments =
3700fca6ea1SDimitry Andric Specialization->getTemplateInstantiationArgs().asArray();
3710fca6ea1SDimitry Andric }
3725f757f3fSDimitry Andric Result.addOuterTemplateArguments(
3730fca6ea1SDimitry Andric const_cast<FunctionTemplateDecl *>(FTD), Arguments,
37406c3fb27SDimitry Andric /*Final=*/false);
37506c3fb27SDimitry Andric }
3760fca6ea1SDimitry Andric }
3775f757f3fSDimitry Andric
3785f757f3fSDimitry Andric NNS = NNS->getPrefix();
3795f757f3fSDimitry Andric }
3805f757f3fSDimitry Andric }
3815f757f3fSDimitry Andric
38206c3fb27SDimitry Andric return Response::ChangeDecl(FTD->getLexicalDeclContext());
38306c3fb27SDimitry Andric }
38406c3fb27SDimitry Andric
HandleRecordDecl(Sema & SemaRef,const CXXRecordDecl * Rec,MultiLevelTemplateArgumentList & Result,ASTContext & Context,bool ForConstraintInstantiation)3850fca6ea1SDimitry Andric Response HandleRecordDecl(Sema &SemaRef, const CXXRecordDecl *Rec,
386bdd1243dSDimitry Andric MultiLevelTemplateArgumentList &Result,
387bdd1243dSDimitry Andric ASTContext &Context,
388bdd1243dSDimitry Andric bool ForConstraintInstantiation) {
3890b57cec5SDimitry Andric if (ClassTemplateDecl *ClassTemplate = Rec->getDescribedClassTemplate()) {
390bdd1243dSDimitry Andric assert(
391bdd1243dSDimitry Andric (ForConstraintInstantiation || Result.getNumSubstitutedLevels() == 0) &&
392349cc55cSDimitry Andric "Outer template not instantiated?");
3930b57cec5SDimitry Andric if (ClassTemplate->isMemberSpecialization())
394bdd1243dSDimitry Andric return Response::Done();
39506c3fb27SDimitry Andric if (ForConstraintInstantiation)
396bdd1243dSDimitry Andric Result.addOuterTemplateArguments(const_cast<CXXRecordDecl *>(Rec),
39706c3fb27SDimitry Andric ClassTemplate->getInjectedTemplateArgs(),
398bdd1243dSDimitry Andric /*Final=*/false);
3990b57cec5SDimitry Andric }
40006c3fb27SDimitry Andric
40106c3fb27SDimitry Andric if (const MemberSpecializationInfo *MSInfo =
40206c3fb27SDimitry Andric Rec->getMemberSpecializationInfo())
40306c3fb27SDimitry Andric if (MSInfo->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
40406c3fb27SDimitry Andric return Response::Done();
4050b57cec5SDimitry Andric
406bdd1243dSDimitry Andric bool IsFriend = Rec->getFriendObjectKind() ||
407bdd1243dSDimitry Andric (Rec->getDescribedClassTemplate() &&
408bdd1243dSDimitry Andric Rec->getDescribedClassTemplate()->getFriendObjectKind());
409bdd1243dSDimitry Andric if (ForConstraintInstantiation && IsFriend &&
410bdd1243dSDimitry Andric Rec->getNonTransparentDeclContext()->isFileContext()) {
411bdd1243dSDimitry Andric return Response::ChangeDecl(Rec->getLexicalDeclContext());
412bdd1243dSDimitry Andric }
413bdd1243dSDimitry Andric
4140fca6ea1SDimitry Andric // This is to make sure we pick up the VarTemplateSpecializationDecl or the
4150fca6ea1SDimitry Andric // TypeAliasTemplateDecl that this lambda is defined inside of.
4160fca6ea1SDimitry Andric if (Rec->isLambda()) {
417bdd1243dSDimitry Andric if (const Decl *LCD = Rec->getLambdaContextDecl())
418bdd1243dSDimitry Andric return Response::ChangeDecl(LCD);
4190fca6ea1SDimitry Andric // Retrieve the template arguments for a using alias declaration.
4200fca6ea1SDimitry Andric // This is necessary for constraint checking, since we always keep
4210fca6ea1SDimitry Andric // constraints relative to the primary template.
4226c4b055cSDimitry Andric if (auto TypeAlias = getEnclosingTypeAliasTemplateDecl(SemaRef);
4236c4b055cSDimitry Andric ForConstraintInstantiation && TypeAlias) {
4246c4b055cSDimitry Andric if (isLambdaEnclosedByTypeAliasDecl(Rec->getLambdaCallOperator(),
4250fca6ea1SDimitry Andric TypeAlias.PrimaryTypeAliasDecl)) {
4260fca6ea1SDimitry Andric Result.addOuterTemplateArguments(TypeAlias.Template,
4270fca6ea1SDimitry Andric TypeAlias.AssociatedTemplateArguments,
4280fca6ea1SDimitry Andric /*Final=*/false);
4290fca6ea1SDimitry Andric // Visit the parent of the current type alias declaration rather than
4300fca6ea1SDimitry Andric // the lambda thereof.
4310fca6ea1SDimitry Andric // E.g., in the following example:
4320fca6ea1SDimitry Andric // struct S {
4330fca6ea1SDimitry Andric // template <class> using T = decltype([]<Concept> {} ());
4340fca6ea1SDimitry Andric // };
4350fca6ea1SDimitry Andric // void foo() {
4360fca6ea1SDimitry Andric // S::T var;
4370fca6ea1SDimitry Andric // }
4380fca6ea1SDimitry Andric // The instantiated lambda expression (which we're visiting at 'var')
4390fca6ea1SDimitry Andric // has a function DeclContext 'foo' rather than the Record DeclContext
4400fca6ea1SDimitry Andric // S. This seems to be an oversight to me that we may want to set a
4410fca6ea1SDimitry Andric // Sema Context from the CXXScopeSpec before substituting into T.
4420fca6ea1SDimitry Andric return Response::ChangeDecl(TypeAlias.Template->getDeclContext());
4430fca6ea1SDimitry Andric }
4440fca6ea1SDimitry Andric }
4450fca6ea1SDimitry Andric }
446bdd1243dSDimitry Andric
447bdd1243dSDimitry Andric return Response::UseNextDecl(Rec);
448bdd1243dSDimitry Andric }
449bdd1243dSDimitry Andric
HandleImplicitConceptSpecializationDecl(const ImplicitConceptSpecializationDecl * CSD,MultiLevelTemplateArgumentList & Result)450bdd1243dSDimitry Andric Response HandleImplicitConceptSpecializationDecl(
451bdd1243dSDimitry Andric const ImplicitConceptSpecializationDecl *CSD,
452bdd1243dSDimitry Andric MultiLevelTemplateArgumentList &Result) {
453bdd1243dSDimitry Andric Result.addOuterTemplateArguments(
454bdd1243dSDimitry Andric const_cast<ImplicitConceptSpecializationDecl *>(CSD),
455bdd1243dSDimitry Andric CSD->getTemplateArguments(),
456bdd1243dSDimitry Andric /*Final=*/false);
457bdd1243dSDimitry Andric return Response::UseNextDecl(CSD);
458bdd1243dSDimitry Andric }
459bdd1243dSDimitry Andric
HandleGenericDeclContext(const Decl * CurDecl)460bdd1243dSDimitry Andric Response HandleGenericDeclContext(const Decl *CurDecl) {
461bdd1243dSDimitry Andric return Response::UseNextDecl(CurDecl);
462bdd1243dSDimitry Andric }
463bdd1243dSDimitry Andric } // namespace TemplateInstArgsHelpers
464bdd1243dSDimitry Andric } // namespace
465bdd1243dSDimitry Andric
getTemplateInstantiationArgs(const NamedDecl * ND,const DeclContext * DC,bool Final,std::optional<ArrayRef<TemplateArgument>> Innermost,bool RelativeToPrimary,const FunctionDecl * Pattern,bool ForConstraintInstantiation,bool SkipForSpecialization,bool ForDefaultArgumentSubstitution)466bdd1243dSDimitry Andric MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs(
4675f757f3fSDimitry Andric const NamedDecl *ND, const DeclContext *DC, bool Final,
4680fca6ea1SDimitry Andric std::optional<ArrayRef<TemplateArgument>> Innermost, bool RelativeToPrimary,
4695f757f3fSDimitry Andric const FunctionDecl *Pattern, bool ForConstraintInstantiation,
470*ffc5ee0fSDimitry Andric bool SkipForSpecialization, bool ForDefaultArgumentSubstitution) {
4715f757f3fSDimitry Andric assert((ND || DC) && "Can't find arguments for a decl if one isn't provided");
472bdd1243dSDimitry Andric // Accumulate the set of template argument lists in this structure.
473bdd1243dSDimitry Andric MultiLevelTemplateArgumentList Result;
474bdd1243dSDimitry Andric
47506c3fb27SDimitry Andric using namespace TemplateInstArgsHelpers;
47606c3fb27SDimitry Andric const Decl *CurDecl = ND;
4771db9f3b2SDimitry Andric
4781db9f3b2SDimitry Andric if (!CurDecl)
4791db9f3b2SDimitry Andric CurDecl = Decl::castFromDeclContext(DC);
4801db9f3b2SDimitry Andric
48106c3fb27SDimitry Andric if (Innermost) {
4820fca6ea1SDimitry Andric Result.addOuterTemplateArguments(const_cast<NamedDecl *>(ND), *Innermost,
4830fca6ea1SDimitry Andric Final);
4841db9f3b2SDimitry Andric // Populate placeholder template arguments for TemplateTemplateParmDecls.
4851db9f3b2SDimitry Andric // This is essential for the case e.g.
4861db9f3b2SDimitry Andric //
4871db9f3b2SDimitry Andric // template <class> concept Concept = false;
4881db9f3b2SDimitry Andric // template <template <Concept C> class T> void foo(T<int>)
4891db9f3b2SDimitry Andric //
4901db9f3b2SDimitry Andric // where parameter C has a depth of 1 but the substituting argument `int`
4911db9f3b2SDimitry Andric // has a depth of 0.
4921db9f3b2SDimitry Andric if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(CurDecl))
4931db9f3b2SDimitry Andric HandleDefaultTempArgIntoTempTempParam(TTP, Result);
4941db9f3b2SDimitry Andric CurDecl = Response::UseNextDecl(CurDecl).NextDecl;
49506c3fb27SDimitry Andric }
496bdd1243dSDimitry Andric
497bdd1243dSDimitry Andric while (!CurDecl->isFileContextDecl()) {
498bdd1243dSDimitry Andric Response R;
499bdd1243dSDimitry Andric if (const auto *VarTemplSpec =
500bdd1243dSDimitry Andric dyn_cast<VarTemplateSpecializationDecl>(CurDecl)) {
501bdd1243dSDimitry Andric R = HandleVarTemplateSpec(VarTemplSpec, Result, SkipForSpecialization);
50206c3fb27SDimitry Andric } else if (const auto *PartialClassTemplSpec =
50306c3fb27SDimitry Andric dyn_cast<ClassTemplatePartialSpecializationDecl>(CurDecl)) {
50406c3fb27SDimitry Andric R = HandlePartialClassTemplateSpec(PartialClassTemplSpec, Result,
50506c3fb27SDimitry Andric SkipForSpecialization);
506bdd1243dSDimitry Andric } else if (const auto *ClassTemplSpec =
507bdd1243dSDimitry Andric dyn_cast<ClassTemplateSpecializationDecl>(CurDecl)) {
508bdd1243dSDimitry Andric R = HandleClassTemplateSpec(ClassTemplSpec, Result,
509bdd1243dSDimitry Andric SkipForSpecialization);
510bdd1243dSDimitry Andric } else if (const auto *Function = dyn_cast<FunctionDecl>(CurDecl)) {
5110fca6ea1SDimitry Andric R = HandleFunction(*this, Function, Result, Pattern, RelativeToPrimary,
512*ffc5ee0fSDimitry Andric ForConstraintInstantiation,
513*ffc5ee0fSDimitry Andric ForDefaultArgumentSubstitution);
514bdd1243dSDimitry Andric } else if (const auto *Rec = dyn_cast<CXXRecordDecl>(CurDecl)) {
5150fca6ea1SDimitry Andric R = HandleRecordDecl(*this, Rec, Result, Context,
5160fca6ea1SDimitry Andric ForConstraintInstantiation);
517bdd1243dSDimitry Andric } else if (const auto *CSD =
518bdd1243dSDimitry Andric dyn_cast<ImplicitConceptSpecializationDecl>(CurDecl)) {
519bdd1243dSDimitry Andric R = HandleImplicitConceptSpecializationDecl(CSD, Result);
52006c3fb27SDimitry Andric } else if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(CurDecl)) {
52106c3fb27SDimitry Andric R = HandleFunctionTemplateDecl(FTD, Result);
5225f757f3fSDimitry Andric } else if (const auto *CTD = dyn_cast<ClassTemplateDecl>(CurDecl)) {
5235f757f3fSDimitry Andric R = Response::ChangeDecl(CTD->getLexicalDeclContext());
524bdd1243dSDimitry Andric } else if (!isa<DeclContext>(CurDecl)) {
525bdd1243dSDimitry Andric R = Response::DontClearRelativeToPrimaryNextDecl(CurDecl);
526bdd1243dSDimitry Andric if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(CurDecl)) {
527bdd1243dSDimitry Andric R = HandleDefaultTempArgIntoTempTempParam(TTP, Result);
528bdd1243dSDimitry Andric }
529bdd1243dSDimitry Andric } else {
530bdd1243dSDimitry Andric R = HandleGenericDeclContext(CurDecl);
531bdd1243dSDimitry Andric }
532bdd1243dSDimitry Andric
533bdd1243dSDimitry Andric if (R.IsDone)
534bdd1243dSDimitry Andric return Result;
535bdd1243dSDimitry Andric if (R.ClearRelativeToPrimary)
5360b57cec5SDimitry Andric RelativeToPrimary = false;
537bdd1243dSDimitry Andric assert(R.NextDecl);
538bdd1243dSDimitry Andric CurDecl = R.NextDecl;
5390b57cec5SDimitry Andric }
5400b57cec5SDimitry Andric
5410b57cec5SDimitry Andric return Result;
5420b57cec5SDimitry Andric }
5430b57cec5SDimitry Andric
isInstantiationRecord() const5440b57cec5SDimitry Andric bool Sema::CodeSynthesisContext::isInstantiationRecord() const {
5450b57cec5SDimitry Andric switch (Kind) {
5460b57cec5SDimitry Andric case TemplateInstantiation:
5470b57cec5SDimitry Andric case ExceptionSpecInstantiation:
5480b57cec5SDimitry Andric case DefaultTemplateArgumentInstantiation:
5490b57cec5SDimitry Andric case DefaultFunctionArgumentInstantiation:
5500b57cec5SDimitry Andric case ExplicitTemplateArgumentSubstitution:
5510b57cec5SDimitry Andric case DeducedTemplateArgumentSubstitution:
5520b57cec5SDimitry Andric case PriorTemplateArgumentSubstitution:
553a7dea167SDimitry Andric case ConstraintsCheck:
55455e4f9d5SDimitry Andric case NestedRequirementConstraintsCheck:
5550b57cec5SDimitry Andric return true;
5560b57cec5SDimitry Andric
55755e4f9d5SDimitry Andric case RequirementInstantiation:
558bdd1243dSDimitry Andric case RequirementParameterInstantiation:
5590b57cec5SDimitry Andric case DefaultTemplateArgumentChecking:
5600b57cec5SDimitry Andric case DeclaringSpecialMember:
561480093f4SDimitry Andric case DeclaringImplicitEqualityComparison:
5620b57cec5SDimitry Andric case DefiningSynthesizedFunction:
5630b57cec5SDimitry Andric case ExceptionSpecEvaluation:
564a7dea167SDimitry Andric case ConstraintSubstitution:
565480093f4SDimitry Andric case ParameterMappingSubstitution:
566480093f4SDimitry Andric case ConstraintNormalization:
567a7dea167SDimitry Andric case RewritingOperatorAsSpaceship:
5685ffd83dbSDimitry Andric case InitializingStructuredBinding:
5695ffd83dbSDimitry Andric case MarkingClassDllexported:
57081ad6265SDimitry Andric case BuildingBuiltinDumpStructCall:
57106c3fb27SDimitry Andric case LambdaExpressionSubstitution:
57206c3fb27SDimitry Andric case BuildingDeductionGuides:
5730fca6ea1SDimitry Andric case TypeAliasTemplateInstantiation:
5740b57cec5SDimitry Andric return false;
5750b57cec5SDimitry Andric
5760b57cec5SDimitry Andric // This function should never be called when Kind's value is Memoization.
5770b57cec5SDimitry Andric case Memoization:
5780b57cec5SDimitry Andric break;
5790b57cec5SDimitry Andric }
5800b57cec5SDimitry Andric
5810b57cec5SDimitry Andric llvm_unreachable("Invalid SynthesisKind!");
5820b57cec5SDimitry Andric }
5830b57cec5SDimitry Andric
InstantiatingTemplate(Sema & SemaRef,CodeSynthesisContext::SynthesisKind Kind,SourceLocation PointOfInstantiation,SourceRange InstantiationRange,Decl * Entity,NamedDecl * Template,ArrayRef<TemplateArgument> TemplateArgs,sema::TemplateDeductionInfo * DeductionInfo)5840b57cec5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
5850b57cec5SDimitry Andric Sema &SemaRef, CodeSynthesisContext::SynthesisKind Kind,
5860b57cec5SDimitry Andric SourceLocation PointOfInstantiation, SourceRange InstantiationRange,
5870b57cec5SDimitry Andric Decl *Entity, NamedDecl *Template, ArrayRef<TemplateArgument> TemplateArgs,
5880b57cec5SDimitry Andric sema::TemplateDeductionInfo *DeductionInfo)
5890b57cec5SDimitry Andric : SemaRef(SemaRef) {
5900b57cec5SDimitry Andric // Don't allow further instantiation if a fatal error and an uncompilable
5910b57cec5SDimitry Andric // error have occurred. Any diagnostics we might have raised will not be
5920b57cec5SDimitry Andric // visible, and we do not need to construct a correct AST.
5930b57cec5SDimitry Andric if (SemaRef.Diags.hasFatalErrorOccurred() &&
594e8d8bef9SDimitry Andric SemaRef.hasUncompilableErrorOccurred()) {
5950b57cec5SDimitry Andric Invalid = true;
5960b57cec5SDimitry Andric return;
5970b57cec5SDimitry Andric }
5980b57cec5SDimitry Andric Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
5990b57cec5SDimitry Andric if (!Invalid) {
6000b57cec5SDimitry Andric CodeSynthesisContext Inst;
6010b57cec5SDimitry Andric Inst.Kind = Kind;
6020b57cec5SDimitry Andric Inst.PointOfInstantiation = PointOfInstantiation;
6030b57cec5SDimitry Andric Inst.Entity = Entity;
6040b57cec5SDimitry Andric Inst.Template = Template;
6050b57cec5SDimitry Andric Inst.TemplateArgs = TemplateArgs.data();
6060b57cec5SDimitry Andric Inst.NumTemplateArgs = TemplateArgs.size();
6070b57cec5SDimitry Andric Inst.DeductionInfo = DeductionInfo;
6080b57cec5SDimitry Andric Inst.InstantiationRange = InstantiationRange;
6090b57cec5SDimitry Andric SemaRef.pushCodeSynthesisContext(Inst);
6100b57cec5SDimitry Andric
61155e4f9d5SDimitry Andric AlreadyInstantiating = !Inst.Entity ? false :
6120b57cec5SDimitry Andric !SemaRef.InstantiatingSpecializations
613e8d8bef9SDimitry Andric .insert({Inst.Entity->getCanonicalDecl(), Inst.Kind})
6140b57cec5SDimitry Andric .second;
6150b57cec5SDimitry Andric atTemplateBegin(SemaRef.TemplateInstCallbacks, SemaRef, Inst);
6160b57cec5SDimitry Andric }
6170b57cec5SDimitry Andric }
6180b57cec5SDimitry Andric
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,Decl * Entity,SourceRange InstantiationRange)6190b57cec5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
6200b57cec5SDimitry Andric Sema &SemaRef, SourceLocation PointOfInstantiation, Decl *Entity,
6210b57cec5SDimitry Andric SourceRange InstantiationRange)
6220b57cec5SDimitry Andric : InstantiatingTemplate(SemaRef,
6230b57cec5SDimitry Andric CodeSynthesisContext::TemplateInstantiation,
6240b57cec5SDimitry Andric PointOfInstantiation, InstantiationRange, Entity) {}
6250b57cec5SDimitry Andric
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,FunctionDecl * Entity,ExceptionSpecification,SourceRange InstantiationRange)6260b57cec5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
6270b57cec5SDimitry Andric Sema &SemaRef, SourceLocation PointOfInstantiation, FunctionDecl *Entity,
6280b57cec5SDimitry Andric ExceptionSpecification, SourceRange InstantiationRange)
6290b57cec5SDimitry Andric : InstantiatingTemplate(
6300b57cec5SDimitry Andric SemaRef, CodeSynthesisContext::ExceptionSpecInstantiation,
6310b57cec5SDimitry Andric PointOfInstantiation, InstantiationRange, Entity) {}
6320b57cec5SDimitry Andric
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,TemplateParameter Param,TemplateDecl * Template,ArrayRef<TemplateArgument> TemplateArgs,SourceRange InstantiationRange)6330b57cec5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
6340b57cec5SDimitry Andric Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateParameter Param,
6350b57cec5SDimitry Andric TemplateDecl *Template, ArrayRef<TemplateArgument> TemplateArgs,
6360b57cec5SDimitry Andric SourceRange InstantiationRange)
6370b57cec5SDimitry Andric : InstantiatingTemplate(
6380b57cec5SDimitry Andric SemaRef,
6390b57cec5SDimitry Andric CodeSynthesisContext::DefaultTemplateArgumentInstantiation,
6400b57cec5SDimitry Andric PointOfInstantiation, InstantiationRange, getAsNamedDecl(Param),
6410b57cec5SDimitry Andric Template, TemplateArgs) {}
6420b57cec5SDimitry Andric
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,FunctionTemplateDecl * FunctionTemplate,ArrayRef<TemplateArgument> TemplateArgs,CodeSynthesisContext::SynthesisKind Kind,sema::TemplateDeductionInfo & DeductionInfo,SourceRange InstantiationRange)6430b57cec5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
6440b57cec5SDimitry Andric Sema &SemaRef, SourceLocation PointOfInstantiation,
6450b57cec5SDimitry Andric FunctionTemplateDecl *FunctionTemplate,
6460b57cec5SDimitry Andric ArrayRef<TemplateArgument> TemplateArgs,
6470b57cec5SDimitry Andric CodeSynthesisContext::SynthesisKind Kind,
6480b57cec5SDimitry Andric sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
6490b57cec5SDimitry Andric : InstantiatingTemplate(SemaRef, Kind, PointOfInstantiation,
6500b57cec5SDimitry Andric InstantiationRange, FunctionTemplate, nullptr,
6510b57cec5SDimitry Andric TemplateArgs, &DeductionInfo) {
6520fca6ea1SDimitry Andric assert(Kind == CodeSynthesisContext::ExplicitTemplateArgumentSubstitution ||
6530fca6ea1SDimitry Andric Kind == CodeSynthesisContext::DeducedTemplateArgumentSubstitution ||
6540fca6ea1SDimitry Andric Kind == CodeSynthesisContext::BuildingDeductionGuides);
6550b57cec5SDimitry Andric }
6560b57cec5SDimitry Andric
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,TemplateDecl * Template,ArrayRef<TemplateArgument> TemplateArgs,sema::TemplateDeductionInfo & DeductionInfo,SourceRange InstantiationRange)6570b57cec5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
6580b57cec5SDimitry Andric Sema &SemaRef, SourceLocation PointOfInstantiation,
6590b57cec5SDimitry Andric TemplateDecl *Template,
6600b57cec5SDimitry Andric ArrayRef<TemplateArgument> TemplateArgs,
6610b57cec5SDimitry Andric sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
6620b57cec5SDimitry Andric : InstantiatingTemplate(
6630b57cec5SDimitry Andric SemaRef,
6640b57cec5SDimitry Andric CodeSynthesisContext::DeducedTemplateArgumentSubstitution,
6650b57cec5SDimitry Andric PointOfInstantiation, InstantiationRange, Template, nullptr,
6660b57cec5SDimitry Andric TemplateArgs, &DeductionInfo) {}
6670b57cec5SDimitry Andric
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,ClassTemplatePartialSpecializationDecl * PartialSpec,ArrayRef<TemplateArgument> TemplateArgs,sema::TemplateDeductionInfo & DeductionInfo,SourceRange InstantiationRange)6680b57cec5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
6690b57cec5SDimitry Andric Sema &SemaRef, SourceLocation PointOfInstantiation,
6700b57cec5SDimitry Andric ClassTemplatePartialSpecializationDecl *PartialSpec,
6710b57cec5SDimitry Andric ArrayRef<TemplateArgument> TemplateArgs,
6720b57cec5SDimitry Andric sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
6730b57cec5SDimitry Andric : InstantiatingTemplate(
6740b57cec5SDimitry Andric SemaRef,
6750b57cec5SDimitry Andric CodeSynthesisContext::DeducedTemplateArgumentSubstitution,
6760b57cec5SDimitry Andric PointOfInstantiation, InstantiationRange, PartialSpec, nullptr,
6770b57cec5SDimitry Andric TemplateArgs, &DeductionInfo) {}
6780b57cec5SDimitry Andric
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,VarTemplatePartialSpecializationDecl * PartialSpec,ArrayRef<TemplateArgument> TemplateArgs,sema::TemplateDeductionInfo & DeductionInfo,SourceRange InstantiationRange)6790b57cec5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
6800b57cec5SDimitry Andric Sema &SemaRef, SourceLocation PointOfInstantiation,
6810b57cec5SDimitry Andric VarTemplatePartialSpecializationDecl *PartialSpec,
6820b57cec5SDimitry Andric ArrayRef<TemplateArgument> TemplateArgs,
6830b57cec5SDimitry Andric sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
6840b57cec5SDimitry Andric : InstantiatingTemplate(
6850b57cec5SDimitry Andric SemaRef,
6860b57cec5SDimitry Andric CodeSynthesisContext::DeducedTemplateArgumentSubstitution,
6870b57cec5SDimitry Andric PointOfInstantiation, InstantiationRange, PartialSpec, nullptr,
6880b57cec5SDimitry Andric TemplateArgs, &DeductionInfo) {}
6890b57cec5SDimitry Andric
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,ParmVarDecl * Param,ArrayRef<TemplateArgument> TemplateArgs,SourceRange InstantiationRange)6900b57cec5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
6910b57cec5SDimitry Andric Sema &SemaRef, SourceLocation PointOfInstantiation, ParmVarDecl *Param,
6920b57cec5SDimitry Andric ArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange)
6930b57cec5SDimitry Andric : InstantiatingTemplate(
6940b57cec5SDimitry Andric SemaRef,
6950b57cec5SDimitry Andric CodeSynthesisContext::DefaultFunctionArgumentInstantiation,
6960b57cec5SDimitry Andric PointOfInstantiation, InstantiationRange, Param, nullptr,
6970b57cec5SDimitry Andric TemplateArgs) {}
6980b57cec5SDimitry Andric
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,NamedDecl * Template,NonTypeTemplateParmDecl * Param,ArrayRef<TemplateArgument> TemplateArgs,SourceRange InstantiationRange)6990b57cec5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
7000b57cec5SDimitry Andric Sema &SemaRef, SourceLocation PointOfInstantiation, NamedDecl *Template,
7010b57cec5SDimitry Andric NonTypeTemplateParmDecl *Param, ArrayRef<TemplateArgument> TemplateArgs,
7020b57cec5SDimitry Andric SourceRange InstantiationRange)
7030b57cec5SDimitry Andric : InstantiatingTemplate(
7040b57cec5SDimitry Andric SemaRef,
7050b57cec5SDimitry Andric CodeSynthesisContext::PriorTemplateArgumentSubstitution,
7060b57cec5SDimitry Andric PointOfInstantiation, InstantiationRange, Param, Template,
7070b57cec5SDimitry Andric TemplateArgs) {}
7080b57cec5SDimitry Andric
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,NamedDecl * Template,TemplateTemplateParmDecl * Param,ArrayRef<TemplateArgument> TemplateArgs,SourceRange InstantiationRange)7090b57cec5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
7100b57cec5SDimitry Andric Sema &SemaRef, SourceLocation PointOfInstantiation, NamedDecl *Template,
7110b57cec5SDimitry Andric TemplateTemplateParmDecl *Param, ArrayRef<TemplateArgument> TemplateArgs,
7120b57cec5SDimitry Andric SourceRange InstantiationRange)
7130b57cec5SDimitry Andric : InstantiatingTemplate(
7140b57cec5SDimitry Andric SemaRef,
7150b57cec5SDimitry Andric CodeSynthesisContext::PriorTemplateArgumentSubstitution,
7160b57cec5SDimitry Andric PointOfInstantiation, InstantiationRange, Param, Template,
7170b57cec5SDimitry Andric TemplateArgs) {}
7180b57cec5SDimitry Andric
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,TypeAliasTemplateDecl * Entity,ArrayRef<TemplateArgument> TemplateArgs,SourceRange InstantiationRange)7190b57cec5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
7200fca6ea1SDimitry Andric Sema &SemaRef, SourceLocation PointOfInstantiation,
7210fca6ea1SDimitry Andric TypeAliasTemplateDecl *Entity, ArrayRef<TemplateArgument> TemplateArgs,
7220fca6ea1SDimitry Andric SourceRange InstantiationRange)
7230fca6ea1SDimitry Andric : InstantiatingTemplate(
7240fca6ea1SDimitry Andric SemaRef, CodeSynthesisContext::TypeAliasTemplateInstantiation,
7250fca6ea1SDimitry Andric PointOfInstantiation, InstantiationRange, /*Entity=*/Entity,
7260fca6ea1SDimitry Andric /*Template=*/nullptr, TemplateArgs) {}
7270fca6ea1SDimitry Andric
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,TemplateDecl * Template,NamedDecl * Param,ArrayRef<TemplateArgument> TemplateArgs,SourceRange InstantiationRange)7280fca6ea1SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
7290b57cec5SDimitry Andric Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateDecl *Template,
7300b57cec5SDimitry Andric NamedDecl *Param, ArrayRef<TemplateArgument> TemplateArgs,
7310b57cec5SDimitry Andric SourceRange InstantiationRange)
7320b57cec5SDimitry Andric : InstantiatingTemplate(
7330b57cec5SDimitry Andric SemaRef, CodeSynthesisContext::DefaultTemplateArgumentChecking,
7340b57cec5SDimitry Andric PointOfInstantiation, InstantiationRange, Param, Template,
7350b57cec5SDimitry Andric TemplateArgs) {}
7360b57cec5SDimitry Andric
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,concepts::Requirement * Req,sema::TemplateDeductionInfo & DeductionInfo,SourceRange InstantiationRange)737a7dea167SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
738a7dea167SDimitry Andric Sema &SemaRef, SourceLocation PointOfInstantiation,
73955e4f9d5SDimitry Andric concepts::Requirement *Req, sema::TemplateDeductionInfo &DeductionInfo,
74055e4f9d5SDimitry Andric SourceRange InstantiationRange)
74155e4f9d5SDimitry Andric : InstantiatingTemplate(
74255e4f9d5SDimitry Andric SemaRef, CodeSynthesisContext::RequirementInstantiation,
74355e4f9d5SDimitry Andric PointOfInstantiation, InstantiationRange, /*Entity=*/nullptr,
744bdd1243dSDimitry Andric /*Template=*/nullptr, /*TemplateArgs=*/std::nullopt, &DeductionInfo) {
745bdd1243dSDimitry Andric }
74655e4f9d5SDimitry Andric
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,concepts::NestedRequirement * Req,ConstraintsCheck,SourceRange InstantiationRange)74755e4f9d5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
74855e4f9d5SDimitry Andric Sema &SemaRef, SourceLocation PointOfInstantiation,
74955e4f9d5SDimitry Andric concepts::NestedRequirement *Req, ConstraintsCheck,
75055e4f9d5SDimitry Andric SourceRange InstantiationRange)
75155e4f9d5SDimitry Andric : InstantiatingTemplate(
75255e4f9d5SDimitry Andric SemaRef, CodeSynthesisContext::NestedRequirementConstraintsCheck,
75355e4f9d5SDimitry Andric PointOfInstantiation, InstantiationRange, /*Entity=*/nullptr,
754bdd1243dSDimitry Andric /*Template=*/nullptr, /*TemplateArgs=*/std::nullopt) {}
75555e4f9d5SDimitry Andric
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,const RequiresExpr * RE,sema::TemplateDeductionInfo & DeductionInfo,SourceRange InstantiationRange)756bdd1243dSDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
757bdd1243dSDimitry Andric Sema &SemaRef, SourceLocation PointOfInstantiation, const RequiresExpr *RE,
758bdd1243dSDimitry Andric sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
759bdd1243dSDimitry Andric : InstantiatingTemplate(
760bdd1243dSDimitry Andric SemaRef, CodeSynthesisContext::RequirementParameterInstantiation,
761bdd1243dSDimitry Andric PointOfInstantiation, InstantiationRange, /*Entity=*/nullptr,
762bdd1243dSDimitry Andric /*Template=*/nullptr, /*TemplateArgs=*/std::nullopt, &DeductionInfo) {
763bdd1243dSDimitry Andric }
76455e4f9d5SDimitry Andric
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,ConstraintsCheck,NamedDecl * Template,ArrayRef<TemplateArgument> TemplateArgs,SourceRange InstantiationRange)76555e4f9d5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
76655e4f9d5SDimitry Andric Sema &SemaRef, SourceLocation PointOfInstantiation,
767480093f4SDimitry Andric ConstraintsCheck, NamedDecl *Template,
768a7dea167SDimitry Andric ArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange)
769a7dea167SDimitry Andric : InstantiatingTemplate(
770a7dea167SDimitry Andric SemaRef, CodeSynthesisContext::ConstraintsCheck,
771a7dea167SDimitry Andric PointOfInstantiation, InstantiationRange, Template, nullptr,
772a7dea167SDimitry Andric TemplateArgs) {}
773a7dea167SDimitry Andric
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,ConstraintSubstitution,NamedDecl * Template,sema::TemplateDeductionInfo & DeductionInfo,SourceRange InstantiationRange)774a7dea167SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
775a7dea167SDimitry Andric Sema &SemaRef, SourceLocation PointOfInstantiation,
776480093f4SDimitry Andric ConstraintSubstitution, NamedDecl *Template,
777a7dea167SDimitry Andric sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
778a7dea167SDimitry Andric : InstantiatingTemplate(
779a7dea167SDimitry Andric SemaRef, CodeSynthesisContext::ConstraintSubstitution,
780a7dea167SDimitry Andric PointOfInstantiation, InstantiationRange, Template, nullptr,
781a7dea167SDimitry Andric {}, &DeductionInfo) {}
782a7dea167SDimitry Andric
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,ConstraintNormalization,NamedDecl * Template,SourceRange InstantiationRange)783480093f4SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
784480093f4SDimitry Andric Sema &SemaRef, SourceLocation PointOfInstantiation,
785480093f4SDimitry Andric ConstraintNormalization, NamedDecl *Template,
786480093f4SDimitry Andric SourceRange InstantiationRange)
787480093f4SDimitry Andric : InstantiatingTemplate(
788480093f4SDimitry Andric SemaRef, CodeSynthesisContext::ConstraintNormalization,
789480093f4SDimitry Andric PointOfInstantiation, InstantiationRange, Template) {}
790480093f4SDimitry Andric
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,ParameterMappingSubstitution,NamedDecl * Template,SourceRange InstantiationRange)791480093f4SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
792480093f4SDimitry Andric Sema &SemaRef, SourceLocation PointOfInstantiation,
793480093f4SDimitry Andric ParameterMappingSubstitution, NamedDecl *Template,
794480093f4SDimitry Andric SourceRange InstantiationRange)
795480093f4SDimitry Andric : InstantiatingTemplate(
796480093f4SDimitry Andric SemaRef, CodeSynthesisContext::ParameterMappingSubstitution,
797480093f4SDimitry Andric PointOfInstantiation, InstantiationRange, Template) {}
798480093f4SDimitry Andric
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,TemplateDecl * Entity,BuildingDeductionGuidesTag,SourceRange InstantiationRange)79906c3fb27SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
80006c3fb27SDimitry Andric Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateDecl *Entity,
80106c3fb27SDimitry Andric BuildingDeductionGuidesTag, SourceRange InstantiationRange)
80206c3fb27SDimitry Andric : InstantiatingTemplate(
80306c3fb27SDimitry Andric SemaRef, CodeSynthesisContext::BuildingDeductionGuides,
80406c3fb27SDimitry Andric PointOfInstantiation, InstantiationRange, Entity) {}
80506c3fb27SDimitry Andric
806bdd1243dSDimitry Andric
pushCodeSynthesisContext(CodeSynthesisContext Ctx)8070b57cec5SDimitry Andric void Sema::pushCodeSynthesisContext(CodeSynthesisContext Ctx) {
8080b57cec5SDimitry Andric Ctx.SavedInNonInstantiationSFINAEContext = InNonInstantiationSFINAEContext;
8090b57cec5SDimitry Andric InNonInstantiationSFINAEContext = false;
8100b57cec5SDimitry Andric
8110b57cec5SDimitry Andric CodeSynthesisContexts.push_back(Ctx);
8120b57cec5SDimitry Andric
8130b57cec5SDimitry Andric if (!Ctx.isInstantiationRecord())
8140b57cec5SDimitry Andric ++NonInstantiationEntries;
815a7dea167SDimitry Andric
816a7dea167SDimitry Andric // Check to see if we're low on stack space. We can't do anything about this
817a7dea167SDimitry Andric // from here, but we can at least warn the user.
818a7dea167SDimitry Andric if (isStackNearlyExhausted())
819a7dea167SDimitry Andric warnStackExhausted(Ctx.PointOfInstantiation);
8200b57cec5SDimitry Andric }
8210b57cec5SDimitry Andric
popCodeSynthesisContext()8220b57cec5SDimitry Andric void Sema::popCodeSynthesisContext() {
8230b57cec5SDimitry Andric auto &Active = CodeSynthesisContexts.back();
8240b57cec5SDimitry Andric if (!Active.isInstantiationRecord()) {
8250b57cec5SDimitry Andric assert(NonInstantiationEntries > 0);
8260b57cec5SDimitry Andric --NonInstantiationEntries;
8270b57cec5SDimitry Andric }
8280b57cec5SDimitry Andric
8290b57cec5SDimitry Andric InNonInstantiationSFINAEContext = Active.SavedInNonInstantiationSFINAEContext;
8300b57cec5SDimitry Andric
8310b57cec5SDimitry Andric // Name lookup no longer looks in this template's defining module.
8320b57cec5SDimitry Andric assert(CodeSynthesisContexts.size() >=
8330b57cec5SDimitry Andric CodeSynthesisContextLookupModules.size() &&
8340b57cec5SDimitry Andric "forgot to remove a lookup module for a template instantiation");
8350b57cec5SDimitry Andric if (CodeSynthesisContexts.size() ==
8360b57cec5SDimitry Andric CodeSynthesisContextLookupModules.size()) {
8370b57cec5SDimitry Andric if (Module *M = CodeSynthesisContextLookupModules.back())
8380b57cec5SDimitry Andric LookupModulesCache.erase(M);
8390b57cec5SDimitry Andric CodeSynthesisContextLookupModules.pop_back();
8400b57cec5SDimitry Andric }
8410b57cec5SDimitry Andric
8420b57cec5SDimitry Andric // If we've left the code synthesis context for the current context stack,
8430b57cec5SDimitry Andric // stop remembering that we've emitted that stack.
8440b57cec5SDimitry Andric if (CodeSynthesisContexts.size() ==
8450b57cec5SDimitry Andric LastEmittedCodeSynthesisContextDepth)
8460b57cec5SDimitry Andric LastEmittedCodeSynthesisContextDepth = 0;
8470b57cec5SDimitry Andric
8480b57cec5SDimitry Andric CodeSynthesisContexts.pop_back();
8490b57cec5SDimitry Andric }
8500b57cec5SDimitry Andric
Clear()8510b57cec5SDimitry Andric void Sema::InstantiatingTemplate::Clear() {
8520b57cec5SDimitry Andric if (!Invalid) {
8530b57cec5SDimitry Andric if (!AlreadyInstantiating) {
8540b57cec5SDimitry Andric auto &Active = SemaRef.CodeSynthesisContexts.back();
85555e4f9d5SDimitry Andric if (Active.Entity)
8560b57cec5SDimitry Andric SemaRef.InstantiatingSpecializations.erase(
857e8d8bef9SDimitry Andric {Active.Entity->getCanonicalDecl(), Active.Kind});
8580b57cec5SDimitry Andric }
8590b57cec5SDimitry Andric
8600b57cec5SDimitry Andric atTemplateEnd(SemaRef.TemplateInstCallbacks, SemaRef,
8610b57cec5SDimitry Andric SemaRef.CodeSynthesisContexts.back());
8620b57cec5SDimitry Andric
8630b57cec5SDimitry Andric SemaRef.popCodeSynthesisContext();
8640b57cec5SDimitry Andric Invalid = true;
8650b57cec5SDimitry Andric }
8660b57cec5SDimitry Andric }
8670b57cec5SDimitry Andric
convertCallArgsToString(Sema & S,llvm::ArrayRef<const Expr * > Args)86881ad6265SDimitry Andric static std::string convertCallArgsToString(Sema &S,
86981ad6265SDimitry Andric llvm::ArrayRef<const Expr *> Args) {
87081ad6265SDimitry Andric std::string Result;
87181ad6265SDimitry Andric llvm::raw_string_ostream OS(Result);
87281ad6265SDimitry Andric llvm::ListSeparator Comma;
87381ad6265SDimitry Andric for (const Expr *Arg : Args) {
87481ad6265SDimitry Andric OS << Comma;
87581ad6265SDimitry Andric Arg->IgnoreParens()->printPretty(OS, nullptr,
87681ad6265SDimitry Andric S.Context.getPrintingPolicy());
87781ad6265SDimitry Andric }
87881ad6265SDimitry Andric return Result;
87981ad6265SDimitry Andric }
88081ad6265SDimitry Andric
CheckInstantiationDepth(SourceLocation PointOfInstantiation,SourceRange InstantiationRange)8810b57cec5SDimitry Andric bool Sema::InstantiatingTemplate::CheckInstantiationDepth(
8820b57cec5SDimitry Andric SourceLocation PointOfInstantiation,
8830b57cec5SDimitry Andric SourceRange InstantiationRange) {
8840b57cec5SDimitry Andric assert(SemaRef.NonInstantiationEntries <=
8850b57cec5SDimitry Andric SemaRef.CodeSynthesisContexts.size());
8860b57cec5SDimitry Andric if ((SemaRef.CodeSynthesisContexts.size() -
8870b57cec5SDimitry Andric SemaRef.NonInstantiationEntries)
8880b57cec5SDimitry Andric <= SemaRef.getLangOpts().InstantiationDepth)
8890b57cec5SDimitry Andric return false;
8900b57cec5SDimitry Andric
8910b57cec5SDimitry Andric SemaRef.Diag(PointOfInstantiation,
8920b57cec5SDimitry Andric diag::err_template_recursion_depth_exceeded)
8930b57cec5SDimitry Andric << SemaRef.getLangOpts().InstantiationDepth
8940b57cec5SDimitry Andric << InstantiationRange;
8950b57cec5SDimitry Andric SemaRef.Diag(PointOfInstantiation, diag::note_template_recursion_depth)
8960b57cec5SDimitry Andric << SemaRef.getLangOpts().InstantiationDepth;
8970b57cec5SDimitry Andric return true;
8980b57cec5SDimitry Andric }
8990b57cec5SDimitry Andric
PrintInstantiationStack()9000b57cec5SDimitry Andric void Sema::PrintInstantiationStack() {
9010b57cec5SDimitry Andric // Determine which template instantiations to skip, if any.
9020b57cec5SDimitry Andric unsigned SkipStart = CodeSynthesisContexts.size(), SkipEnd = SkipStart;
9030b57cec5SDimitry Andric unsigned Limit = Diags.getTemplateBacktraceLimit();
9040b57cec5SDimitry Andric if (Limit && Limit < CodeSynthesisContexts.size()) {
9050b57cec5SDimitry Andric SkipStart = Limit / 2 + Limit % 2;
9060b57cec5SDimitry Andric SkipEnd = CodeSynthesisContexts.size() - Limit / 2;
9070b57cec5SDimitry Andric }
9080b57cec5SDimitry Andric
9090b57cec5SDimitry Andric // FIXME: In all of these cases, we need to show the template arguments
9100b57cec5SDimitry Andric unsigned InstantiationIdx = 0;
9110b57cec5SDimitry Andric for (SmallVectorImpl<CodeSynthesisContext>::reverse_iterator
9120b57cec5SDimitry Andric Active = CodeSynthesisContexts.rbegin(),
9130b57cec5SDimitry Andric ActiveEnd = CodeSynthesisContexts.rend();
9140b57cec5SDimitry Andric Active != ActiveEnd;
9150b57cec5SDimitry Andric ++Active, ++InstantiationIdx) {
9160b57cec5SDimitry Andric // Skip this instantiation?
9170b57cec5SDimitry Andric if (InstantiationIdx >= SkipStart && InstantiationIdx < SkipEnd) {
9180b57cec5SDimitry Andric if (InstantiationIdx == SkipStart) {
9190b57cec5SDimitry Andric // Note that we're skipping instantiations.
9200b57cec5SDimitry Andric Diags.Report(Active->PointOfInstantiation,
9210b57cec5SDimitry Andric diag::note_instantiation_contexts_suppressed)
9220b57cec5SDimitry Andric << unsigned(CodeSynthesisContexts.size() - Limit);
9230b57cec5SDimitry Andric }
9240b57cec5SDimitry Andric continue;
9250b57cec5SDimitry Andric }
9260b57cec5SDimitry Andric
9270b57cec5SDimitry Andric switch (Active->Kind) {
9280b57cec5SDimitry Andric case CodeSynthesisContext::TemplateInstantiation: {
9290b57cec5SDimitry Andric Decl *D = Active->Entity;
9300b57cec5SDimitry Andric if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) {
9310b57cec5SDimitry Andric unsigned DiagID = diag::note_template_member_class_here;
9320b57cec5SDimitry Andric if (isa<ClassTemplateSpecializationDecl>(Record))
9330b57cec5SDimitry Andric DiagID = diag::note_template_class_instantiation_here;
9340b57cec5SDimitry Andric Diags.Report(Active->PointOfInstantiation, DiagID)
9350b57cec5SDimitry Andric << Record << Active->InstantiationRange;
9360b57cec5SDimitry Andric } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
9370b57cec5SDimitry Andric unsigned DiagID;
9380b57cec5SDimitry Andric if (Function->getPrimaryTemplate())
9390b57cec5SDimitry Andric DiagID = diag::note_function_template_spec_here;
9400b57cec5SDimitry Andric else
9410b57cec5SDimitry Andric DiagID = diag::note_template_member_function_here;
9420b57cec5SDimitry Andric Diags.Report(Active->PointOfInstantiation, DiagID)
9430b57cec5SDimitry Andric << Function
9440b57cec5SDimitry Andric << Active->InstantiationRange;
9450b57cec5SDimitry Andric } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
9460b57cec5SDimitry Andric Diags.Report(Active->PointOfInstantiation,
9470b57cec5SDimitry Andric VD->isStaticDataMember()?
9480b57cec5SDimitry Andric diag::note_template_static_data_member_def_here
9490b57cec5SDimitry Andric : diag::note_template_variable_def_here)
9500b57cec5SDimitry Andric << VD
9510b57cec5SDimitry Andric << Active->InstantiationRange;
9520b57cec5SDimitry Andric } else if (EnumDecl *ED = dyn_cast<EnumDecl>(D)) {
9530b57cec5SDimitry Andric Diags.Report(Active->PointOfInstantiation,
9540b57cec5SDimitry Andric diag::note_template_enum_def_here)
9550b57cec5SDimitry Andric << ED
9560b57cec5SDimitry Andric << Active->InstantiationRange;
9570b57cec5SDimitry Andric } else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
9580b57cec5SDimitry Andric Diags.Report(Active->PointOfInstantiation,
9590b57cec5SDimitry Andric diag::note_template_nsdmi_here)
9600b57cec5SDimitry Andric << FD << Active->InstantiationRange;
961bcd401b5SDimitry Andric } else if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(D)) {
962bcd401b5SDimitry Andric Diags.Report(Active->PointOfInstantiation,
963bcd401b5SDimitry Andric diag::note_template_class_instantiation_here)
964bcd401b5SDimitry Andric << CTD << Active->InstantiationRange;
9650b57cec5SDimitry Andric }
9660b57cec5SDimitry Andric break;
9670b57cec5SDimitry Andric }
9680b57cec5SDimitry Andric
9690b57cec5SDimitry Andric case CodeSynthesisContext::DefaultTemplateArgumentInstantiation: {
9700b57cec5SDimitry Andric TemplateDecl *Template = cast<TemplateDecl>(Active->Template);
971e8d8bef9SDimitry Andric SmallString<128> TemplateArgsStr;
9720b57cec5SDimitry Andric llvm::raw_svector_ostream OS(TemplateArgsStr);
973bdd1243dSDimitry Andric Template->printName(OS, getPrintingPolicy());
9740b57cec5SDimitry Andric printTemplateArgumentList(OS, Active->template_arguments(),
9750b57cec5SDimitry Andric getPrintingPolicy());
9760b57cec5SDimitry Andric Diags.Report(Active->PointOfInstantiation,
9770b57cec5SDimitry Andric diag::note_default_arg_instantiation_here)
9780b57cec5SDimitry Andric << OS.str()
9790b57cec5SDimitry Andric << Active->InstantiationRange;
9800b57cec5SDimitry Andric break;
9810b57cec5SDimitry Andric }
9820b57cec5SDimitry Andric
9830b57cec5SDimitry Andric case CodeSynthesisContext::ExplicitTemplateArgumentSubstitution: {
9840b57cec5SDimitry Andric FunctionTemplateDecl *FnTmpl = cast<FunctionTemplateDecl>(Active->Entity);
9850b57cec5SDimitry Andric Diags.Report(Active->PointOfInstantiation,
9860b57cec5SDimitry Andric diag::note_explicit_template_arg_substitution_here)
9870b57cec5SDimitry Andric << FnTmpl
9880b57cec5SDimitry Andric << getTemplateArgumentBindingsText(FnTmpl->getTemplateParameters(),
9890b57cec5SDimitry Andric Active->TemplateArgs,
9900b57cec5SDimitry Andric Active->NumTemplateArgs)
9910b57cec5SDimitry Andric << Active->InstantiationRange;
9920b57cec5SDimitry Andric break;
9930b57cec5SDimitry Andric }
9940b57cec5SDimitry Andric
9950b57cec5SDimitry Andric case CodeSynthesisContext::DeducedTemplateArgumentSubstitution: {
9960b57cec5SDimitry Andric if (FunctionTemplateDecl *FnTmpl =
9970b57cec5SDimitry Andric dyn_cast<FunctionTemplateDecl>(Active->Entity)) {
9980b57cec5SDimitry Andric Diags.Report(Active->PointOfInstantiation,
9990b57cec5SDimitry Andric diag::note_function_template_deduction_instantiation_here)
10000b57cec5SDimitry Andric << FnTmpl
10010b57cec5SDimitry Andric << getTemplateArgumentBindingsText(FnTmpl->getTemplateParameters(),
10020b57cec5SDimitry Andric Active->TemplateArgs,
10030b57cec5SDimitry Andric Active->NumTemplateArgs)
10040b57cec5SDimitry Andric << Active->InstantiationRange;
10050b57cec5SDimitry Andric } else {
10060b57cec5SDimitry Andric bool IsVar = isa<VarTemplateDecl>(Active->Entity) ||
10070b57cec5SDimitry Andric isa<VarTemplateSpecializationDecl>(Active->Entity);
10080b57cec5SDimitry Andric bool IsTemplate = false;
10090b57cec5SDimitry Andric TemplateParameterList *Params;
10100b57cec5SDimitry Andric if (auto *D = dyn_cast<TemplateDecl>(Active->Entity)) {
10110b57cec5SDimitry Andric IsTemplate = true;
10120b57cec5SDimitry Andric Params = D->getTemplateParameters();
10130b57cec5SDimitry Andric } else if (auto *D = dyn_cast<ClassTemplatePartialSpecializationDecl>(
10140b57cec5SDimitry Andric Active->Entity)) {
10150b57cec5SDimitry Andric Params = D->getTemplateParameters();
10160b57cec5SDimitry Andric } else if (auto *D = dyn_cast<VarTemplatePartialSpecializationDecl>(
10170b57cec5SDimitry Andric Active->Entity)) {
10180b57cec5SDimitry Andric Params = D->getTemplateParameters();
10190b57cec5SDimitry Andric } else {
10200b57cec5SDimitry Andric llvm_unreachable("unexpected template kind");
10210b57cec5SDimitry Andric }
10220b57cec5SDimitry Andric
10230b57cec5SDimitry Andric Diags.Report(Active->PointOfInstantiation,
10240b57cec5SDimitry Andric diag::note_deduced_template_arg_substitution_here)
10250b57cec5SDimitry Andric << IsVar << IsTemplate << cast<NamedDecl>(Active->Entity)
10260b57cec5SDimitry Andric << getTemplateArgumentBindingsText(Params, Active->TemplateArgs,
10270b57cec5SDimitry Andric Active->NumTemplateArgs)
10280b57cec5SDimitry Andric << Active->InstantiationRange;
10290b57cec5SDimitry Andric }
10300b57cec5SDimitry Andric break;
10310b57cec5SDimitry Andric }
10320b57cec5SDimitry Andric
10330b57cec5SDimitry Andric case CodeSynthesisContext::DefaultFunctionArgumentInstantiation: {
10340b57cec5SDimitry Andric ParmVarDecl *Param = cast<ParmVarDecl>(Active->Entity);
10350b57cec5SDimitry Andric FunctionDecl *FD = cast<FunctionDecl>(Param->getDeclContext());
10360b57cec5SDimitry Andric
1037e8d8bef9SDimitry Andric SmallString<128> TemplateArgsStr;
10380b57cec5SDimitry Andric llvm::raw_svector_ostream OS(TemplateArgsStr);
1039bdd1243dSDimitry Andric FD->printName(OS, getPrintingPolicy());
10400b57cec5SDimitry Andric printTemplateArgumentList(OS, Active->template_arguments(),
10410b57cec5SDimitry Andric getPrintingPolicy());
10420b57cec5SDimitry Andric Diags.Report(Active->PointOfInstantiation,
10430b57cec5SDimitry Andric diag::note_default_function_arg_instantiation_here)
10440b57cec5SDimitry Andric << OS.str()
10450b57cec5SDimitry Andric << Active->InstantiationRange;
10460b57cec5SDimitry Andric break;
10470b57cec5SDimitry Andric }
10480b57cec5SDimitry Andric
10490b57cec5SDimitry Andric case CodeSynthesisContext::PriorTemplateArgumentSubstitution: {
10500b57cec5SDimitry Andric NamedDecl *Parm = cast<NamedDecl>(Active->Entity);
10510b57cec5SDimitry Andric std::string Name;
10520b57cec5SDimitry Andric if (!Parm->getName().empty())
10530b57cec5SDimitry Andric Name = std::string(" '") + Parm->getName().str() + "'";
10540b57cec5SDimitry Andric
10550b57cec5SDimitry Andric TemplateParameterList *TemplateParams = nullptr;
10560b57cec5SDimitry Andric if (TemplateDecl *Template = dyn_cast<TemplateDecl>(Active->Template))
10570b57cec5SDimitry Andric TemplateParams = Template->getTemplateParameters();
10580b57cec5SDimitry Andric else
10590b57cec5SDimitry Andric TemplateParams =
10600b57cec5SDimitry Andric cast<ClassTemplatePartialSpecializationDecl>(Active->Template)
10610b57cec5SDimitry Andric ->getTemplateParameters();
10620b57cec5SDimitry Andric Diags.Report(Active->PointOfInstantiation,
10630b57cec5SDimitry Andric diag::note_prior_template_arg_substitution)
10640b57cec5SDimitry Andric << isa<TemplateTemplateParmDecl>(Parm)
10650b57cec5SDimitry Andric << Name
10660b57cec5SDimitry Andric << getTemplateArgumentBindingsText(TemplateParams,
10670b57cec5SDimitry Andric Active->TemplateArgs,
10680b57cec5SDimitry Andric Active->NumTemplateArgs)
10690b57cec5SDimitry Andric << Active->InstantiationRange;
10700b57cec5SDimitry Andric break;
10710b57cec5SDimitry Andric }
10720b57cec5SDimitry Andric
10730b57cec5SDimitry Andric case CodeSynthesisContext::DefaultTemplateArgumentChecking: {
10740b57cec5SDimitry Andric TemplateParameterList *TemplateParams = nullptr;
10750b57cec5SDimitry Andric if (TemplateDecl *Template = dyn_cast<TemplateDecl>(Active->Template))
10760b57cec5SDimitry Andric TemplateParams = Template->getTemplateParameters();
10770b57cec5SDimitry Andric else
10780b57cec5SDimitry Andric TemplateParams =
10790b57cec5SDimitry Andric cast<ClassTemplatePartialSpecializationDecl>(Active->Template)
10800b57cec5SDimitry Andric ->getTemplateParameters();
10810b57cec5SDimitry Andric
10820b57cec5SDimitry Andric Diags.Report(Active->PointOfInstantiation,
10830b57cec5SDimitry Andric diag::note_template_default_arg_checking)
10840b57cec5SDimitry Andric << getTemplateArgumentBindingsText(TemplateParams,
10850b57cec5SDimitry Andric Active->TemplateArgs,
10860b57cec5SDimitry Andric Active->NumTemplateArgs)
10870b57cec5SDimitry Andric << Active->InstantiationRange;
10880b57cec5SDimitry Andric break;
10890b57cec5SDimitry Andric }
10900b57cec5SDimitry Andric
10910b57cec5SDimitry Andric case CodeSynthesisContext::ExceptionSpecEvaluation:
10920b57cec5SDimitry Andric Diags.Report(Active->PointOfInstantiation,
10930b57cec5SDimitry Andric diag::note_evaluating_exception_spec_here)
10940b57cec5SDimitry Andric << cast<FunctionDecl>(Active->Entity);
10950b57cec5SDimitry Andric break;
10960b57cec5SDimitry Andric
10970b57cec5SDimitry Andric case CodeSynthesisContext::ExceptionSpecInstantiation:
10980b57cec5SDimitry Andric Diags.Report(Active->PointOfInstantiation,
10990b57cec5SDimitry Andric diag::note_template_exception_spec_instantiation_here)
11000b57cec5SDimitry Andric << cast<FunctionDecl>(Active->Entity)
11010b57cec5SDimitry Andric << Active->InstantiationRange;
11020b57cec5SDimitry Andric break;
11030b57cec5SDimitry Andric
110455e4f9d5SDimitry Andric case CodeSynthesisContext::RequirementInstantiation:
110555e4f9d5SDimitry Andric Diags.Report(Active->PointOfInstantiation,
110655e4f9d5SDimitry Andric diag::note_template_requirement_instantiation_here)
110755e4f9d5SDimitry Andric << Active->InstantiationRange;
110855e4f9d5SDimitry Andric break;
1109bdd1243dSDimitry Andric case CodeSynthesisContext::RequirementParameterInstantiation:
1110bdd1243dSDimitry Andric Diags.Report(Active->PointOfInstantiation,
1111bdd1243dSDimitry Andric diag::note_template_requirement_params_instantiation_here)
1112bdd1243dSDimitry Andric << Active->InstantiationRange;
1113bdd1243dSDimitry Andric break;
111455e4f9d5SDimitry Andric
111555e4f9d5SDimitry Andric case CodeSynthesisContext::NestedRequirementConstraintsCheck:
111655e4f9d5SDimitry Andric Diags.Report(Active->PointOfInstantiation,
111755e4f9d5SDimitry Andric diag::note_nested_requirement_here)
111855e4f9d5SDimitry Andric << Active->InstantiationRange;
111955e4f9d5SDimitry Andric break;
112055e4f9d5SDimitry Andric
11210b57cec5SDimitry Andric case CodeSynthesisContext::DeclaringSpecialMember:
11220b57cec5SDimitry Andric Diags.Report(Active->PointOfInstantiation,
11230b57cec5SDimitry Andric diag::note_in_declaration_of_implicit_special_member)
11240fca6ea1SDimitry Andric << cast<CXXRecordDecl>(Active->Entity)
11250fca6ea1SDimitry Andric << llvm::to_underlying(Active->SpecialMember);
11260b57cec5SDimitry Andric break;
11270b57cec5SDimitry Andric
1128480093f4SDimitry Andric case CodeSynthesisContext::DeclaringImplicitEqualityComparison:
1129480093f4SDimitry Andric Diags.Report(Active->Entity->getLocation(),
1130480093f4SDimitry Andric diag::note_in_declaration_of_implicit_equality_comparison);
1131480093f4SDimitry Andric break;
1132480093f4SDimitry Andric
11330b57cec5SDimitry Andric case CodeSynthesisContext::DefiningSynthesizedFunction: {
1134480093f4SDimitry Andric // FIXME: For synthesized functions that are not defaulted,
1135480093f4SDimitry Andric // produce a note.
1136480093f4SDimitry Andric auto *FD = dyn_cast<FunctionDecl>(Active->Entity);
1137480093f4SDimitry Andric DefaultedFunctionKind DFK =
1138480093f4SDimitry Andric FD ? getDefaultedFunctionKind(FD) : DefaultedFunctionKind();
1139480093f4SDimitry Andric if (DFK.isSpecialMember()) {
1140480093f4SDimitry Andric auto *MD = cast<CXXMethodDecl>(FD);
11410b57cec5SDimitry Andric Diags.Report(Active->PointOfInstantiation,
11420b57cec5SDimitry Andric diag::note_member_synthesized_at)
11430fca6ea1SDimitry Andric << MD->isExplicitlyDefaulted()
11440fca6ea1SDimitry Andric << llvm::to_underlying(DFK.asSpecialMember())
1145480093f4SDimitry Andric << Context.getTagDeclType(MD->getParent());
1146480093f4SDimitry Andric } else if (DFK.isComparison()) {
114706c3fb27SDimitry Andric QualType RecordType = FD->getParamDecl(0)
114806c3fb27SDimitry Andric ->getType()
114906c3fb27SDimitry Andric .getNonReferenceType()
115006c3fb27SDimitry Andric .getUnqualifiedType();
1151480093f4SDimitry Andric Diags.Report(Active->PointOfInstantiation,
1152480093f4SDimitry Andric diag::note_comparison_synthesized_at)
115306c3fb27SDimitry Andric << (int)DFK.asComparison() << RecordType;
11540b57cec5SDimitry Andric }
11550b57cec5SDimitry Andric break;
11560b57cec5SDimitry Andric }
11570b57cec5SDimitry Andric
1158a7dea167SDimitry Andric case CodeSynthesisContext::RewritingOperatorAsSpaceship:
1159a7dea167SDimitry Andric Diags.Report(Active->Entity->getLocation(),
1160a7dea167SDimitry Andric diag::note_rewriting_operator_as_spaceship);
1161a7dea167SDimitry Andric break;
1162a7dea167SDimitry Andric
11635ffd83dbSDimitry Andric case CodeSynthesisContext::InitializingStructuredBinding:
11645ffd83dbSDimitry Andric Diags.Report(Active->PointOfInstantiation,
11655ffd83dbSDimitry Andric diag::note_in_binding_decl_init)
11665ffd83dbSDimitry Andric << cast<BindingDecl>(Active->Entity);
11675ffd83dbSDimitry Andric break;
11685ffd83dbSDimitry Andric
11695ffd83dbSDimitry Andric case CodeSynthesisContext::MarkingClassDllexported:
11705ffd83dbSDimitry Andric Diags.Report(Active->PointOfInstantiation,
11715ffd83dbSDimitry Andric diag::note_due_to_dllexported_class)
11725ffd83dbSDimitry Andric << cast<CXXRecordDecl>(Active->Entity) << !getLangOpts().CPlusPlus11;
11735ffd83dbSDimitry Andric break;
11745ffd83dbSDimitry Andric
117581ad6265SDimitry Andric case CodeSynthesisContext::BuildingBuiltinDumpStructCall:
117681ad6265SDimitry Andric Diags.Report(Active->PointOfInstantiation,
117781ad6265SDimitry Andric diag::note_building_builtin_dump_struct_call)
117881ad6265SDimitry Andric << convertCallArgsToString(
1179bdd1243dSDimitry Andric *this, llvm::ArrayRef(Active->CallArgs, Active->NumCallArgs));
118081ad6265SDimitry Andric break;
118181ad6265SDimitry Andric
11820b57cec5SDimitry Andric case CodeSynthesisContext::Memoization:
11830b57cec5SDimitry Andric break;
1184a7dea167SDimitry Andric
118506c3fb27SDimitry Andric case CodeSynthesisContext::LambdaExpressionSubstitution:
118606c3fb27SDimitry Andric Diags.Report(Active->PointOfInstantiation,
118706c3fb27SDimitry Andric diag::note_lambda_substitution_here);
118806c3fb27SDimitry Andric break;
1189480093f4SDimitry Andric case CodeSynthesisContext::ConstraintsCheck: {
1190480093f4SDimitry Andric unsigned DiagID = 0;
119113138422SDimitry Andric if (!Active->Entity) {
119213138422SDimitry Andric Diags.Report(Active->PointOfInstantiation,
119313138422SDimitry Andric diag::note_nested_requirement_here)
119413138422SDimitry Andric << Active->InstantiationRange;
119513138422SDimitry Andric break;
119613138422SDimitry Andric }
1197480093f4SDimitry Andric if (isa<ConceptDecl>(Active->Entity))
1198480093f4SDimitry Andric DiagID = diag::note_concept_specialization_here;
1199480093f4SDimitry Andric else if (isa<TemplateDecl>(Active->Entity))
1200480093f4SDimitry Andric DiagID = diag::note_checking_constraints_for_template_id_here;
1201480093f4SDimitry Andric else if (isa<VarTemplatePartialSpecializationDecl>(Active->Entity))
1202480093f4SDimitry Andric DiagID = diag::note_checking_constraints_for_var_spec_id_here;
120313138422SDimitry Andric else if (isa<ClassTemplatePartialSpecializationDecl>(Active->Entity))
1204480093f4SDimitry Andric DiagID = diag::note_checking_constraints_for_class_spec_id_here;
120513138422SDimitry Andric else {
120613138422SDimitry Andric assert(isa<FunctionDecl>(Active->Entity));
120713138422SDimitry Andric DiagID = diag::note_checking_constraints_for_function_here;
1208480093f4SDimitry Andric }
1209e8d8bef9SDimitry Andric SmallString<128> TemplateArgsStr;
1210a7dea167SDimitry Andric llvm::raw_svector_ostream OS(TemplateArgsStr);
1211bdd1243dSDimitry Andric cast<NamedDecl>(Active->Entity)->printName(OS, getPrintingPolicy());
1212fe6060f1SDimitry Andric if (!isa<FunctionDecl>(Active->Entity)) {
1213a7dea167SDimitry Andric printTemplateArgumentList(OS, Active->template_arguments(),
1214a7dea167SDimitry Andric getPrintingPolicy());
1215fe6060f1SDimitry Andric }
1216480093f4SDimitry Andric Diags.Report(Active->PointOfInstantiation, DiagID) << OS.str()
1217a7dea167SDimitry Andric << Active->InstantiationRange;
1218a7dea167SDimitry Andric break;
1219a7dea167SDimitry Andric }
1220a7dea167SDimitry Andric case CodeSynthesisContext::ConstraintSubstitution:
1221a7dea167SDimitry Andric Diags.Report(Active->PointOfInstantiation,
1222a7dea167SDimitry Andric diag::note_constraint_substitution_here)
1223a7dea167SDimitry Andric << Active->InstantiationRange;
1224a7dea167SDimitry Andric break;
1225480093f4SDimitry Andric case CodeSynthesisContext::ConstraintNormalization:
1226480093f4SDimitry Andric Diags.Report(Active->PointOfInstantiation,
1227480093f4SDimitry Andric diag::note_constraint_normalization_here)
1228480093f4SDimitry Andric << cast<NamedDecl>(Active->Entity)->getName()
1229480093f4SDimitry Andric << Active->InstantiationRange;
1230480093f4SDimitry Andric break;
1231480093f4SDimitry Andric case CodeSynthesisContext::ParameterMappingSubstitution:
1232480093f4SDimitry Andric Diags.Report(Active->PointOfInstantiation,
1233480093f4SDimitry Andric diag::note_parameter_mapping_substitution_here)
1234480093f4SDimitry Andric << Active->InstantiationRange;
1235480093f4SDimitry Andric break;
123606c3fb27SDimitry Andric case CodeSynthesisContext::BuildingDeductionGuides:
12375f757f3fSDimitry Andric Diags.Report(Active->PointOfInstantiation,
12385f757f3fSDimitry Andric diag::note_building_deduction_guide_here);
12395f757f3fSDimitry Andric break;
12400fca6ea1SDimitry Andric case CodeSynthesisContext::TypeAliasTemplateInstantiation:
12410fca6ea1SDimitry Andric Diags.Report(Active->PointOfInstantiation,
12420fca6ea1SDimitry Andric diag::note_template_type_alias_instantiation_here)
12430fca6ea1SDimitry Andric << cast<TypeAliasTemplateDecl>(Active->Entity)
12440fca6ea1SDimitry Andric << Active->InstantiationRange;
12450fca6ea1SDimitry Andric break;
12460b57cec5SDimitry Andric }
12470b57cec5SDimitry Andric }
12480b57cec5SDimitry Andric }
12490b57cec5SDimitry Andric
isSFINAEContext() const1250bdd1243dSDimitry Andric std::optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const {
12510b57cec5SDimitry Andric if (InNonInstantiationSFINAEContext)
1252bdd1243dSDimitry Andric return std::optional<TemplateDeductionInfo *>(nullptr);
12530b57cec5SDimitry Andric
12540b57cec5SDimitry Andric for (SmallVectorImpl<CodeSynthesisContext>::const_reverse_iterator
12550b57cec5SDimitry Andric Active = CodeSynthesisContexts.rbegin(),
12560b57cec5SDimitry Andric ActiveEnd = CodeSynthesisContexts.rend();
12570b57cec5SDimitry Andric Active != ActiveEnd;
12580b57cec5SDimitry Andric ++Active)
12590b57cec5SDimitry Andric {
12600b57cec5SDimitry Andric switch (Active->Kind) {
12610fca6ea1SDimitry Andric case CodeSynthesisContext::TypeAliasTemplateInstantiation:
12620b57cec5SDimitry Andric // An instantiation of an alias template may or may not be a SFINAE
12630b57cec5SDimitry Andric // context, depending on what else is on the stack.
12640b57cec5SDimitry Andric if (isa<TypeAliasTemplateDecl>(Active->Entity))
12650b57cec5SDimitry Andric break;
1266bdd1243dSDimitry Andric [[fallthrough]];
12670fca6ea1SDimitry Andric case CodeSynthesisContext::TemplateInstantiation:
12680b57cec5SDimitry Andric case CodeSynthesisContext::DefaultFunctionArgumentInstantiation:
12690b57cec5SDimitry Andric case CodeSynthesisContext::ExceptionSpecInstantiation:
1270a7dea167SDimitry Andric case CodeSynthesisContext::ConstraintsCheck:
1271480093f4SDimitry Andric case CodeSynthesisContext::ParameterMappingSubstitution:
1272480093f4SDimitry Andric case CodeSynthesisContext::ConstraintNormalization:
127355e4f9d5SDimitry Andric case CodeSynthesisContext::NestedRequirementConstraintsCheck:
12740b57cec5SDimitry Andric // This is a template instantiation, so there is no SFINAE.
1275bdd1243dSDimitry Andric return std::nullopt;
127606c3fb27SDimitry Andric case CodeSynthesisContext::LambdaExpressionSubstitution:
127706c3fb27SDimitry Andric // [temp.deduct]p9
127806c3fb27SDimitry Andric // A lambda-expression appearing in a function type or a template
127906c3fb27SDimitry Andric // parameter is not considered part of the immediate context for the
128006c3fb27SDimitry Andric // purposes of template argument deduction.
12815f757f3fSDimitry Andric // CWG2672: A lambda-expression body is never in the immediate context.
12825f757f3fSDimitry Andric return std::nullopt;
12830b57cec5SDimitry Andric
12840b57cec5SDimitry Andric case CodeSynthesisContext::DefaultTemplateArgumentInstantiation:
12850b57cec5SDimitry Andric case CodeSynthesisContext::PriorTemplateArgumentSubstitution:
12860b57cec5SDimitry Andric case CodeSynthesisContext::DefaultTemplateArgumentChecking:
1287e8d8bef9SDimitry Andric case CodeSynthesisContext::RewritingOperatorAsSpaceship:
12880b57cec5SDimitry Andric // A default template argument instantiation and substitution into
12890b57cec5SDimitry Andric // template parameters with arguments for prior parameters may or may
12900b57cec5SDimitry Andric // not be a SFINAE context; look further up the stack.
12910b57cec5SDimitry Andric break;
12920b57cec5SDimitry Andric
12930b57cec5SDimitry Andric case CodeSynthesisContext::ExplicitTemplateArgumentSubstitution:
12940b57cec5SDimitry Andric case CodeSynthesisContext::DeducedTemplateArgumentSubstitution:
129506c3fb27SDimitry Andric // We're either substituting explicitly-specified template arguments,
129606c3fb27SDimitry Andric // deduced template arguments. SFINAE applies unless we are in a lambda
12971db9f3b2SDimitry Andric // body, see [temp.deduct]p9.
1298a7dea167SDimitry Andric case CodeSynthesisContext::ConstraintSubstitution:
129955e4f9d5SDimitry Andric case CodeSynthesisContext::RequirementInstantiation:
1300bdd1243dSDimitry Andric case CodeSynthesisContext::RequirementParameterInstantiation:
130106c3fb27SDimitry Andric // SFINAE always applies in a constraint expression or a requirement
130206c3fb27SDimitry Andric // in a requires expression.
13030b57cec5SDimitry Andric assert(Active->DeductionInfo && "Missing deduction info pointer");
13040b57cec5SDimitry Andric return Active->DeductionInfo;
13050b57cec5SDimitry Andric
13060b57cec5SDimitry Andric case CodeSynthesisContext::DeclaringSpecialMember:
1307480093f4SDimitry Andric case CodeSynthesisContext::DeclaringImplicitEqualityComparison:
13080b57cec5SDimitry Andric case CodeSynthesisContext::DefiningSynthesizedFunction:
13095ffd83dbSDimitry Andric case CodeSynthesisContext::InitializingStructuredBinding:
13105ffd83dbSDimitry Andric case CodeSynthesisContext::MarkingClassDllexported:
131181ad6265SDimitry Andric case CodeSynthesisContext::BuildingBuiltinDumpStructCall:
131206c3fb27SDimitry Andric case CodeSynthesisContext::BuildingDeductionGuides:
13130b57cec5SDimitry Andric // This happens in a context unrelated to template instantiation, so
13140b57cec5SDimitry Andric // there is no SFINAE.
1315bdd1243dSDimitry Andric return std::nullopt;
13160b57cec5SDimitry Andric
13170b57cec5SDimitry Andric case CodeSynthesisContext::ExceptionSpecEvaluation:
13180b57cec5SDimitry Andric // FIXME: This should not be treated as a SFINAE context, because
13190b57cec5SDimitry Andric // we will cache an incorrect exception specification. However, clang
13200b57cec5SDimitry Andric // bootstrap relies this! See PR31692.
13210b57cec5SDimitry Andric break;
13220b57cec5SDimitry Andric
13230b57cec5SDimitry Andric case CodeSynthesisContext::Memoization:
13240b57cec5SDimitry Andric break;
13250b57cec5SDimitry Andric }
13260b57cec5SDimitry Andric
13270b57cec5SDimitry Andric // The inner context was transparent for SFINAE. If it occurred within a
13280b57cec5SDimitry Andric // non-instantiation SFINAE context, then SFINAE applies.
13290b57cec5SDimitry Andric if (Active->SavedInNonInstantiationSFINAEContext)
1330bdd1243dSDimitry Andric return std::optional<TemplateDeductionInfo *>(nullptr);
13310b57cec5SDimitry Andric }
13320b57cec5SDimitry Andric
1333bdd1243dSDimitry Andric return std::nullopt;
13340b57cec5SDimitry Andric }
13350b57cec5SDimitry Andric
13360b57cec5SDimitry Andric //===----------------------------------------------------------------------===/
13370b57cec5SDimitry Andric // Template Instantiation for Types
13380b57cec5SDimitry Andric //===----------------------------------------------------------------------===/
13390b57cec5SDimitry Andric namespace {
13400b57cec5SDimitry Andric class TemplateInstantiator : public TreeTransform<TemplateInstantiator> {
13410b57cec5SDimitry Andric const MultiLevelTemplateArgumentList &TemplateArgs;
13420b57cec5SDimitry Andric SourceLocation Loc;
13430b57cec5SDimitry Andric DeclarationName Entity;
13441db9f3b2SDimitry Andric // Whether to evaluate the C++20 constraints or simply substitute into them.
1345bdd1243dSDimitry Andric bool EvaluateConstraints = true;
13460b57cec5SDimitry Andric
13470b57cec5SDimitry Andric public:
13480b57cec5SDimitry Andric typedef TreeTransform<TemplateInstantiator> inherited;
13490b57cec5SDimitry Andric
TemplateInstantiator(Sema & SemaRef,const MultiLevelTemplateArgumentList & TemplateArgs,SourceLocation Loc,DeclarationName Entity)13500b57cec5SDimitry Andric TemplateInstantiator(Sema &SemaRef,
13510b57cec5SDimitry Andric const MultiLevelTemplateArgumentList &TemplateArgs,
1352bdd1243dSDimitry Andric SourceLocation Loc, DeclarationName Entity)
13530b57cec5SDimitry Andric : inherited(SemaRef), TemplateArgs(TemplateArgs), Loc(Loc),
13540b57cec5SDimitry Andric Entity(Entity) {}
13550b57cec5SDimitry Andric
setEvaluateConstraints(bool B)1356bdd1243dSDimitry Andric void setEvaluateConstraints(bool B) {
1357bdd1243dSDimitry Andric EvaluateConstraints = B;
1358bdd1243dSDimitry Andric }
getEvaluateConstraints()1359bdd1243dSDimitry Andric bool getEvaluateConstraints() {
1360bdd1243dSDimitry Andric return EvaluateConstraints;
1361bdd1243dSDimitry Andric }
1362bdd1243dSDimitry Andric
13630b57cec5SDimitry Andric /// Determine whether the given type \p T has already been
13640b57cec5SDimitry Andric /// transformed.
13650b57cec5SDimitry Andric ///
13660b57cec5SDimitry Andric /// For the purposes of template instantiation, a type has already been
13670b57cec5SDimitry Andric /// transformed if it is NULL or if it is not dependent.
13680b57cec5SDimitry Andric bool AlreadyTransformed(QualType T);
13690b57cec5SDimitry Andric
13700b57cec5SDimitry Andric /// Returns the location of the entity being instantiated, if known.
getBaseLocation()13710b57cec5SDimitry Andric SourceLocation getBaseLocation() { return Loc; }
13720b57cec5SDimitry Andric
13730b57cec5SDimitry Andric /// Returns the name of the entity being instantiated, if any.
getBaseEntity()13740b57cec5SDimitry Andric DeclarationName getBaseEntity() { return Entity; }
13750b57cec5SDimitry Andric
13760b57cec5SDimitry Andric /// Sets the "base" location and entity when that
13770b57cec5SDimitry Andric /// information is known based on another transformation.
setBase(SourceLocation Loc,DeclarationName Entity)13780b57cec5SDimitry Andric void setBase(SourceLocation Loc, DeclarationName Entity) {
13790b57cec5SDimitry Andric this->Loc = Loc;
13800b57cec5SDimitry Andric this->Entity = Entity;
13810b57cec5SDimitry Andric }
13820b57cec5SDimitry Andric
TransformTemplateDepth(unsigned Depth)1383cd675bb6SDimitry Andric unsigned TransformTemplateDepth(unsigned Depth) {
1384cd675bb6SDimitry Andric return TemplateArgs.getNewDepth(Depth);
1385cd675bb6SDimitry Andric }
1386cd675bb6SDimitry Andric
getPackIndex(TemplateArgument Pack)1387bdd1243dSDimitry Andric std::optional<unsigned> getPackIndex(TemplateArgument Pack) {
1388bdd1243dSDimitry Andric int Index = getSema().ArgumentPackSubstitutionIndex;
1389bdd1243dSDimitry Andric if (Index == -1)
1390bdd1243dSDimitry Andric return std::nullopt;
1391bdd1243dSDimitry Andric return Pack.pack_size() - 1 - Index;
1392bdd1243dSDimitry Andric }
1393bdd1243dSDimitry Andric
TryExpandParameterPacks(SourceLocation EllipsisLoc,SourceRange PatternRange,ArrayRef<UnexpandedParameterPack> Unexpanded,bool & ShouldExpand,bool & RetainExpansion,std::optional<unsigned> & NumExpansions)13940b57cec5SDimitry Andric bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
13950b57cec5SDimitry Andric SourceRange PatternRange,
13960b57cec5SDimitry Andric ArrayRef<UnexpandedParameterPack> Unexpanded,
13970b57cec5SDimitry Andric bool &ShouldExpand, bool &RetainExpansion,
1398bdd1243dSDimitry Andric std::optional<unsigned> &NumExpansions) {
13990b57cec5SDimitry Andric return getSema().CheckParameterPacksForExpansion(EllipsisLoc,
14000b57cec5SDimitry Andric PatternRange, Unexpanded,
14010b57cec5SDimitry Andric TemplateArgs,
14020b57cec5SDimitry Andric ShouldExpand,
14030b57cec5SDimitry Andric RetainExpansion,
14040b57cec5SDimitry Andric NumExpansions);
14050b57cec5SDimitry Andric }
14060b57cec5SDimitry Andric
ExpandingFunctionParameterPack(ParmVarDecl * Pack)14070b57cec5SDimitry Andric void ExpandingFunctionParameterPack(ParmVarDecl *Pack) {
14080b57cec5SDimitry Andric SemaRef.CurrentInstantiationScope->MakeInstantiatedLocalArgPack(Pack);
14090b57cec5SDimitry Andric }
14100b57cec5SDimitry Andric
ForgetPartiallySubstitutedPack()14110b57cec5SDimitry Andric TemplateArgument ForgetPartiallySubstitutedPack() {
14120b57cec5SDimitry Andric TemplateArgument Result;
14130b57cec5SDimitry Andric if (NamedDecl *PartialPack
14140b57cec5SDimitry Andric = SemaRef.CurrentInstantiationScope->getPartiallySubstitutedPack()){
14150b57cec5SDimitry Andric MultiLevelTemplateArgumentList &TemplateArgs
14160b57cec5SDimitry Andric = const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs);
14170b57cec5SDimitry Andric unsigned Depth, Index;
14180b57cec5SDimitry Andric std::tie(Depth, Index) = getDepthAndIndex(PartialPack);
14190b57cec5SDimitry Andric if (TemplateArgs.hasTemplateArgument(Depth, Index)) {
14200b57cec5SDimitry Andric Result = TemplateArgs(Depth, Index);
14210b57cec5SDimitry Andric TemplateArgs.setArgument(Depth, Index, TemplateArgument());
14220b57cec5SDimitry Andric }
14230b57cec5SDimitry Andric }
14240b57cec5SDimitry Andric
14250b57cec5SDimitry Andric return Result;
14260b57cec5SDimitry Andric }
14270b57cec5SDimitry Andric
RememberPartiallySubstitutedPack(TemplateArgument Arg)14280b57cec5SDimitry Andric void RememberPartiallySubstitutedPack(TemplateArgument Arg) {
14290b57cec5SDimitry Andric if (Arg.isNull())
14300b57cec5SDimitry Andric return;
14310b57cec5SDimitry Andric
14320b57cec5SDimitry Andric if (NamedDecl *PartialPack
14330b57cec5SDimitry Andric = SemaRef.CurrentInstantiationScope->getPartiallySubstitutedPack()){
14340b57cec5SDimitry Andric MultiLevelTemplateArgumentList &TemplateArgs
14350b57cec5SDimitry Andric = const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs);
14360b57cec5SDimitry Andric unsigned Depth, Index;
14370b57cec5SDimitry Andric std::tie(Depth, Index) = getDepthAndIndex(PartialPack);
14380b57cec5SDimitry Andric TemplateArgs.setArgument(Depth, Index, Arg);
14390b57cec5SDimitry Andric }
14400b57cec5SDimitry Andric }
14410b57cec5SDimitry Andric
14420b57cec5SDimitry Andric /// Transform the given declaration by instantiating a reference to
14430b57cec5SDimitry Andric /// this declaration.
14440b57cec5SDimitry Andric Decl *TransformDecl(SourceLocation Loc, Decl *D);
14450b57cec5SDimitry Andric
transformAttrs(Decl * Old,Decl * New)14460b57cec5SDimitry Andric void transformAttrs(Decl *Old, Decl *New) {
14470b57cec5SDimitry Andric SemaRef.InstantiateAttrs(TemplateArgs, Old, New);
14480b57cec5SDimitry Andric }
14490b57cec5SDimitry Andric
transformedLocalDecl(Decl * Old,ArrayRef<Decl * > NewDecls)14500b57cec5SDimitry Andric void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> NewDecls) {
14510b57cec5SDimitry Andric if (Old->isParameterPack()) {
14520b57cec5SDimitry Andric SemaRef.CurrentInstantiationScope->MakeInstantiatedLocalArgPack(Old);
14530b57cec5SDimitry Andric for (auto *New : NewDecls)
14540b57cec5SDimitry Andric SemaRef.CurrentInstantiationScope->InstantiatedLocalPackArg(
14550b57cec5SDimitry Andric Old, cast<VarDecl>(New));
14560b57cec5SDimitry Andric return;
14570b57cec5SDimitry Andric }
14580b57cec5SDimitry Andric
14590b57cec5SDimitry Andric assert(NewDecls.size() == 1 &&
14600b57cec5SDimitry Andric "should only have multiple expansions for a pack");
14610b57cec5SDimitry Andric Decl *New = NewDecls.front();
14620b57cec5SDimitry Andric
14630b57cec5SDimitry Andric // If we've instantiated the call operator of a lambda or the call
14640b57cec5SDimitry Andric // operator template of a generic lambda, update the "instantiation of"
14650b57cec5SDimitry Andric // information.
14660b57cec5SDimitry Andric auto *NewMD = dyn_cast<CXXMethodDecl>(New);
14670b57cec5SDimitry Andric if (NewMD && isLambdaCallOperator(NewMD)) {
14680b57cec5SDimitry Andric auto *OldMD = dyn_cast<CXXMethodDecl>(Old);
14690b57cec5SDimitry Andric if (auto *NewTD = NewMD->getDescribedFunctionTemplate())
14700b57cec5SDimitry Andric NewTD->setInstantiatedFromMemberTemplate(
14710b57cec5SDimitry Andric OldMD->getDescribedFunctionTemplate());
14720b57cec5SDimitry Andric else
14730b57cec5SDimitry Andric NewMD->setInstantiationOfMemberFunction(OldMD,
14740b57cec5SDimitry Andric TSK_ImplicitInstantiation);
14750b57cec5SDimitry Andric }
14760b57cec5SDimitry Andric
14770b57cec5SDimitry Andric SemaRef.CurrentInstantiationScope->InstantiatedLocal(Old, New);
14780b57cec5SDimitry Andric
14790b57cec5SDimitry Andric // We recreated a local declaration, but not by instantiating it. There
14800b57cec5SDimitry Andric // may be pending dependent diagnostics to produce.
148106c3fb27SDimitry Andric if (auto *DC = dyn_cast<DeclContext>(Old);
148206c3fb27SDimitry Andric DC && DC->isDependentContext() && DC->isFunctionOrMethod())
14830b57cec5SDimitry Andric SemaRef.PerformDependentDiagnostics(DC, TemplateArgs);
14840b57cec5SDimitry Andric }
14850b57cec5SDimitry Andric
14860b57cec5SDimitry Andric /// Transform the definition of the given declaration by
14870b57cec5SDimitry Andric /// instantiating it.
14880b57cec5SDimitry Andric Decl *TransformDefinition(SourceLocation Loc, Decl *D);
14890b57cec5SDimitry Andric
14900b57cec5SDimitry Andric /// Transform the first qualifier within a scope by instantiating the
14910b57cec5SDimitry Andric /// declaration.
14920b57cec5SDimitry Andric NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc);
14930b57cec5SDimitry Andric
14945f757f3fSDimitry Andric bool TransformExceptionSpec(SourceLocation Loc,
14955f757f3fSDimitry Andric FunctionProtoType::ExceptionSpecInfo &ESI,
14965f757f3fSDimitry Andric SmallVectorImpl<QualType> &Exceptions,
14975f757f3fSDimitry Andric bool &Changed);
14985f757f3fSDimitry Andric
14990b57cec5SDimitry Andric /// Rebuild the exception declaration and register the declaration
15000b57cec5SDimitry Andric /// as an instantiated local.
15010b57cec5SDimitry Andric VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
15020b57cec5SDimitry Andric TypeSourceInfo *Declarator,
15030b57cec5SDimitry Andric SourceLocation StartLoc,
15040b57cec5SDimitry Andric SourceLocation NameLoc,
15050b57cec5SDimitry Andric IdentifierInfo *Name);
15060b57cec5SDimitry Andric
15070b57cec5SDimitry Andric /// Rebuild the Objective-C exception declaration and register the
15080b57cec5SDimitry Andric /// declaration as an instantiated local.
15090b57cec5SDimitry Andric VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
15100b57cec5SDimitry Andric TypeSourceInfo *TSInfo, QualType T);
15110b57cec5SDimitry Andric
15120b57cec5SDimitry Andric /// Check for tag mismatches when instantiating an
15130b57cec5SDimitry Andric /// elaborated type.
15140b57cec5SDimitry Andric QualType RebuildElaboratedType(SourceLocation KeywordLoc,
15150b57cec5SDimitry Andric ElaboratedTypeKeyword Keyword,
15160b57cec5SDimitry Andric NestedNameSpecifierLoc QualifierLoc,
15170b57cec5SDimitry Andric QualType T);
15180b57cec5SDimitry Andric
15190b57cec5SDimitry Andric TemplateName
15200b57cec5SDimitry Andric TransformTemplateName(CXXScopeSpec &SS, TemplateName Name,
15210b57cec5SDimitry Andric SourceLocation NameLoc,
15220b57cec5SDimitry Andric QualType ObjectType = QualType(),
15230b57cec5SDimitry Andric NamedDecl *FirstQualifierInScope = nullptr,
15240b57cec5SDimitry Andric bool AllowInjectedClassName = false);
15250b57cec5SDimitry Andric
15260fca6ea1SDimitry Andric const CXXAssumeAttr *TransformCXXAssumeAttr(const CXXAssumeAttr *AA);
15270b57cec5SDimitry Andric const LoopHintAttr *TransformLoopHintAttr(const LoopHintAttr *LH);
152806c3fb27SDimitry Andric const NoInlineAttr *TransformStmtNoInlineAttr(const Stmt *OrigS,
152906c3fb27SDimitry Andric const Stmt *InstS,
153006c3fb27SDimitry Andric const NoInlineAttr *A);
153106c3fb27SDimitry Andric const AlwaysInlineAttr *
153206c3fb27SDimitry Andric TransformStmtAlwaysInlineAttr(const Stmt *OrigS, const Stmt *InstS,
153306c3fb27SDimitry Andric const AlwaysInlineAttr *A);
15345f757f3fSDimitry Andric const CodeAlignAttr *TransformCodeAlignAttr(const CodeAlignAttr *CA);
15350b57cec5SDimitry Andric ExprResult TransformPredefinedExpr(PredefinedExpr *E);
15360b57cec5SDimitry Andric ExprResult TransformDeclRefExpr(DeclRefExpr *E);
15370b57cec5SDimitry Andric ExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E);
15380b57cec5SDimitry Andric
15390b57cec5SDimitry Andric ExprResult TransformTemplateParmRefExpr(DeclRefExpr *E,
15400b57cec5SDimitry Andric NonTypeTemplateParmDecl *D);
15410b57cec5SDimitry Andric ExprResult TransformSubstNonTypeTemplateParmPackExpr(
15420b57cec5SDimitry Andric SubstNonTypeTemplateParmPackExpr *E);
154313138422SDimitry Andric ExprResult TransformSubstNonTypeTemplateParmExpr(
154413138422SDimitry Andric SubstNonTypeTemplateParmExpr *E);
15450b57cec5SDimitry Andric
15460b57cec5SDimitry Andric /// Rebuild a DeclRefExpr for a VarDecl reference.
15470b57cec5SDimitry Andric ExprResult RebuildVarDeclRefExpr(VarDecl *PD, SourceLocation Loc);
15480b57cec5SDimitry Andric
15490b57cec5SDimitry Andric /// Transform a reference to a function or init-capture parameter pack.
15500b57cec5SDimitry Andric ExprResult TransformFunctionParmPackRefExpr(DeclRefExpr *E, VarDecl *PD);
15510b57cec5SDimitry Andric
15520b57cec5SDimitry Andric /// Transform a FunctionParmPackExpr which was built when we couldn't
15530b57cec5SDimitry Andric /// expand a function parameter pack reference which refers to an expanded
15540b57cec5SDimitry Andric /// pack.
15550b57cec5SDimitry Andric ExprResult TransformFunctionParmPackExpr(FunctionParmPackExpr *E);
15560b57cec5SDimitry Andric
TransformFunctionProtoType(TypeLocBuilder & TLB,FunctionProtoTypeLoc TL)15570b57cec5SDimitry Andric QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
15580b57cec5SDimitry Andric FunctionProtoTypeLoc TL) {
15590b57cec5SDimitry Andric // Call the base version; it will forward to our overridden version below.
15600b57cec5SDimitry Andric return inherited::TransformFunctionProtoType(TLB, TL);
15610b57cec5SDimitry Andric }
15620b57cec5SDimitry Andric
TransformInjectedClassNameType(TypeLocBuilder & TLB,InjectedClassNameTypeLoc TL)15630fca6ea1SDimitry Andric QualType TransformInjectedClassNameType(TypeLocBuilder &TLB,
15640fca6ea1SDimitry Andric InjectedClassNameTypeLoc TL) {
15650fca6ea1SDimitry Andric auto Type = inherited::TransformInjectedClassNameType(TLB, TL);
15660fca6ea1SDimitry Andric // Special case for transforming a deduction guide, we return a
15670fca6ea1SDimitry Andric // transformed TemplateSpecializationType.
15680fca6ea1SDimitry Andric if (Type.isNull() &&
15690fca6ea1SDimitry Andric SemaRef.CodeSynthesisContexts.back().Kind ==
15700fca6ea1SDimitry Andric Sema::CodeSynthesisContext::BuildingDeductionGuides) {
15710fca6ea1SDimitry Andric // Return a TemplateSpecializationType for transforming a deduction
15720fca6ea1SDimitry Andric // guide.
15730fca6ea1SDimitry Andric if (auto *ICT = TL.getType()->getAs<InjectedClassNameType>()) {
15740fca6ea1SDimitry Andric auto Type =
15750fca6ea1SDimitry Andric inherited::TransformType(ICT->getInjectedSpecializationType());
15760fca6ea1SDimitry Andric TLB.pushTrivial(SemaRef.Context, Type, TL.getNameLoc());
15770fca6ea1SDimitry Andric return Type;
15780fca6ea1SDimitry Andric }
15790fca6ea1SDimitry Andric }
15800fca6ea1SDimitry Andric return Type;
15810fca6ea1SDimitry Andric }
15820fca6ea1SDimitry Andric // Override the default version to handle a rewrite-template-arg-pack case
15830fca6ea1SDimitry Andric // for building a deduction guide.
TransformTemplateArgument(const TemplateArgumentLoc & Input,TemplateArgumentLoc & Output,bool Uneval=false)15840fca6ea1SDimitry Andric bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
15850fca6ea1SDimitry Andric TemplateArgumentLoc &Output,
15860fca6ea1SDimitry Andric bool Uneval = false) {
15870fca6ea1SDimitry Andric const TemplateArgument &Arg = Input.getArgument();
15880fca6ea1SDimitry Andric std::vector<TemplateArgument> TArgs;
15890fca6ea1SDimitry Andric switch (Arg.getKind()) {
15900fca6ea1SDimitry Andric case TemplateArgument::Pack:
15910fca6ea1SDimitry Andric // Literally rewrite the template argument pack, instead of unpacking
15920fca6ea1SDimitry Andric // it.
15930fca6ea1SDimitry Andric for (auto &pack : Arg.getPackAsArray()) {
15940fca6ea1SDimitry Andric TemplateArgumentLoc Input = SemaRef.getTrivialTemplateArgumentLoc(
15950fca6ea1SDimitry Andric pack, QualType(), SourceLocation{});
15960fca6ea1SDimitry Andric TemplateArgumentLoc Output;
15970fca6ea1SDimitry Andric if (SemaRef.SubstTemplateArgument(Input, TemplateArgs, Output))
15980fca6ea1SDimitry Andric return true; // fails
15990fca6ea1SDimitry Andric TArgs.push_back(Output.getArgument());
16000fca6ea1SDimitry Andric }
16010fca6ea1SDimitry Andric Output = SemaRef.getTrivialTemplateArgumentLoc(
16020fca6ea1SDimitry Andric TemplateArgument(llvm::ArrayRef(TArgs).copy(SemaRef.Context)),
16030fca6ea1SDimitry Andric QualType(), SourceLocation{});
16040fca6ea1SDimitry Andric return false;
16050fca6ea1SDimitry Andric default:
16060fca6ea1SDimitry Andric break;
16070fca6ea1SDimitry Andric }
16080fca6ea1SDimitry Andric return inherited::TransformTemplateArgument(Input, Output, Uneval);
16090fca6ea1SDimitry Andric }
16100fca6ea1SDimitry Andric
16110b57cec5SDimitry Andric template<typename Fn>
16120b57cec5SDimitry Andric QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
16130b57cec5SDimitry Andric FunctionProtoTypeLoc TL,
16140b57cec5SDimitry Andric CXXRecordDecl *ThisContext,
16150b57cec5SDimitry Andric Qualifiers ThisTypeQuals,
16160b57cec5SDimitry Andric Fn TransformExceptionSpec);
16170b57cec5SDimitry Andric
1618bdd1243dSDimitry Andric ParmVarDecl *
1619bdd1243dSDimitry Andric TransformFunctionTypeParam(ParmVarDecl *OldParm, int indexAdjustment,
1620bdd1243dSDimitry Andric std::optional<unsigned> NumExpansions,
16210b57cec5SDimitry Andric bool ExpectParameterPack);
16220b57cec5SDimitry Andric
1623bdd1243dSDimitry Andric using inherited::TransformTemplateTypeParmType;
16240b57cec5SDimitry Andric /// Transforms a template type parameter type by performing
16250b57cec5SDimitry Andric /// substitution of the corresponding template type argument.
16260b57cec5SDimitry Andric QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
1627bdd1243dSDimitry Andric TemplateTypeParmTypeLoc TL,
1628bdd1243dSDimitry Andric bool SuppressObjCLifetime);
1629bdd1243dSDimitry Andric
1630bdd1243dSDimitry Andric QualType BuildSubstTemplateTypeParmType(
1631bdd1243dSDimitry Andric TypeLocBuilder &TLB, bool SuppressObjCLifetime, bool Final,
1632bdd1243dSDimitry Andric Decl *AssociatedDecl, unsigned Index, std::optional<unsigned> PackIndex,
1633bdd1243dSDimitry Andric TemplateArgument Arg, SourceLocation NameLoc);
16340b57cec5SDimitry Andric
16350b57cec5SDimitry Andric /// Transforms an already-substituted template type parameter pack
16360b57cec5SDimitry Andric /// into either itself (if we aren't substituting into its pack expansion)
16370b57cec5SDimitry Andric /// or the appropriate substituted argument.
1638bdd1243dSDimitry Andric using inherited::TransformSubstTemplateTypeParmPackType;
1639bdd1243dSDimitry Andric QualType
1640bdd1243dSDimitry Andric TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB,
1641bdd1243dSDimitry Andric SubstTemplateTypeParmPackTypeLoc TL,
1642bdd1243dSDimitry Andric bool SuppressObjCLifetime);
16430b57cec5SDimitry Andric
16440fca6ea1SDimitry Andric CXXRecordDecl::LambdaDependencyKind
ComputeLambdaDependency(LambdaScopeInfo * LSI)16450fca6ea1SDimitry Andric ComputeLambdaDependency(LambdaScopeInfo *LSI) {
16466c4b055cSDimitry Andric if (auto TypeAlias =
16476c4b055cSDimitry Andric TemplateInstArgsHelpers::getEnclosingTypeAliasTemplateDecl(
16486c4b055cSDimitry Andric getSema());
16496c4b055cSDimitry Andric TypeAlias && TemplateInstArgsHelpers::isLambdaEnclosedByTypeAliasDecl(
16506c4b055cSDimitry Andric LSI->CallOperator, TypeAlias.PrimaryTypeAliasDecl)) {
16516c4b055cSDimitry Andric unsigned TypeAliasDeclDepth = TypeAlias.Template->getTemplateDepth();
16520fca6ea1SDimitry Andric if (TypeAliasDeclDepth >= TemplateArgs.getNumSubstitutedLevels())
16530fca6ea1SDimitry Andric return CXXRecordDecl::LambdaDependencyKind::LDK_AlwaysDependent;
16546c4b055cSDimitry Andric for (const TemplateArgument &TA : TypeAlias.AssociatedTemplateArguments)
16556c4b055cSDimitry Andric if (TA.isDependent())
16566c4b055cSDimitry Andric return CXXRecordDecl::LambdaDependencyKind::LDK_AlwaysDependent;
16570fca6ea1SDimitry Andric }
16580fca6ea1SDimitry Andric return inherited::ComputeLambdaDependency(LSI);
16590fca6ea1SDimitry Andric }
16600fca6ea1SDimitry Andric
TransformLambdaExpr(LambdaExpr * E)16610b57cec5SDimitry Andric ExprResult TransformLambdaExpr(LambdaExpr *E) {
16620b57cec5SDimitry Andric LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
1663bdd1243dSDimitry Andric Sema::ConstraintEvalRAII<TemplateInstantiator> RAII(*this);
166406c3fb27SDimitry Andric
1665bdd1243dSDimitry Andric ExprResult Result = inherited::TransformLambdaExpr(E);
1666bdd1243dSDimitry Andric if (Result.isInvalid())
1667bdd1243dSDimitry Andric return Result;
1668bdd1243dSDimitry Andric
1669bdd1243dSDimitry Andric CXXMethodDecl *MD = Result.getAs<LambdaExpr>()->getCallOperator();
1670bdd1243dSDimitry Andric for (ParmVarDecl *PVD : MD->parameters()) {
167106c3fb27SDimitry Andric assert(PVD && "null in a parameter list");
1672bdd1243dSDimitry Andric if (!PVD->hasDefaultArg())
1673bdd1243dSDimitry Andric continue;
1674bdd1243dSDimitry Andric Expr *UninstExpr = PVD->getUninstantiatedDefaultArg();
1675bdd1243dSDimitry Andric // FIXME: Obtain the source location for the '=' token.
1676bdd1243dSDimitry Andric SourceLocation EqualLoc = UninstExpr->getBeginLoc();
1677bdd1243dSDimitry Andric if (SemaRef.SubstDefaultArgument(EqualLoc, PVD, TemplateArgs)) {
1678bdd1243dSDimitry Andric // If substitution fails, the default argument is set to a
1679bdd1243dSDimitry Andric // RecoveryExpr that wraps the uninstantiated default argument so
1680bdd1243dSDimitry Andric // that downstream diagnostics are omitted.
1681bdd1243dSDimitry Andric ExprResult ErrorResult = SemaRef.CreateRecoveryExpr(
1682bdd1243dSDimitry Andric UninstExpr->getBeginLoc(), UninstExpr->getEndLoc(),
1683bdd1243dSDimitry Andric { UninstExpr }, UninstExpr->getType());
1684bdd1243dSDimitry Andric if (ErrorResult.isUsable())
1685bdd1243dSDimitry Andric PVD->setDefaultArg(ErrorResult.get());
1686bdd1243dSDimitry Andric }
1687bdd1243dSDimitry Andric }
1688bdd1243dSDimitry Andric
1689bdd1243dSDimitry Andric return Result;
16900b57cec5SDimitry Andric }
16910b57cec5SDimitry Andric
TransformLambdaBody(LambdaExpr * E,Stmt * Body)16921db9f3b2SDimitry Andric StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body) {
16931db9f3b2SDimitry Andric // Currently, we instantiate the body when instantiating the lambda
16941db9f3b2SDimitry Andric // expression. However, `EvaluateConstraints` is disabled during the
16951db9f3b2SDimitry Andric // instantiation of the lambda expression, causing the instantiation
16961db9f3b2SDimitry Andric // failure of the return type requirement in the body. If p0588r1 is fully
16971db9f3b2SDimitry Andric // implemented, the body will be lazily instantiated, and this problem
16981db9f3b2SDimitry Andric // will not occur. Here, `EvaluateConstraints` is temporarily set to
16991db9f3b2SDimitry Andric // `true` to temporarily fix this issue.
17001db9f3b2SDimitry Andric // FIXME: This temporary fix can be removed after fully implementing
17011db9f3b2SDimitry Andric // p0588r1.
17021db9f3b2SDimitry Andric bool Prev = EvaluateConstraints;
17031db9f3b2SDimitry Andric EvaluateConstraints = true;
17041db9f3b2SDimitry Andric StmtResult Stmt = inherited::TransformLambdaBody(E, Body);
17051db9f3b2SDimitry Andric EvaluateConstraints = Prev;
17061db9f3b2SDimitry Andric return Stmt;
17071db9f3b2SDimitry Andric }
17081db9f3b2SDimitry Andric
TransformRequiresExpr(RequiresExpr * E)170955e4f9d5SDimitry Andric ExprResult TransformRequiresExpr(RequiresExpr *E) {
171055e4f9d5SDimitry Andric LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
1711bdd1243dSDimitry Andric ExprResult TransReq = inherited::TransformRequiresExpr(E);
1712bdd1243dSDimitry Andric if (TransReq.isInvalid())
1713bdd1243dSDimitry Andric return TransReq;
1714bdd1243dSDimitry Andric assert(TransReq.get() != E &&
1715bdd1243dSDimitry Andric "Do not change value of isSatisfied for the existing expression. "
1716bdd1243dSDimitry Andric "Create a new expression instead.");
1717bdd1243dSDimitry Andric if (E->getBody()->isDependentContext()) {
1718bdd1243dSDimitry Andric Sema::SFINAETrap Trap(SemaRef);
1719bdd1243dSDimitry Andric // We recreate the RequiresExpr body, but not by instantiating it.
1720bdd1243dSDimitry Andric // Produce pending diagnostics for dependent access check.
1721bdd1243dSDimitry Andric SemaRef.PerformDependentDiagnostics(E->getBody(), TemplateArgs);
1722bdd1243dSDimitry Andric // FIXME: Store SFINAE diagnostics in RequiresExpr for diagnosis.
1723bdd1243dSDimitry Andric if (Trap.hasErrorOccurred())
1724bdd1243dSDimitry Andric TransReq.getAs<RequiresExpr>()->setSatisfied(false);
1725bdd1243dSDimitry Andric }
1726bdd1243dSDimitry Andric return TransReq;
172755e4f9d5SDimitry Andric }
172855e4f9d5SDimitry Andric
TransformRequiresExprRequirements(ArrayRef<concepts::Requirement * > Reqs,SmallVectorImpl<concepts::Requirement * > & Transformed)172955e4f9d5SDimitry Andric bool TransformRequiresExprRequirements(
173055e4f9d5SDimitry Andric ArrayRef<concepts::Requirement *> Reqs,
173155e4f9d5SDimitry Andric SmallVectorImpl<concepts::Requirement *> &Transformed) {
173255e4f9d5SDimitry Andric bool SatisfactionDetermined = false;
173355e4f9d5SDimitry Andric for (concepts::Requirement *Req : Reqs) {
173455e4f9d5SDimitry Andric concepts::Requirement *TransReq = nullptr;
173555e4f9d5SDimitry Andric if (!SatisfactionDetermined) {
173655e4f9d5SDimitry Andric if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req))
173755e4f9d5SDimitry Andric TransReq = TransformTypeRequirement(TypeReq);
173855e4f9d5SDimitry Andric else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req))
173955e4f9d5SDimitry Andric TransReq = TransformExprRequirement(ExprReq);
174055e4f9d5SDimitry Andric else
174155e4f9d5SDimitry Andric TransReq = TransformNestedRequirement(
174255e4f9d5SDimitry Andric cast<concepts::NestedRequirement>(Req));
174355e4f9d5SDimitry Andric if (!TransReq)
174455e4f9d5SDimitry Andric return true;
174555e4f9d5SDimitry Andric if (!TransReq->isDependent() && !TransReq->isSatisfied())
174655e4f9d5SDimitry Andric // [expr.prim.req]p6
174755e4f9d5SDimitry Andric // [...] The substitution and semantic constraint checking
174855e4f9d5SDimitry Andric // proceeds in lexical order and stops when a condition that
174955e4f9d5SDimitry Andric // determines the result of the requires-expression is
175055e4f9d5SDimitry Andric // encountered. [..]
175155e4f9d5SDimitry Andric SatisfactionDetermined = true;
175255e4f9d5SDimitry Andric } else
175355e4f9d5SDimitry Andric TransReq = Req;
175455e4f9d5SDimitry Andric Transformed.push_back(TransReq);
175555e4f9d5SDimitry Andric }
175655e4f9d5SDimitry Andric return false;
175755e4f9d5SDimitry Andric }
175855e4f9d5SDimitry Andric
TransformTemplateParameterList(TemplateParameterList * OrigTPL)17590b57cec5SDimitry Andric TemplateParameterList *TransformTemplateParameterList(
17600b57cec5SDimitry Andric TemplateParameterList *OrigTPL) {
17610b57cec5SDimitry Andric if (!OrigTPL || !OrigTPL->size()) return OrigTPL;
17620b57cec5SDimitry Andric
17630b57cec5SDimitry Andric DeclContext *Owner = OrigTPL->getParam(0)->getDeclContext();
17640b57cec5SDimitry Andric TemplateDeclInstantiator DeclInstantiator(getSema(),
17650b57cec5SDimitry Andric /* DeclContext *Owner */ Owner, TemplateArgs);
1766bdd1243dSDimitry Andric DeclInstantiator.setEvaluateConstraints(EvaluateConstraints);
17670b57cec5SDimitry Andric return DeclInstantiator.SubstTemplateParams(OrigTPL);
17680b57cec5SDimitry Andric }
176955e4f9d5SDimitry Andric
177055e4f9d5SDimitry Andric concepts::TypeRequirement *
177155e4f9d5SDimitry Andric TransformTypeRequirement(concepts::TypeRequirement *Req);
177255e4f9d5SDimitry Andric concepts::ExprRequirement *
177355e4f9d5SDimitry Andric TransformExprRequirement(concepts::ExprRequirement *Req);
177455e4f9d5SDimitry Andric concepts::NestedRequirement *
177555e4f9d5SDimitry Andric TransformNestedRequirement(concepts::NestedRequirement *Req);
1776bdd1243dSDimitry Andric ExprResult TransformRequiresTypeParams(
1777bdd1243dSDimitry Andric SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
1778bdd1243dSDimitry Andric RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,
1779bdd1243dSDimitry Andric SmallVectorImpl<QualType> &PTypes,
1780bdd1243dSDimitry Andric SmallVectorImpl<ParmVarDecl *> &TransParams,
1781bdd1243dSDimitry Andric Sema::ExtParameterInfoBuilder &PInfos);
178255e4f9d5SDimitry Andric
17830b57cec5SDimitry Andric private:
1784bdd1243dSDimitry Andric ExprResult
1785bdd1243dSDimitry Andric transformNonTypeTemplateParmRef(Decl *AssociatedDecl,
1786bdd1243dSDimitry Andric const NonTypeTemplateParmDecl *parm,
1787bdd1243dSDimitry Andric SourceLocation loc, TemplateArgument arg,
1788bdd1243dSDimitry Andric std::optional<unsigned> PackIndex);
17890b57cec5SDimitry Andric };
17900b57cec5SDimitry Andric }
17910b57cec5SDimitry Andric
AlreadyTransformed(QualType T)17920b57cec5SDimitry Andric bool TemplateInstantiator::AlreadyTransformed(QualType T) {
17930b57cec5SDimitry Andric if (T.isNull())
17940b57cec5SDimitry Andric return true;
17950b57cec5SDimitry Andric
17960b57cec5SDimitry Andric if (T->isInstantiationDependentType() || T->isVariablyModifiedType())
17970b57cec5SDimitry Andric return false;
17980b57cec5SDimitry Andric
17990b57cec5SDimitry Andric getSema().MarkDeclarationsReferencedInType(Loc, T);
18000b57cec5SDimitry Andric return true;
18010b57cec5SDimitry Andric }
18020b57cec5SDimitry Andric
18030b57cec5SDimitry Andric static TemplateArgument
getPackSubstitutedTemplateArgument(Sema & S,TemplateArgument Arg)18040b57cec5SDimitry Andric getPackSubstitutedTemplateArgument(Sema &S, TemplateArgument Arg) {
18050b57cec5SDimitry Andric assert(S.ArgumentPackSubstitutionIndex >= 0);
18060b57cec5SDimitry Andric assert(S.ArgumentPackSubstitutionIndex < (int)Arg.pack_size());
18070b57cec5SDimitry Andric Arg = Arg.pack_begin()[S.ArgumentPackSubstitutionIndex];
18080b57cec5SDimitry Andric if (Arg.isPackExpansion())
18090b57cec5SDimitry Andric Arg = Arg.getPackExpansionPattern();
18100b57cec5SDimitry Andric return Arg;
18110b57cec5SDimitry Andric }
18120b57cec5SDimitry Andric
TransformDecl(SourceLocation Loc,Decl * D)18130b57cec5SDimitry Andric Decl *TemplateInstantiator::TransformDecl(SourceLocation Loc, Decl *D) {
18140b57cec5SDimitry Andric if (!D)
18150b57cec5SDimitry Andric return nullptr;
18160b57cec5SDimitry Andric
18170b57cec5SDimitry Andric if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(D)) {
18180b57cec5SDimitry Andric if (TTP->getDepth() < TemplateArgs.getNumLevels()) {
18190b57cec5SDimitry Andric // If the corresponding template argument is NULL or non-existent, it's
18200b57cec5SDimitry Andric // because we are performing instantiation from explicitly-specified
18210b57cec5SDimitry Andric // template arguments in a function template, but there were some
18220b57cec5SDimitry Andric // arguments left unspecified.
18230b57cec5SDimitry Andric if (!TemplateArgs.hasTemplateArgument(TTP->getDepth(),
18240b57cec5SDimitry Andric TTP->getPosition()))
18250b57cec5SDimitry Andric return D;
18260b57cec5SDimitry Andric
18270b57cec5SDimitry Andric TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getPosition());
18280b57cec5SDimitry Andric
18290b57cec5SDimitry Andric if (TTP->isParameterPack()) {
18300b57cec5SDimitry Andric assert(Arg.getKind() == TemplateArgument::Pack &&
18310b57cec5SDimitry Andric "Missing argument pack");
18320b57cec5SDimitry Andric Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
18330b57cec5SDimitry Andric }
18340b57cec5SDimitry Andric
18350fca6ea1SDimitry Andric TemplateName Template = Arg.getAsTemplate();
18360b57cec5SDimitry Andric assert(!Template.isNull() && Template.getAsTemplateDecl() &&
18370b57cec5SDimitry Andric "Wrong kind of template template argument");
18380b57cec5SDimitry Andric return Template.getAsTemplateDecl();
18390b57cec5SDimitry Andric }
18400b57cec5SDimitry Andric
18410b57cec5SDimitry Andric // Fall through to find the instantiated declaration for this template
18420b57cec5SDimitry Andric // template parameter.
18430b57cec5SDimitry Andric }
18440b57cec5SDimitry Andric
18450b57cec5SDimitry Andric return SemaRef.FindInstantiatedDecl(Loc, cast<NamedDecl>(D), TemplateArgs);
18460b57cec5SDimitry Andric }
18470b57cec5SDimitry Andric
TransformDefinition(SourceLocation Loc,Decl * D)18480b57cec5SDimitry Andric Decl *TemplateInstantiator::TransformDefinition(SourceLocation Loc, Decl *D) {
18490b57cec5SDimitry Andric Decl *Inst = getSema().SubstDecl(D, getSema().CurContext, TemplateArgs);
18500b57cec5SDimitry Andric if (!Inst)
18510b57cec5SDimitry Andric return nullptr;
18520b57cec5SDimitry Andric
18530b57cec5SDimitry Andric getSema().CurrentInstantiationScope->InstantiatedLocal(D, Inst);
18540b57cec5SDimitry Andric return Inst;
18550b57cec5SDimitry Andric }
18560b57cec5SDimitry Andric
TransformExceptionSpec(SourceLocation Loc,FunctionProtoType::ExceptionSpecInfo & ESI,SmallVectorImpl<QualType> & Exceptions,bool & Changed)18575f757f3fSDimitry Andric bool TemplateInstantiator::TransformExceptionSpec(
18585f757f3fSDimitry Andric SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
18595f757f3fSDimitry Andric SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
18605f757f3fSDimitry Andric if (ESI.Type == EST_Uninstantiated) {
18611db9f3b2SDimitry Andric ESI.instantiate();
18625f757f3fSDimitry Andric Changed = true;
18635f757f3fSDimitry Andric }
18645f757f3fSDimitry Andric return inherited::TransformExceptionSpec(Loc, ESI, Exceptions, Changed);
18655f757f3fSDimitry Andric }
18665f757f3fSDimitry Andric
18670b57cec5SDimitry Andric NamedDecl *
TransformFirstQualifierInScope(NamedDecl * D,SourceLocation Loc)18680b57cec5SDimitry Andric TemplateInstantiator::TransformFirstQualifierInScope(NamedDecl *D,
18690b57cec5SDimitry Andric SourceLocation Loc) {
18700b57cec5SDimitry Andric // If the first part of the nested-name-specifier was a template type
18710b57cec5SDimitry Andric // parameter, instantiate that type parameter down to a tag type.
18720b57cec5SDimitry Andric if (TemplateTypeParmDecl *TTPD = dyn_cast_or_null<TemplateTypeParmDecl>(D)) {
18730b57cec5SDimitry Andric const TemplateTypeParmType *TTP
18740b57cec5SDimitry Andric = cast<TemplateTypeParmType>(getSema().Context.getTypeDeclType(TTPD));
18750b57cec5SDimitry Andric
18760b57cec5SDimitry Andric if (TTP->getDepth() < TemplateArgs.getNumLevels()) {
18770b57cec5SDimitry Andric // FIXME: This needs testing w/ member access expressions.
18780b57cec5SDimitry Andric TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getIndex());
18790b57cec5SDimitry Andric
18800b57cec5SDimitry Andric if (TTP->isParameterPack()) {
18810b57cec5SDimitry Andric assert(Arg.getKind() == TemplateArgument::Pack &&
18820b57cec5SDimitry Andric "Missing argument pack");
18830b57cec5SDimitry Andric
18840b57cec5SDimitry Andric if (getSema().ArgumentPackSubstitutionIndex == -1)
18850b57cec5SDimitry Andric return nullptr;
18860b57cec5SDimitry Andric
18870b57cec5SDimitry Andric Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
18880b57cec5SDimitry Andric }
18890b57cec5SDimitry Andric
18900b57cec5SDimitry Andric QualType T = Arg.getAsType();
18910b57cec5SDimitry Andric if (T.isNull())
18920b57cec5SDimitry Andric return cast_or_null<NamedDecl>(TransformDecl(Loc, D));
18930b57cec5SDimitry Andric
18940b57cec5SDimitry Andric if (const TagType *Tag = T->getAs<TagType>())
18950b57cec5SDimitry Andric return Tag->getDecl();
18960b57cec5SDimitry Andric
18970b57cec5SDimitry Andric // The resulting type is not a tag; complain.
18980b57cec5SDimitry Andric getSema().Diag(Loc, diag::err_nested_name_spec_non_tag) << T;
18990b57cec5SDimitry Andric return nullptr;
19000b57cec5SDimitry Andric }
19010b57cec5SDimitry Andric }
19020b57cec5SDimitry Andric
19030b57cec5SDimitry Andric return cast_or_null<NamedDecl>(TransformDecl(Loc, D));
19040b57cec5SDimitry Andric }
19050b57cec5SDimitry Andric
19060b57cec5SDimitry Andric VarDecl *
RebuildExceptionDecl(VarDecl * ExceptionDecl,TypeSourceInfo * Declarator,SourceLocation StartLoc,SourceLocation NameLoc,IdentifierInfo * Name)19070b57cec5SDimitry Andric TemplateInstantiator::RebuildExceptionDecl(VarDecl *ExceptionDecl,
19080b57cec5SDimitry Andric TypeSourceInfo *Declarator,
19090b57cec5SDimitry Andric SourceLocation StartLoc,
19100b57cec5SDimitry Andric SourceLocation NameLoc,
19110b57cec5SDimitry Andric IdentifierInfo *Name) {
19120b57cec5SDimitry Andric VarDecl *Var = inherited::RebuildExceptionDecl(ExceptionDecl, Declarator,
19130b57cec5SDimitry Andric StartLoc, NameLoc, Name);
19140b57cec5SDimitry Andric if (Var)
19150b57cec5SDimitry Andric getSema().CurrentInstantiationScope->InstantiatedLocal(ExceptionDecl, Var);
19160b57cec5SDimitry Andric return Var;
19170b57cec5SDimitry Andric }
19180b57cec5SDimitry Andric
RebuildObjCExceptionDecl(VarDecl * ExceptionDecl,TypeSourceInfo * TSInfo,QualType T)19190b57cec5SDimitry Andric VarDecl *TemplateInstantiator::RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
19200b57cec5SDimitry Andric TypeSourceInfo *TSInfo,
19210b57cec5SDimitry Andric QualType T) {
19220b57cec5SDimitry Andric VarDecl *Var = inherited::RebuildObjCExceptionDecl(ExceptionDecl, TSInfo, T);
19230b57cec5SDimitry Andric if (Var)
19240b57cec5SDimitry Andric getSema().CurrentInstantiationScope->InstantiatedLocal(ExceptionDecl, Var);
19250b57cec5SDimitry Andric return Var;
19260b57cec5SDimitry Andric }
19270b57cec5SDimitry Andric
19280b57cec5SDimitry Andric QualType
RebuildElaboratedType(SourceLocation KeywordLoc,ElaboratedTypeKeyword Keyword,NestedNameSpecifierLoc QualifierLoc,QualType T)19290b57cec5SDimitry Andric TemplateInstantiator::RebuildElaboratedType(SourceLocation KeywordLoc,
19300b57cec5SDimitry Andric ElaboratedTypeKeyword Keyword,
19310b57cec5SDimitry Andric NestedNameSpecifierLoc QualifierLoc,
19320b57cec5SDimitry Andric QualType T) {
19330b57cec5SDimitry Andric if (const TagType *TT = T->getAs<TagType>()) {
19340b57cec5SDimitry Andric TagDecl* TD = TT->getDecl();
19350b57cec5SDimitry Andric
19360b57cec5SDimitry Andric SourceLocation TagLocation = KeywordLoc;
19370b57cec5SDimitry Andric
19380b57cec5SDimitry Andric IdentifierInfo *Id = TD->getIdentifier();
19390b57cec5SDimitry Andric
19400b57cec5SDimitry Andric // TODO: should we even warn on struct/class mismatches for this? Seems
19410b57cec5SDimitry Andric // like it's likely to produce a lot of spurious errors.
19425f757f3fSDimitry Andric if (Id && Keyword != ElaboratedTypeKeyword::None &&
19435f757f3fSDimitry Andric Keyword != ElaboratedTypeKeyword::Typename) {
19440b57cec5SDimitry Andric TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
19450b57cec5SDimitry Andric if (!SemaRef.isAcceptableTagRedeclaration(TD, Kind, /*isDefinition*/false,
19460b57cec5SDimitry Andric TagLocation, Id)) {
19470b57cec5SDimitry Andric SemaRef.Diag(TagLocation, diag::err_use_with_wrong_tag)
19480b57cec5SDimitry Andric << Id
19490b57cec5SDimitry Andric << FixItHint::CreateReplacement(SourceRange(TagLocation),
19500b57cec5SDimitry Andric TD->getKindName());
19510b57cec5SDimitry Andric SemaRef.Diag(TD->getLocation(), diag::note_previous_use);
19520b57cec5SDimitry Andric }
19530b57cec5SDimitry Andric }
19540b57cec5SDimitry Andric }
19550b57cec5SDimitry Andric
195681ad6265SDimitry Andric return inherited::RebuildElaboratedType(KeywordLoc, Keyword, QualifierLoc, T);
19570b57cec5SDimitry Andric }
19580b57cec5SDimitry Andric
TransformTemplateName(CXXScopeSpec & SS,TemplateName Name,SourceLocation NameLoc,QualType ObjectType,NamedDecl * FirstQualifierInScope,bool AllowInjectedClassName)19590b57cec5SDimitry Andric TemplateName TemplateInstantiator::TransformTemplateName(
19600b57cec5SDimitry Andric CXXScopeSpec &SS, TemplateName Name, SourceLocation NameLoc,
19610b57cec5SDimitry Andric QualType ObjectType, NamedDecl *FirstQualifierInScope,
19620b57cec5SDimitry Andric bool AllowInjectedClassName) {
19630b57cec5SDimitry Andric if (TemplateTemplateParmDecl *TTP
19640b57cec5SDimitry Andric = dyn_cast_or_null<TemplateTemplateParmDecl>(Name.getAsTemplateDecl())) {
19650b57cec5SDimitry Andric if (TTP->getDepth() < TemplateArgs.getNumLevels()) {
19660b57cec5SDimitry Andric // If the corresponding template argument is NULL or non-existent, it's
19670b57cec5SDimitry Andric // because we are performing instantiation from explicitly-specified
19680b57cec5SDimitry Andric // template arguments in a function template, but there were some
19690b57cec5SDimitry Andric // arguments left unspecified.
19700b57cec5SDimitry Andric if (!TemplateArgs.hasTemplateArgument(TTP->getDepth(),
19710b57cec5SDimitry Andric TTP->getPosition()))
19720b57cec5SDimitry Andric return Name;
19730b57cec5SDimitry Andric
19740b57cec5SDimitry Andric TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getPosition());
19750b57cec5SDimitry Andric
19765ffd83dbSDimitry Andric if (TemplateArgs.isRewrite()) {
19775ffd83dbSDimitry Andric // We're rewriting the template parameter as a reference to another
19785ffd83dbSDimitry Andric // template parameter.
19795ffd83dbSDimitry Andric if (Arg.getKind() == TemplateArgument::Pack) {
19805ffd83dbSDimitry Andric assert(Arg.pack_size() == 1 && Arg.pack_begin()->isPackExpansion() &&
19815ffd83dbSDimitry Andric "unexpected pack arguments in template rewrite");
19825ffd83dbSDimitry Andric Arg = Arg.pack_begin()->getPackExpansionPattern();
19835ffd83dbSDimitry Andric }
19845ffd83dbSDimitry Andric assert(Arg.getKind() == TemplateArgument::Template &&
19855ffd83dbSDimitry Andric "unexpected nontype template argument kind in template rewrite");
19865ffd83dbSDimitry Andric return Arg.getAsTemplate();
19875ffd83dbSDimitry Andric }
19885ffd83dbSDimitry Andric
1989bdd1243dSDimitry Andric auto [AssociatedDecl, Final] =
1990bdd1243dSDimitry Andric TemplateArgs.getAssociatedDecl(TTP->getDepth());
1991bdd1243dSDimitry Andric std::optional<unsigned> PackIndex;
19920b57cec5SDimitry Andric if (TTP->isParameterPack()) {
19930b57cec5SDimitry Andric assert(Arg.getKind() == TemplateArgument::Pack &&
19940b57cec5SDimitry Andric "Missing argument pack");
19950b57cec5SDimitry Andric
19960b57cec5SDimitry Andric if (getSema().ArgumentPackSubstitutionIndex == -1) {
19970b57cec5SDimitry Andric // We have the template argument pack to substitute, but we're not
19980b57cec5SDimitry Andric // actually expanding the enclosing pack expansion yet. So, just
19990b57cec5SDimitry Andric // keep the entire argument pack.
2000bdd1243dSDimitry Andric return getSema().Context.getSubstTemplateTemplateParmPack(
2001bdd1243dSDimitry Andric Arg, AssociatedDecl, TTP->getIndex(), Final);
20020b57cec5SDimitry Andric }
20030b57cec5SDimitry Andric
2004bdd1243dSDimitry Andric PackIndex = getPackIndex(Arg);
20050b57cec5SDimitry Andric Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
20060b57cec5SDimitry Andric }
20070b57cec5SDimitry Andric
20080fca6ea1SDimitry Andric TemplateName Template = Arg.getAsTemplate();
20090b57cec5SDimitry Andric assert(!Template.isNull() && "Null template template argument");
20100b57cec5SDimitry Andric
2011bdd1243dSDimitry Andric if (Final)
20120b57cec5SDimitry Andric return Template;
2013bdd1243dSDimitry Andric return getSema().Context.getSubstTemplateTemplateParm(
2014bdd1243dSDimitry Andric Template, AssociatedDecl, TTP->getIndex(), PackIndex);
20150b57cec5SDimitry Andric }
20160b57cec5SDimitry Andric }
20170b57cec5SDimitry Andric
20180b57cec5SDimitry Andric if (SubstTemplateTemplateParmPackStorage *SubstPack
20190b57cec5SDimitry Andric = Name.getAsSubstTemplateTemplateParmPack()) {
20200b57cec5SDimitry Andric if (getSema().ArgumentPackSubstitutionIndex == -1)
20210b57cec5SDimitry Andric return Name;
20220b57cec5SDimitry Andric
2023bdd1243dSDimitry Andric TemplateArgument Pack = SubstPack->getArgumentPack();
2024bdd1243dSDimitry Andric TemplateName Template =
2025bdd1243dSDimitry Andric getPackSubstitutedTemplateArgument(getSema(), Pack).getAsTemplate();
2026bdd1243dSDimitry Andric if (SubstPack->getFinal())
2027bdd1243dSDimitry Andric return Template;
2028bdd1243dSDimitry Andric return getSema().Context.getSubstTemplateTemplateParm(
20290fca6ea1SDimitry Andric Template, SubstPack->getAssociatedDecl(), SubstPack->getIndex(),
20300fca6ea1SDimitry Andric getPackIndex(Pack));
20310b57cec5SDimitry Andric }
20320b57cec5SDimitry Andric
20330b57cec5SDimitry Andric return inherited::TransformTemplateName(SS, Name, NameLoc, ObjectType,
20340b57cec5SDimitry Andric FirstQualifierInScope,
20350b57cec5SDimitry Andric AllowInjectedClassName);
20360b57cec5SDimitry Andric }
20370b57cec5SDimitry Andric
20380b57cec5SDimitry Andric ExprResult
TransformPredefinedExpr(PredefinedExpr * E)20390b57cec5SDimitry Andric TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) {
20400b57cec5SDimitry Andric if (!E->isTypeDependent())
20410b57cec5SDimitry Andric return E;
20420b57cec5SDimitry Andric
20430b57cec5SDimitry Andric return getSema().BuildPredefinedExpr(E->getLocation(), E->getIdentKind());
20440b57cec5SDimitry Andric }
20450b57cec5SDimitry Andric
20460b57cec5SDimitry Andric ExprResult
TransformTemplateParmRefExpr(DeclRefExpr * E,NonTypeTemplateParmDecl * NTTP)20470b57cec5SDimitry Andric TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,
20480b57cec5SDimitry Andric NonTypeTemplateParmDecl *NTTP) {
20490b57cec5SDimitry Andric // If the corresponding template argument is NULL or non-existent, it's
20500b57cec5SDimitry Andric // because we are performing instantiation from explicitly-specified
20510b57cec5SDimitry Andric // template arguments in a function template, but there were some
20520b57cec5SDimitry Andric // arguments left unspecified.
20530b57cec5SDimitry Andric if (!TemplateArgs.hasTemplateArgument(NTTP->getDepth(),
20540b57cec5SDimitry Andric NTTP->getPosition()))
20550b57cec5SDimitry Andric return E;
20560b57cec5SDimitry Andric
20570b57cec5SDimitry Andric TemplateArgument Arg = TemplateArgs(NTTP->getDepth(), NTTP->getPosition());
20580b57cec5SDimitry Andric
20595ffd83dbSDimitry Andric if (TemplateArgs.isRewrite()) {
20605ffd83dbSDimitry Andric // We're rewriting the template parameter as a reference to another
20615ffd83dbSDimitry Andric // template parameter.
20620b57cec5SDimitry Andric if (Arg.getKind() == TemplateArgument::Pack) {
20630b57cec5SDimitry Andric assert(Arg.pack_size() == 1 && Arg.pack_begin()->isPackExpansion() &&
20645ffd83dbSDimitry Andric "unexpected pack arguments in template rewrite");
20650b57cec5SDimitry Andric Arg = Arg.pack_begin()->getPackExpansionPattern();
20660b57cec5SDimitry Andric }
20670b57cec5SDimitry Andric assert(Arg.getKind() == TemplateArgument::Expression &&
20685ffd83dbSDimitry Andric "unexpected nontype template argument kind in template rewrite");
20695ffd83dbSDimitry Andric // FIXME: This can lead to the same subexpression appearing multiple times
20705ffd83dbSDimitry Andric // in a complete expression.
20710b57cec5SDimitry Andric return Arg.getAsExpr();
20720b57cec5SDimitry Andric }
20730b57cec5SDimitry Andric
2074bdd1243dSDimitry Andric auto [AssociatedDecl, _] = TemplateArgs.getAssociatedDecl(NTTP->getDepth());
2075bdd1243dSDimitry Andric std::optional<unsigned> PackIndex;
20760b57cec5SDimitry Andric if (NTTP->isParameterPack()) {
20770b57cec5SDimitry Andric assert(Arg.getKind() == TemplateArgument::Pack &&
20780b57cec5SDimitry Andric "Missing argument pack");
20790b57cec5SDimitry Andric
20800b57cec5SDimitry Andric if (getSema().ArgumentPackSubstitutionIndex == -1) {
20810b57cec5SDimitry Andric // We have an argument pack, but we can't select a particular argument
20820b57cec5SDimitry Andric // out of it yet. Therefore, we'll build an expression to hold on to that
20830b57cec5SDimitry Andric // argument pack.
20840b57cec5SDimitry Andric QualType TargetType = SemaRef.SubstType(NTTP->getType(), TemplateArgs,
20850b57cec5SDimitry Andric E->getLocation(),
20860b57cec5SDimitry Andric NTTP->getDeclName());
20870b57cec5SDimitry Andric if (TargetType.isNull())
20880b57cec5SDimitry Andric return ExprError();
20890b57cec5SDimitry Andric
2090e8d8bef9SDimitry Andric QualType ExprType = TargetType.getNonLValueExprType(SemaRef.Context);
2091e8d8bef9SDimitry Andric if (TargetType->isRecordType())
2092e8d8bef9SDimitry Andric ExprType.addConst();
2093bdd1243dSDimitry Andric // FIXME: Pass in Final.
20940b57cec5SDimitry Andric return new (SemaRef.Context) SubstNonTypeTemplateParmPackExpr(
2095fe6060f1SDimitry Andric ExprType, TargetType->isReferenceType() ? VK_LValue : VK_PRValue,
2096bdd1243dSDimitry Andric E->getLocation(), Arg, AssociatedDecl, NTTP->getPosition());
20970b57cec5SDimitry Andric }
2098bdd1243dSDimitry Andric PackIndex = getPackIndex(Arg);
20990b57cec5SDimitry Andric Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
21000b57cec5SDimitry Andric }
2101bdd1243dSDimitry Andric // FIXME: Don't put subst node on Final replacement.
2102bdd1243dSDimitry Andric return transformNonTypeTemplateParmRef(AssociatedDecl, NTTP, E->getLocation(),
2103bdd1243dSDimitry Andric Arg, PackIndex);
21040b57cec5SDimitry Andric }
21050b57cec5SDimitry Andric
21060fca6ea1SDimitry Andric const CXXAssumeAttr *
TransformCXXAssumeAttr(const CXXAssumeAttr * AA)21070fca6ea1SDimitry Andric TemplateInstantiator::TransformCXXAssumeAttr(const CXXAssumeAttr *AA) {
21080fca6ea1SDimitry Andric ExprResult Res = getDerived().TransformExpr(AA->getAssumption());
21090fca6ea1SDimitry Andric if (!Res.isUsable())
21100fca6ea1SDimitry Andric return AA;
21110fca6ea1SDimitry Andric
21120fca6ea1SDimitry Andric Res = getSema().BuildCXXAssumeExpr(Res.get(), AA->getAttrName(),
21130fca6ea1SDimitry Andric AA->getRange());
21140fca6ea1SDimitry Andric if (!Res.isUsable())
21150fca6ea1SDimitry Andric return AA;
21160fca6ea1SDimitry Andric
21170fca6ea1SDimitry Andric return CXXAssumeAttr::CreateImplicit(getSema().Context, Res.get(),
21180fca6ea1SDimitry Andric AA->getRange());
21190fca6ea1SDimitry Andric }
21200fca6ea1SDimitry Andric
21210b57cec5SDimitry Andric const LoopHintAttr *
TransformLoopHintAttr(const LoopHintAttr * LH)21220b57cec5SDimitry Andric TemplateInstantiator::TransformLoopHintAttr(const LoopHintAttr *LH) {
21230b57cec5SDimitry Andric Expr *TransformedExpr = getDerived().TransformExpr(LH->getValue()).get();
21240b57cec5SDimitry Andric
21250b57cec5SDimitry Andric if (TransformedExpr == LH->getValue())
21260b57cec5SDimitry Andric return LH;
21270b57cec5SDimitry Andric
21280b57cec5SDimitry Andric // Generate error if there is a problem with the value.
21290fca6ea1SDimitry Andric if (getSema().CheckLoopHintExpr(TransformedExpr, LH->getLocation(),
21300fca6ea1SDimitry Andric LH->getSemanticSpelling() ==
21310fca6ea1SDimitry Andric LoopHintAttr::Pragma_unroll))
21320b57cec5SDimitry Andric return LH;
21330b57cec5SDimitry Andric
21340fca6ea1SDimitry Andric LoopHintAttr::OptionType Option = LH->getOption();
21350fca6ea1SDimitry Andric LoopHintAttr::LoopHintState State = LH->getState();
21360fca6ea1SDimitry Andric
21370fca6ea1SDimitry Andric llvm::APSInt ValueAPS =
21380fca6ea1SDimitry Andric TransformedExpr->EvaluateKnownConstInt(getSema().getASTContext());
21390fca6ea1SDimitry Andric // The values of 0 and 1 block any unrolling of the loop.
21400fca6ea1SDimitry Andric if (ValueAPS.isZero() || ValueAPS.isOne()) {
21410fca6ea1SDimitry Andric Option = LoopHintAttr::Unroll;
21420fca6ea1SDimitry Andric State = LoopHintAttr::Disable;
21430fca6ea1SDimitry Andric }
21440fca6ea1SDimitry Andric
21450b57cec5SDimitry Andric // Create new LoopHintValueAttr with integral expression in place of the
21460b57cec5SDimitry Andric // non-type template parameter.
21470fca6ea1SDimitry Andric return LoopHintAttr::CreateImplicit(getSema().Context, Option, State,
21480fca6ea1SDimitry Andric TransformedExpr, *LH);
21490b57cec5SDimitry Andric }
TransformStmtNoInlineAttr(const Stmt * OrigS,const Stmt * InstS,const NoInlineAttr * A)215006c3fb27SDimitry Andric const NoInlineAttr *TemplateInstantiator::TransformStmtNoInlineAttr(
215106c3fb27SDimitry Andric const Stmt *OrigS, const Stmt *InstS, const NoInlineAttr *A) {
215206c3fb27SDimitry Andric if (!A || getSema().CheckNoInlineAttr(OrigS, InstS, *A))
215306c3fb27SDimitry Andric return nullptr;
215406c3fb27SDimitry Andric
215506c3fb27SDimitry Andric return A;
215606c3fb27SDimitry Andric }
TransformStmtAlwaysInlineAttr(const Stmt * OrigS,const Stmt * InstS,const AlwaysInlineAttr * A)215706c3fb27SDimitry Andric const AlwaysInlineAttr *TemplateInstantiator::TransformStmtAlwaysInlineAttr(
215806c3fb27SDimitry Andric const Stmt *OrigS, const Stmt *InstS, const AlwaysInlineAttr *A) {
215906c3fb27SDimitry Andric if (!A || getSema().CheckAlwaysInlineAttr(OrigS, InstS, *A))
216006c3fb27SDimitry Andric return nullptr;
216106c3fb27SDimitry Andric
216206c3fb27SDimitry Andric return A;
216306c3fb27SDimitry Andric }
21640b57cec5SDimitry Andric
21655f757f3fSDimitry Andric const CodeAlignAttr *
TransformCodeAlignAttr(const CodeAlignAttr * CA)21665f757f3fSDimitry Andric TemplateInstantiator::TransformCodeAlignAttr(const CodeAlignAttr *CA) {
21675f757f3fSDimitry Andric Expr *TransformedExpr = getDerived().TransformExpr(CA->getAlignment()).get();
21685f757f3fSDimitry Andric return getSema().BuildCodeAlignAttr(*CA, TransformedExpr);
21695f757f3fSDimitry Andric }
21705f757f3fSDimitry Andric
transformNonTypeTemplateParmRef(Decl * AssociatedDecl,const NonTypeTemplateParmDecl * parm,SourceLocation loc,TemplateArgument arg,std::optional<unsigned> PackIndex)21710b57cec5SDimitry Andric ExprResult TemplateInstantiator::transformNonTypeTemplateParmRef(
2172bdd1243dSDimitry Andric Decl *AssociatedDecl, const NonTypeTemplateParmDecl *parm,
2173bdd1243dSDimitry Andric SourceLocation loc, TemplateArgument arg,
2174bdd1243dSDimitry Andric std::optional<unsigned> PackIndex) {
21750b57cec5SDimitry Andric ExprResult result;
21760b57cec5SDimitry Andric
2177e8d8bef9SDimitry Andric // Determine the substituted parameter type. We can usually infer this from
2178e8d8bef9SDimitry Andric // the template argument, but not always.
2179e8d8bef9SDimitry Andric auto SubstParamType = [&] {
2180e8d8bef9SDimitry Andric QualType T;
2181e8d8bef9SDimitry Andric if (parm->isExpandedParameterPack())
2182e8d8bef9SDimitry Andric T = parm->getExpansionType(SemaRef.ArgumentPackSubstitutionIndex);
2183e8d8bef9SDimitry Andric else
2184e8d8bef9SDimitry Andric T = parm->getType();
2185e8d8bef9SDimitry Andric if (parm->isParameterPack() && isa<PackExpansionType>(T))
2186e8d8bef9SDimitry Andric T = cast<PackExpansionType>(T)->getPattern();
2187e8d8bef9SDimitry Andric return SemaRef.SubstType(T, TemplateArgs, loc, parm->getDeclName());
2188e8d8bef9SDimitry Andric };
2189e8d8bef9SDimitry Andric
2190e8d8bef9SDimitry Andric bool refParam = false;
2191e8d8bef9SDimitry Andric
2192e8d8bef9SDimitry Andric // The template argument itself might be an expression, in which case we just
2193e8d8bef9SDimitry Andric // return that expression. This happens when substituting into an alias
2194e8d8bef9SDimitry Andric // template.
21950b57cec5SDimitry Andric if (arg.getKind() == TemplateArgument::Expression) {
21960b57cec5SDimitry Andric Expr *argExpr = arg.getAsExpr();
21970b57cec5SDimitry Andric result = argExpr;
2198e8d8bef9SDimitry Andric if (argExpr->isLValue()) {
2199e8d8bef9SDimitry Andric if (argExpr->getType()->isRecordType()) {
2200e8d8bef9SDimitry Andric // Check whether the parameter was actually a reference.
2201e8d8bef9SDimitry Andric QualType paramType = SubstParamType();
2202e8d8bef9SDimitry Andric if (paramType.isNull())
2203e8d8bef9SDimitry Andric return ExprError();
2204e8d8bef9SDimitry Andric refParam = paramType->isReferenceType();
2205e8d8bef9SDimitry Andric } else {
2206e8d8bef9SDimitry Andric refParam = true;
2207e8d8bef9SDimitry Andric }
2208e8d8bef9SDimitry Andric }
22090b57cec5SDimitry Andric } else if (arg.getKind() == TemplateArgument::Declaration ||
22100b57cec5SDimitry Andric arg.getKind() == TemplateArgument::NullPtr) {
22110b57cec5SDimitry Andric if (arg.getKind() == TemplateArgument::Declaration) {
22127a6dacacSDimitry Andric ValueDecl *VD = arg.getAsDecl();
22130b57cec5SDimitry Andric
22140b57cec5SDimitry Andric // Find the instantiation of the template argument. This is
22150b57cec5SDimitry Andric // required for nested templates.
22160b57cec5SDimitry Andric VD = cast_or_null<ValueDecl>(
22170b57cec5SDimitry Andric getSema().FindInstantiatedDecl(loc, VD, TemplateArgs));
22180b57cec5SDimitry Andric if (!VD)
22190b57cec5SDimitry Andric return ExprError();
22200b57cec5SDimitry Andric }
22210b57cec5SDimitry Andric
22227a6dacacSDimitry Andric QualType paramType = arg.getNonTypeTemplateArgumentType();
2223e8d8bef9SDimitry Andric assert(!paramType.isNull() && "type substitution failed for param type");
2224e8d8bef9SDimitry Andric assert(!paramType->isDependentType() && "param type still dependent");
2225e8d8bef9SDimitry Andric result = SemaRef.BuildExpressionFromDeclTemplateArgument(arg, paramType, loc);
2226e8d8bef9SDimitry Andric refParam = paramType->isReferenceType();
22270b57cec5SDimitry Andric } else {
22287a6dacacSDimitry Andric QualType paramType = arg.getNonTypeTemplateArgumentType();
22297a6dacacSDimitry Andric result = SemaRef.BuildExpressionFromNonTypeTemplateArgument(arg, loc);
22307a6dacacSDimitry Andric refParam = paramType->isReferenceType();
2231e8d8bef9SDimitry Andric assert(result.isInvalid() ||
2232e8d8bef9SDimitry Andric SemaRef.Context.hasSameType(result.get()->getType(),
22337a6dacacSDimitry Andric paramType.getNonReferenceType()));
22340b57cec5SDimitry Andric }
2235e8d8bef9SDimitry Andric
2236e8d8bef9SDimitry Andric if (result.isInvalid())
2237e8d8bef9SDimitry Andric return ExprError();
22380b57cec5SDimitry Andric
22390b57cec5SDimitry Andric Expr *resultExpr = result.get();
2240bdd1243dSDimitry Andric // FIXME: Don't put subst node on final replacement.
22410b57cec5SDimitry Andric return new (SemaRef.Context) SubstNonTypeTemplateParmExpr(
2242bdd1243dSDimitry Andric resultExpr->getType(), resultExpr->getValueKind(), loc, resultExpr,
2243bdd1243dSDimitry Andric AssociatedDecl, parm->getIndex(), PackIndex, refParam);
22440b57cec5SDimitry Andric }
22450b57cec5SDimitry Andric
22460b57cec5SDimitry Andric ExprResult
TransformSubstNonTypeTemplateParmPackExpr(SubstNonTypeTemplateParmPackExpr * E)22470b57cec5SDimitry Andric TemplateInstantiator::TransformSubstNonTypeTemplateParmPackExpr(
22480b57cec5SDimitry Andric SubstNonTypeTemplateParmPackExpr *E) {
22490b57cec5SDimitry Andric if (getSema().ArgumentPackSubstitutionIndex == -1) {
22500b57cec5SDimitry Andric // We aren't expanding the parameter pack, so just return ourselves.
22510b57cec5SDimitry Andric return E;
22520b57cec5SDimitry Andric }
22530b57cec5SDimitry Andric
2254bdd1243dSDimitry Andric TemplateArgument Pack = E->getArgumentPack();
2255bdd1243dSDimitry Andric TemplateArgument Arg = getPackSubstitutedTemplateArgument(getSema(), Pack);
2256bdd1243dSDimitry Andric // FIXME: Don't put subst node on final replacement.
2257bdd1243dSDimitry Andric return transformNonTypeTemplateParmRef(
2258bdd1243dSDimitry Andric E->getAssociatedDecl(), E->getParameterPack(),
2259bdd1243dSDimitry Andric E->getParameterPackLocation(), Arg, getPackIndex(Pack));
22600b57cec5SDimitry Andric }
22610b57cec5SDimitry Andric
226213138422SDimitry Andric ExprResult
TransformSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr * E)226313138422SDimitry Andric TemplateInstantiator::TransformSubstNonTypeTemplateParmExpr(
226413138422SDimitry Andric SubstNonTypeTemplateParmExpr *E) {
2265e8d8bef9SDimitry Andric ExprResult SubstReplacement = E->getReplacement();
2266e8d8bef9SDimitry Andric if (!isa<ConstantExpr>(SubstReplacement.get()))
2267e8d8bef9SDimitry Andric SubstReplacement = TransformExpr(E->getReplacement());
226813138422SDimitry Andric if (SubstReplacement.isInvalid())
226913138422SDimitry Andric return true;
2270e8d8bef9SDimitry Andric QualType SubstType = TransformType(E->getParameterType(getSema().Context));
227113138422SDimitry Andric if (SubstType.isNull())
227213138422SDimitry Andric return true;
227313138422SDimitry Andric // The type may have been previously dependent and not now, which means we
227413138422SDimitry Andric // might have to implicit cast the argument to the new type, for example:
227513138422SDimitry Andric // template<auto T, decltype(T) U>
227613138422SDimitry Andric // concept C = sizeof(U) == 4;
227713138422SDimitry Andric // void foo() requires C<2, 'a'> { }
227813138422SDimitry Andric // When normalizing foo(), we first form the normalized constraints of C:
227913138422SDimitry Andric // AtomicExpr(sizeof(U) == 4,
228013138422SDimitry Andric // U=SubstNonTypeTemplateParmExpr(Param=U,
228113138422SDimitry Andric // Expr=DeclRef(U),
228213138422SDimitry Andric // Type=decltype(T)))
228313138422SDimitry Andric // Then we substitute T = 2, U = 'a' into the parameter mapping, and need to
228413138422SDimitry Andric // produce:
228513138422SDimitry Andric // AtomicExpr(sizeof(U) == 4,
228613138422SDimitry Andric // U=SubstNonTypeTemplateParmExpr(Param=U,
228713138422SDimitry Andric // Expr=ImpCast(
228813138422SDimitry Andric // decltype(2),
228913138422SDimitry Andric // SubstNTTPE(Param=U, Expr='a',
229013138422SDimitry Andric // Type=char)),
229113138422SDimitry Andric // Type=decltype(2)))
229213138422SDimitry Andric // The call to CheckTemplateArgument here produces the ImpCast.
2293bdd1243dSDimitry Andric TemplateArgument SugaredConverted, CanonicalConverted;
2294bdd1243dSDimitry Andric if (SemaRef
2295bdd1243dSDimitry Andric .CheckTemplateArgument(E->getParameter(), SubstType,
2296bdd1243dSDimitry Andric SubstReplacement.get(), SugaredConverted,
2297bdd1243dSDimitry Andric CanonicalConverted, Sema::CTAK_Specified)
2298bdd1243dSDimitry Andric .isInvalid())
229913138422SDimitry Andric return true;
2300bdd1243dSDimitry Andric return transformNonTypeTemplateParmRef(E->getAssociatedDecl(),
2301bdd1243dSDimitry Andric E->getParameter(), E->getExprLoc(),
2302bdd1243dSDimitry Andric SugaredConverted, E->getPackIndex());
230313138422SDimitry Andric }
230413138422SDimitry Andric
RebuildVarDeclRefExpr(VarDecl * PD,SourceLocation Loc)23050b57cec5SDimitry Andric ExprResult TemplateInstantiator::RebuildVarDeclRefExpr(VarDecl *PD,
23060b57cec5SDimitry Andric SourceLocation Loc) {
23070b57cec5SDimitry Andric DeclarationNameInfo NameInfo(PD->getDeclName(), Loc);
23080b57cec5SDimitry Andric return getSema().BuildDeclarationNameExpr(CXXScopeSpec(), NameInfo, PD);
23090b57cec5SDimitry Andric }
23100b57cec5SDimitry Andric
23110b57cec5SDimitry Andric ExprResult
TransformFunctionParmPackExpr(FunctionParmPackExpr * E)23120b57cec5SDimitry Andric TemplateInstantiator::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
23130b57cec5SDimitry Andric if (getSema().ArgumentPackSubstitutionIndex != -1) {
23140b57cec5SDimitry Andric // We can expand this parameter pack now.
23150b57cec5SDimitry Andric VarDecl *D = E->getExpansion(getSema().ArgumentPackSubstitutionIndex);
23160b57cec5SDimitry Andric VarDecl *VD = cast_or_null<VarDecl>(TransformDecl(E->getExprLoc(), D));
23170b57cec5SDimitry Andric if (!VD)
23180b57cec5SDimitry Andric return ExprError();
23190b57cec5SDimitry Andric return RebuildVarDeclRefExpr(VD, E->getExprLoc());
23200b57cec5SDimitry Andric }
23210b57cec5SDimitry Andric
23220b57cec5SDimitry Andric QualType T = TransformType(E->getType());
23230b57cec5SDimitry Andric if (T.isNull())
23240b57cec5SDimitry Andric return ExprError();
23250b57cec5SDimitry Andric
23260b57cec5SDimitry Andric // Transform each of the parameter expansions into the corresponding
23270b57cec5SDimitry Andric // parameters in the instantiation of the function decl.
23280b57cec5SDimitry Andric SmallVector<VarDecl *, 8> Vars;
23290b57cec5SDimitry Andric Vars.reserve(E->getNumExpansions());
23300b57cec5SDimitry Andric for (FunctionParmPackExpr::iterator I = E->begin(), End = E->end();
23310b57cec5SDimitry Andric I != End; ++I) {
23320b57cec5SDimitry Andric VarDecl *D = cast_or_null<VarDecl>(TransformDecl(E->getExprLoc(), *I));
23330b57cec5SDimitry Andric if (!D)
23340b57cec5SDimitry Andric return ExprError();
23350b57cec5SDimitry Andric Vars.push_back(D);
23360b57cec5SDimitry Andric }
23370b57cec5SDimitry Andric
23380b57cec5SDimitry Andric auto *PackExpr =
23390b57cec5SDimitry Andric FunctionParmPackExpr::Create(getSema().Context, T, E->getParameterPack(),
23400b57cec5SDimitry Andric E->getParameterPackLocation(), Vars);
23410b57cec5SDimitry Andric getSema().MarkFunctionParmPackReferenced(PackExpr);
23420b57cec5SDimitry Andric return PackExpr;
23430b57cec5SDimitry Andric }
23440b57cec5SDimitry Andric
23450b57cec5SDimitry Andric ExprResult
TransformFunctionParmPackRefExpr(DeclRefExpr * E,VarDecl * PD)23460b57cec5SDimitry Andric TemplateInstantiator::TransformFunctionParmPackRefExpr(DeclRefExpr *E,
23470b57cec5SDimitry Andric VarDecl *PD) {
23480b57cec5SDimitry Andric typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
23490b57cec5SDimitry Andric llvm::PointerUnion<Decl *, DeclArgumentPack *> *Found
23500b57cec5SDimitry Andric = getSema().CurrentInstantiationScope->findInstantiationOf(PD);
23510b57cec5SDimitry Andric assert(Found && "no instantiation for parameter pack");
23520b57cec5SDimitry Andric
23530b57cec5SDimitry Andric Decl *TransformedDecl;
23540b57cec5SDimitry Andric if (DeclArgumentPack *Pack = Found->dyn_cast<DeclArgumentPack *>()) {
23550b57cec5SDimitry Andric // If this is a reference to a function parameter pack which we can
23560b57cec5SDimitry Andric // substitute but can't yet expand, build a FunctionParmPackExpr for it.
23570b57cec5SDimitry Andric if (getSema().ArgumentPackSubstitutionIndex == -1) {
23580b57cec5SDimitry Andric QualType T = TransformType(E->getType());
23590b57cec5SDimitry Andric if (T.isNull())
23600b57cec5SDimitry Andric return ExprError();
23610b57cec5SDimitry Andric auto *PackExpr = FunctionParmPackExpr::Create(getSema().Context, T, PD,
23620b57cec5SDimitry Andric E->getExprLoc(), *Pack);
23630b57cec5SDimitry Andric getSema().MarkFunctionParmPackReferenced(PackExpr);
23640b57cec5SDimitry Andric return PackExpr;
23650b57cec5SDimitry Andric }
23660b57cec5SDimitry Andric
23670b57cec5SDimitry Andric TransformedDecl = (*Pack)[getSema().ArgumentPackSubstitutionIndex];
23680b57cec5SDimitry Andric } else {
23690b57cec5SDimitry Andric TransformedDecl = Found->get<Decl*>();
23700b57cec5SDimitry Andric }
23710b57cec5SDimitry Andric
23720b57cec5SDimitry Andric // We have either an unexpanded pack or a specific expansion.
23730b57cec5SDimitry Andric return RebuildVarDeclRefExpr(cast<VarDecl>(TransformedDecl), E->getExprLoc());
23740b57cec5SDimitry Andric }
23750b57cec5SDimitry Andric
23760b57cec5SDimitry Andric ExprResult
TransformDeclRefExpr(DeclRefExpr * E)23770b57cec5SDimitry Andric TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E) {
23780b57cec5SDimitry Andric NamedDecl *D = E->getDecl();
23790b57cec5SDimitry Andric
23800b57cec5SDimitry Andric // Handle references to non-type template parameters and non-type template
23810b57cec5SDimitry Andric // parameter packs.
23820b57cec5SDimitry Andric if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
23830b57cec5SDimitry Andric if (NTTP->getDepth() < TemplateArgs.getNumLevels())
23840b57cec5SDimitry Andric return TransformTemplateParmRefExpr(E, NTTP);
23850b57cec5SDimitry Andric
23860b57cec5SDimitry Andric // We have a non-type template parameter that isn't fully substituted;
23870b57cec5SDimitry Andric // FindInstantiatedDecl will find it in the local instantiation scope.
23880b57cec5SDimitry Andric }
23890b57cec5SDimitry Andric
23900b57cec5SDimitry Andric // Handle references to function parameter packs.
23910b57cec5SDimitry Andric if (VarDecl *PD = dyn_cast<VarDecl>(D))
23920b57cec5SDimitry Andric if (PD->isParameterPack())
23930b57cec5SDimitry Andric return TransformFunctionParmPackRefExpr(E, PD);
23940b57cec5SDimitry Andric
239581ad6265SDimitry Andric return inherited::TransformDeclRefExpr(E);
23960b57cec5SDimitry Andric }
23970b57cec5SDimitry Andric
TransformCXXDefaultArgExpr(CXXDefaultArgExpr * E)23980b57cec5SDimitry Andric ExprResult TemplateInstantiator::TransformCXXDefaultArgExpr(
23990b57cec5SDimitry Andric CXXDefaultArgExpr *E) {
24000b57cec5SDimitry Andric assert(!cast<FunctionDecl>(E->getParam()->getDeclContext())->
24010b57cec5SDimitry Andric getDescribedFunctionTemplate() &&
24020b57cec5SDimitry Andric "Default arg expressions are never formed in dependent cases.");
2403bdd1243dSDimitry Andric return SemaRef.BuildCXXDefaultArgExpr(
2404bdd1243dSDimitry Andric E->getUsedLocation(), cast<FunctionDecl>(E->getParam()->getDeclContext()),
24050b57cec5SDimitry Andric E->getParam());
24060b57cec5SDimitry Andric }
24070b57cec5SDimitry Andric
24080b57cec5SDimitry Andric template<typename Fn>
TransformFunctionProtoType(TypeLocBuilder & TLB,FunctionProtoTypeLoc TL,CXXRecordDecl * ThisContext,Qualifiers ThisTypeQuals,Fn TransformExceptionSpec)24090b57cec5SDimitry Andric QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB,
24100b57cec5SDimitry Andric FunctionProtoTypeLoc TL,
24110b57cec5SDimitry Andric CXXRecordDecl *ThisContext,
24120b57cec5SDimitry Andric Qualifiers ThisTypeQuals,
24130b57cec5SDimitry Andric Fn TransformExceptionSpec) {
24140b57cec5SDimitry Andric // We need a local instantiation scope for this function prototype.
24150b57cec5SDimitry Andric LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
24160b57cec5SDimitry Andric return inherited::TransformFunctionProtoType(
24170b57cec5SDimitry Andric TLB, TL, ThisContext, ThisTypeQuals, TransformExceptionSpec);
24180b57cec5SDimitry Andric }
24190b57cec5SDimitry Andric
TransformFunctionTypeParam(ParmVarDecl * OldParm,int indexAdjustment,std::optional<unsigned> NumExpansions,bool ExpectParameterPack)2420bdd1243dSDimitry Andric ParmVarDecl *TemplateInstantiator::TransformFunctionTypeParam(
2421bdd1243dSDimitry Andric ParmVarDecl *OldParm, int indexAdjustment,
2422bdd1243dSDimitry Andric std::optional<unsigned> NumExpansions, bool ExpectParameterPack) {
2423bdd1243dSDimitry Andric auto NewParm = SemaRef.SubstParmVarDecl(
2424bdd1243dSDimitry Andric OldParm, TemplateArgs, indexAdjustment, NumExpansions,
2425bdd1243dSDimitry Andric ExpectParameterPack, EvaluateConstraints);
2426480093f4SDimitry Andric if (NewParm && SemaRef.getLangOpts().OpenCL)
2427480093f4SDimitry Andric SemaRef.deduceOpenCLAddressSpace(NewParm);
2428480093f4SDimitry Andric return NewParm;
24290b57cec5SDimitry Andric }
24300b57cec5SDimitry Andric
BuildSubstTemplateTypeParmType(TypeLocBuilder & TLB,bool SuppressObjCLifetime,bool Final,Decl * AssociatedDecl,unsigned Index,std::optional<unsigned> PackIndex,TemplateArgument Arg,SourceLocation NameLoc)2431bdd1243dSDimitry Andric QualType TemplateInstantiator::BuildSubstTemplateTypeParmType(
2432bdd1243dSDimitry Andric TypeLocBuilder &TLB, bool SuppressObjCLifetime, bool Final,
2433bdd1243dSDimitry Andric Decl *AssociatedDecl, unsigned Index, std::optional<unsigned> PackIndex,
2434bdd1243dSDimitry Andric TemplateArgument Arg, SourceLocation NameLoc) {
2435bdd1243dSDimitry Andric QualType Replacement = Arg.getAsType();
2436bdd1243dSDimitry Andric
2437bdd1243dSDimitry Andric // If the template parameter had ObjC lifetime qualifiers,
2438bdd1243dSDimitry Andric // then any such qualifiers on the replacement type are ignored.
2439bdd1243dSDimitry Andric if (SuppressObjCLifetime) {
2440bdd1243dSDimitry Andric Qualifiers RQs;
2441bdd1243dSDimitry Andric RQs = Replacement.getQualifiers();
2442bdd1243dSDimitry Andric RQs.removeObjCLifetime();
2443bdd1243dSDimitry Andric Replacement =
2444bdd1243dSDimitry Andric SemaRef.Context.getQualifiedType(Replacement.getUnqualifiedType(), RQs);
2445bdd1243dSDimitry Andric }
2446bdd1243dSDimitry Andric
2447bdd1243dSDimitry Andric if (Final) {
2448bdd1243dSDimitry Andric TLB.pushTrivial(SemaRef.Context, Replacement, NameLoc);
2449bdd1243dSDimitry Andric return Replacement;
2450bdd1243dSDimitry Andric }
2451bdd1243dSDimitry Andric // TODO: only do this uniquing once, at the start of instantiation.
2452bdd1243dSDimitry Andric QualType Result = getSema().Context.getSubstTemplateTypeParmType(
2453bdd1243dSDimitry Andric Replacement, AssociatedDecl, Index, PackIndex);
2454bdd1243dSDimitry Andric SubstTemplateTypeParmTypeLoc NewTL =
2455bdd1243dSDimitry Andric TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
2456bdd1243dSDimitry Andric NewTL.setNameLoc(NameLoc);
2457bdd1243dSDimitry Andric return Result;
2458bdd1243dSDimitry Andric }
2459bdd1243dSDimitry Andric
24600b57cec5SDimitry Andric QualType
TransformTemplateTypeParmType(TypeLocBuilder & TLB,TemplateTypeParmTypeLoc TL,bool SuppressObjCLifetime)24610b57cec5SDimitry Andric TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB,
2462bdd1243dSDimitry Andric TemplateTypeParmTypeLoc TL,
2463bdd1243dSDimitry Andric bool SuppressObjCLifetime) {
24640b57cec5SDimitry Andric const TemplateTypeParmType *T = TL.getTypePtr();
24650b57cec5SDimitry Andric if (T->getDepth() < TemplateArgs.getNumLevels()) {
24660b57cec5SDimitry Andric // Replace the template type parameter with its corresponding
24670b57cec5SDimitry Andric // template argument.
24680b57cec5SDimitry Andric
24690b57cec5SDimitry Andric // If the corresponding template argument is NULL or doesn't exist, it's
24700b57cec5SDimitry Andric // because we are performing instantiation from explicitly-specified
24710b57cec5SDimitry Andric // template arguments in a function template class, but there were some
24720b57cec5SDimitry Andric // arguments left unspecified.
24730b57cec5SDimitry Andric if (!TemplateArgs.hasTemplateArgument(T->getDepth(), T->getIndex())) {
24740b57cec5SDimitry Andric TemplateTypeParmTypeLoc NewTL
24750b57cec5SDimitry Andric = TLB.push<TemplateTypeParmTypeLoc>(TL.getType());
24760b57cec5SDimitry Andric NewTL.setNameLoc(TL.getNameLoc());
24770b57cec5SDimitry Andric return TL.getType();
24780b57cec5SDimitry Andric }
24790b57cec5SDimitry Andric
24800b57cec5SDimitry Andric TemplateArgument Arg = TemplateArgs(T->getDepth(), T->getIndex());
24810b57cec5SDimitry Andric
24825ffd83dbSDimitry Andric if (TemplateArgs.isRewrite()) {
24835ffd83dbSDimitry Andric // We're rewriting the template parameter as a reference to another
24845ffd83dbSDimitry Andric // template parameter.
24855ffd83dbSDimitry Andric if (Arg.getKind() == TemplateArgument::Pack) {
24865ffd83dbSDimitry Andric assert(Arg.pack_size() == 1 && Arg.pack_begin()->isPackExpansion() &&
24875ffd83dbSDimitry Andric "unexpected pack arguments in template rewrite");
24885ffd83dbSDimitry Andric Arg = Arg.pack_begin()->getPackExpansionPattern();
24895ffd83dbSDimitry Andric }
24905ffd83dbSDimitry Andric assert(Arg.getKind() == TemplateArgument::Type &&
24915ffd83dbSDimitry Andric "unexpected nontype template argument kind in template rewrite");
24925ffd83dbSDimitry Andric QualType NewT = Arg.getAsType();
24930fca6ea1SDimitry Andric TLB.pushTrivial(SemaRef.Context, NewT, TL.getNameLoc());
24945ffd83dbSDimitry Andric return NewT;
24955ffd83dbSDimitry Andric }
24965ffd83dbSDimitry Andric
2497bdd1243dSDimitry Andric auto [AssociatedDecl, Final] =
2498bdd1243dSDimitry Andric TemplateArgs.getAssociatedDecl(T->getDepth());
2499bdd1243dSDimitry Andric std::optional<unsigned> PackIndex;
25000b57cec5SDimitry Andric if (T->isParameterPack()) {
25010b57cec5SDimitry Andric assert(Arg.getKind() == TemplateArgument::Pack &&
25020b57cec5SDimitry Andric "Missing argument pack");
25030b57cec5SDimitry Andric
25040b57cec5SDimitry Andric if (getSema().ArgumentPackSubstitutionIndex == -1) {
25050b57cec5SDimitry Andric // We have the template argument pack, but we're not expanding the
25060b57cec5SDimitry Andric // enclosing pack expansion yet. Just save the template argument
25070b57cec5SDimitry Andric // pack for later substitution.
2508bdd1243dSDimitry Andric QualType Result = getSema().Context.getSubstTemplateTypeParmPackType(
2509bdd1243dSDimitry Andric AssociatedDecl, T->getIndex(), Final, Arg);
25100b57cec5SDimitry Andric SubstTemplateTypeParmPackTypeLoc NewTL
25110b57cec5SDimitry Andric = TLB.push<SubstTemplateTypeParmPackTypeLoc>(Result);
25120b57cec5SDimitry Andric NewTL.setNameLoc(TL.getNameLoc());
25130b57cec5SDimitry Andric return Result;
25140b57cec5SDimitry Andric }
25150b57cec5SDimitry Andric
2516bdd1243dSDimitry Andric // PackIndex starts from last element.
2517bdd1243dSDimitry Andric PackIndex = getPackIndex(Arg);
25180b57cec5SDimitry Andric Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
25190b57cec5SDimitry Andric }
25200b57cec5SDimitry Andric
25210b57cec5SDimitry Andric assert(Arg.getKind() == TemplateArgument::Type &&
25220b57cec5SDimitry Andric "Template argument kind mismatch");
25230b57cec5SDimitry Andric
2524bdd1243dSDimitry Andric return BuildSubstTemplateTypeParmType(TLB, SuppressObjCLifetime, Final,
2525bdd1243dSDimitry Andric AssociatedDecl, T->getIndex(),
2526bdd1243dSDimitry Andric PackIndex, Arg, TL.getNameLoc());
25270b57cec5SDimitry Andric }
25280b57cec5SDimitry Andric
25290b57cec5SDimitry Andric // The template type parameter comes from an inner template (e.g.,
25300b57cec5SDimitry Andric // the template parameter list of a member template inside the
25310b57cec5SDimitry Andric // template we are instantiating). Create a new template type
25320b57cec5SDimitry Andric // parameter with the template "level" reduced by one.
25330b57cec5SDimitry Andric TemplateTypeParmDecl *NewTTPDecl = nullptr;
25340b57cec5SDimitry Andric if (TemplateTypeParmDecl *OldTTPDecl = T->getDecl())
25350b57cec5SDimitry Andric NewTTPDecl = cast_or_null<TemplateTypeParmDecl>(
25360b57cec5SDimitry Andric TransformDecl(TL.getNameLoc(), OldTTPDecl));
25370b57cec5SDimitry Andric QualType Result = getSema().Context.getTemplateTypeParmType(
25380b57cec5SDimitry Andric T->getDepth() - TemplateArgs.getNumSubstitutedLevels(), T->getIndex(),
25390b57cec5SDimitry Andric T->isParameterPack(), NewTTPDecl);
25400b57cec5SDimitry Andric TemplateTypeParmTypeLoc NewTL = TLB.push<TemplateTypeParmTypeLoc>(Result);
25410b57cec5SDimitry Andric NewTL.setNameLoc(TL.getNameLoc());
25420b57cec5SDimitry Andric return Result;
25430b57cec5SDimitry Andric }
25440b57cec5SDimitry Andric
TransformSubstTemplateTypeParmPackType(TypeLocBuilder & TLB,SubstTemplateTypeParmPackTypeLoc TL,bool SuppressObjCLifetime)2545bdd1243dSDimitry Andric QualType TemplateInstantiator::TransformSubstTemplateTypeParmPackType(
2546bdd1243dSDimitry Andric TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL,
2547bdd1243dSDimitry Andric bool SuppressObjCLifetime) {
2548bdd1243dSDimitry Andric const SubstTemplateTypeParmPackType *T = TL.getTypePtr();
2549bdd1243dSDimitry Andric
2550bdd1243dSDimitry Andric Decl *NewReplaced = TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
2551bdd1243dSDimitry Andric
25520b57cec5SDimitry Andric if (getSema().ArgumentPackSubstitutionIndex == -1) {
25530b57cec5SDimitry Andric // We aren't expanding the parameter pack, so just return ourselves.
2554bdd1243dSDimitry Andric QualType Result = TL.getType();
2555bdd1243dSDimitry Andric if (NewReplaced != T->getAssociatedDecl())
2556bdd1243dSDimitry Andric Result = getSema().Context.getSubstTemplateTypeParmPackType(
2557bdd1243dSDimitry Andric NewReplaced, T->getIndex(), T->getFinal(), T->getArgumentPack());
2558bdd1243dSDimitry Andric SubstTemplateTypeParmPackTypeLoc NewTL =
2559bdd1243dSDimitry Andric TLB.push<SubstTemplateTypeParmPackTypeLoc>(Result);
25600b57cec5SDimitry Andric NewTL.setNameLoc(TL.getNameLoc());
25610b57cec5SDimitry Andric return Result;
25620b57cec5SDimitry Andric }
25630b57cec5SDimitry Andric
2564bdd1243dSDimitry Andric TemplateArgument Pack = T->getArgumentPack();
2565bdd1243dSDimitry Andric TemplateArgument Arg = getPackSubstitutedTemplateArgument(getSema(), Pack);
2566bdd1243dSDimitry Andric return BuildSubstTemplateTypeParmType(
2567bdd1243dSDimitry Andric TLB, SuppressObjCLifetime, T->getFinal(), NewReplaced, T->getIndex(),
2568bdd1243dSDimitry Andric getPackIndex(Pack), Arg, TL.getNameLoc());
2569bdd1243dSDimitry Andric }
2570bdd1243dSDimitry Andric
257155e4f9d5SDimitry Andric static concepts::Requirement::SubstitutionDiagnostic *
createSubstDiag(Sema & S,TemplateDeductionInfo & Info,concepts::EntityPrinter Printer)25728a4dda33SDimitry Andric createSubstDiag(Sema &S, TemplateDeductionInfo &Info,
25738a4dda33SDimitry Andric concepts::EntityPrinter Printer) {
257455e4f9d5SDimitry Andric SmallString<128> Message;
257555e4f9d5SDimitry Andric SourceLocation ErrorLoc;
257655e4f9d5SDimitry Andric if (Info.hasSFINAEDiagnostic()) {
257755e4f9d5SDimitry Andric PartialDiagnosticAt PDA(SourceLocation(),
257855e4f9d5SDimitry Andric PartialDiagnostic::NullDiagnostic{});
257955e4f9d5SDimitry Andric Info.takeSFINAEDiagnostic(PDA);
258055e4f9d5SDimitry Andric PDA.second.EmitToString(S.getDiagnostics(), Message);
258155e4f9d5SDimitry Andric ErrorLoc = PDA.first;
258255e4f9d5SDimitry Andric } else {
258355e4f9d5SDimitry Andric ErrorLoc = Info.getLocation();
258455e4f9d5SDimitry Andric }
258555e4f9d5SDimitry Andric SmallString<128> Entity;
258655e4f9d5SDimitry Andric llvm::raw_svector_ostream OS(Entity);
258755e4f9d5SDimitry Andric Printer(OS);
25880fca6ea1SDimitry Andric const ASTContext &C = S.Context;
25890fca6ea1SDimitry Andric return new (C) concepts::Requirement::SubstitutionDiagnostic{
25900fca6ea1SDimitry Andric C.backupStr(Entity), ErrorLoc, C.backupStr(Message)};
259155e4f9d5SDimitry Andric }
259255e4f9d5SDimitry Andric
25938a4dda33SDimitry Andric concepts::Requirement::SubstitutionDiagnostic *
createSubstDiagAt(Sema & S,SourceLocation Location,EntityPrinter Printer)25948a4dda33SDimitry Andric concepts::createSubstDiagAt(Sema &S, SourceLocation Location,
25958a4dda33SDimitry Andric EntityPrinter Printer) {
25968a4dda33SDimitry Andric SmallString<128> Entity;
25978a4dda33SDimitry Andric llvm::raw_svector_ostream OS(Entity);
25988a4dda33SDimitry Andric Printer(OS);
25990fca6ea1SDimitry Andric const ASTContext &C = S.Context;
26000fca6ea1SDimitry Andric return new (C) concepts::Requirement::SubstitutionDiagnostic{
26010fca6ea1SDimitry Andric /*SubstitutedEntity=*/C.backupStr(Entity),
26028a4dda33SDimitry Andric /*DiagLoc=*/Location, /*DiagMessage=*/StringRef()};
26038a4dda33SDimitry Andric }
26048a4dda33SDimitry Andric
TransformRequiresTypeParams(SourceLocation KWLoc,SourceLocation RBraceLoc,const RequiresExpr * RE,RequiresExprBodyDecl * Body,ArrayRef<ParmVarDecl * > Params,SmallVectorImpl<QualType> & PTypes,SmallVectorImpl<ParmVarDecl * > & TransParams,Sema::ExtParameterInfoBuilder & PInfos)2605bdd1243dSDimitry Andric ExprResult TemplateInstantiator::TransformRequiresTypeParams(
2606bdd1243dSDimitry Andric SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
2607bdd1243dSDimitry Andric RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,
2608bdd1243dSDimitry Andric SmallVectorImpl<QualType> &PTypes,
2609bdd1243dSDimitry Andric SmallVectorImpl<ParmVarDecl *> &TransParams,
2610bdd1243dSDimitry Andric Sema::ExtParameterInfoBuilder &PInfos) {
2611bdd1243dSDimitry Andric
2612bdd1243dSDimitry Andric TemplateDeductionInfo Info(KWLoc);
2613bdd1243dSDimitry Andric Sema::InstantiatingTemplate TypeInst(SemaRef, KWLoc,
2614bdd1243dSDimitry Andric RE, Info,
2615bdd1243dSDimitry Andric SourceRange{KWLoc, RBraceLoc});
2616bdd1243dSDimitry Andric Sema::SFINAETrap Trap(SemaRef);
2617bdd1243dSDimitry Andric
2618bdd1243dSDimitry Andric unsigned ErrorIdx;
2619bdd1243dSDimitry Andric if (getDerived().TransformFunctionTypeParams(
2620bdd1243dSDimitry Andric KWLoc, Params, /*ParamTypes=*/nullptr, /*ParamInfos=*/nullptr, PTypes,
2621bdd1243dSDimitry Andric &TransParams, PInfos, &ErrorIdx) ||
2622bdd1243dSDimitry Andric Trap.hasErrorOccurred()) {
2623bdd1243dSDimitry Andric SmallVector<concepts::Requirement *, 4> TransReqs;
2624bdd1243dSDimitry Andric ParmVarDecl *FailedDecl = Params[ErrorIdx];
2625bdd1243dSDimitry Andric // Add a 'failed' Requirement to contain the error that caused the failure
2626bdd1243dSDimitry Andric // here.
2627bdd1243dSDimitry Andric TransReqs.push_back(RebuildTypeRequirement(createSubstDiag(
2628bdd1243dSDimitry Andric SemaRef, Info, [&](llvm::raw_ostream &OS) { OS << *FailedDecl; })));
26295f757f3fSDimitry Andric return getDerived().RebuildRequiresExpr(KWLoc, Body, RE->getLParenLoc(),
26305f757f3fSDimitry Andric TransParams, RE->getRParenLoc(),
26315f757f3fSDimitry Andric TransReqs, RBraceLoc);
2632bdd1243dSDimitry Andric }
2633bdd1243dSDimitry Andric
2634bdd1243dSDimitry Andric return ExprResult{};
2635bdd1243dSDimitry Andric }
2636bdd1243dSDimitry Andric
263755e4f9d5SDimitry Andric concepts::TypeRequirement *
TransformTypeRequirement(concepts::TypeRequirement * Req)263855e4f9d5SDimitry Andric TemplateInstantiator::TransformTypeRequirement(concepts::TypeRequirement *Req) {
263955e4f9d5SDimitry Andric if (!Req->isDependent() && !AlwaysRebuild())
264055e4f9d5SDimitry Andric return Req;
264155e4f9d5SDimitry Andric if (Req->isSubstitutionFailure()) {
264255e4f9d5SDimitry Andric if (AlwaysRebuild())
264355e4f9d5SDimitry Andric return RebuildTypeRequirement(
264455e4f9d5SDimitry Andric Req->getSubstitutionDiagnostic());
264555e4f9d5SDimitry Andric return Req;
264655e4f9d5SDimitry Andric }
264755e4f9d5SDimitry Andric
264855e4f9d5SDimitry Andric Sema::SFINAETrap Trap(SemaRef);
264955e4f9d5SDimitry Andric TemplateDeductionInfo Info(Req->getType()->getTypeLoc().getBeginLoc());
265055e4f9d5SDimitry Andric Sema::InstantiatingTemplate TypeInst(SemaRef,
265155e4f9d5SDimitry Andric Req->getType()->getTypeLoc().getBeginLoc(), Req, Info,
265255e4f9d5SDimitry Andric Req->getType()->getTypeLoc().getSourceRange());
265355e4f9d5SDimitry Andric if (TypeInst.isInvalid())
265455e4f9d5SDimitry Andric return nullptr;
265555e4f9d5SDimitry Andric TypeSourceInfo *TransType = TransformType(Req->getType());
265655e4f9d5SDimitry Andric if (!TransType || Trap.hasErrorOccurred())
265755e4f9d5SDimitry Andric return RebuildTypeRequirement(createSubstDiag(SemaRef, Info,
265855e4f9d5SDimitry Andric [&] (llvm::raw_ostream& OS) {
265955e4f9d5SDimitry Andric Req->getType()->getType().print(OS, SemaRef.getPrintingPolicy());
266055e4f9d5SDimitry Andric }));
266155e4f9d5SDimitry Andric return RebuildTypeRequirement(TransType);
266255e4f9d5SDimitry Andric }
266355e4f9d5SDimitry Andric
266455e4f9d5SDimitry Andric concepts::ExprRequirement *
TransformExprRequirement(concepts::ExprRequirement * Req)266555e4f9d5SDimitry Andric TemplateInstantiator::TransformExprRequirement(concepts::ExprRequirement *Req) {
266655e4f9d5SDimitry Andric if (!Req->isDependent() && !AlwaysRebuild())
266755e4f9d5SDimitry Andric return Req;
266855e4f9d5SDimitry Andric
266955e4f9d5SDimitry Andric Sema::SFINAETrap Trap(SemaRef);
267055e4f9d5SDimitry Andric
267155e4f9d5SDimitry Andric llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *>
267255e4f9d5SDimitry Andric TransExpr;
267355e4f9d5SDimitry Andric if (Req->isExprSubstitutionFailure())
267455e4f9d5SDimitry Andric TransExpr = Req->getExprSubstitutionDiagnostic();
267555e4f9d5SDimitry Andric else {
26766e75b2fbSDimitry Andric Expr *E = Req->getExpr();
26776e75b2fbSDimitry Andric TemplateDeductionInfo Info(E->getBeginLoc());
26786e75b2fbSDimitry Andric Sema::InstantiatingTemplate ExprInst(SemaRef, E->getBeginLoc(), Req, Info,
26796e75b2fbSDimitry Andric E->getSourceRange());
268055e4f9d5SDimitry Andric if (ExprInst.isInvalid())
268155e4f9d5SDimitry Andric return nullptr;
26826e75b2fbSDimitry Andric ExprResult TransExprRes = TransformExpr(E);
26831fd87a68SDimitry Andric if (!TransExprRes.isInvalid() && !Trap.hasErrorOccurred() &&
26841fd87a68SDimitry Andric TransExprRes.get()->hasPlaceholderType())
26851fd87a68SDimitry Andric TransExprRes = SemaRef.CheckPlaceholderExpr(TransExprRes.get());
268655e4f9d5SDimitry Andric if (TransExprRes.isInvalid() || Trap.hasErrorOccurred())
26876e75b2fbSDimitry Andric TransExpr = createSubstDiag(SemaRef, Info, [&](llvm::raw_ostream &OS) {
26886e75b2fbSDimitry Andric E->printPretty(OS, nullptr, SemaRef.getPrintingPolicy());
268955e4f9d5SDimitry Andric });
269055e4f9d5SDimitry Andric else
269155e4f9d5SDimitry Andric TransExpr = TransExprRes.get();
269255e4f9d5SDimitry Andric }
269355e4f9d5SDimitry Andric
2694bdd1243dSDimitry Andric std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
269555e4f9d5SDimitry Andric const auto &RetReq = Req->getReturnTypeRequirement();
269655e4f9d5SDimitry Andric if (RetReq.isEmpty())
269755e4f9d5SDimitry Andric TransRetReq.emplace();
269855e4f9d5SDimitry Andric else if (RetReq.isSubstitutionFailure())
269955e4f9d5SDimitry Andric TransRetReq.emplace(RetReq.getSubstitutionDiagnostic());
270055e4f9d5SDimitry Andric else if (RetReq.isTypeConstraint()) {
270155e4f9d5SDimitry Andric TemplateParameterList *OrigTPL =
270255e4f9d5SDimitry Andric RetReq.getTypeConstraintTemplateParameterList();
27036e75b2fbSDimitry Andric TemplateDeductionInfo Info(OrigTPL->getTemplateLoc());
270455e4f9d5SDimitry Andric Sema::InstantiatingTemplate TPLInst(SemaRef, OrigTPL->getTemplateLoc(),
270555e4f9d5SDimitry Andric Req, Info, OrigTPL->getSourceRange());
270655e4f9d5SDimitry Andric if (TPLInst.isInvalid())
270755e4f9d5SDimitry Andric return nullptr;
2708bdd1243dSDimitry Andric TemplateParameterList *TPL = TransformTemplateParameterList(OrigTPL);
27090fca6ea1SDimitry Andric if (!TPL || Trap.hasErrorOccurred())
271055e4f9d5SDimitry Andric TransRetReq.emplace(createSubstDiag(SemaRef, Info,
271155e4f9d5SDimitry Andric [&] (llvm::raw_ostream& OS) {
271255e4f9d5SDimitry Andric RetReq.getTypeConstraint()->getImmediatelyDeclaredConstraint()
271355e4f9d5SDimitry Andric ->printPretty(OS, nullptr, SemaRef.getPrintingPolicy());
271455e4f9d5SDimitry Andric }));
271555e4f9d5SDimitry Andric else {
271655e4f9d5SDimitry Andric TPLInst.Clear();
271755e4f9d5SDimitry Andric TransRetReq.emplace(TPL);
271855e4f9d5SDimitry Andric }
271955e4f9d5SDimitry Andric }
272081ad6265SDimitry Andric assert(TransRetReq && "All code paths leading here must set TransRetReq");
272155e4f9d5SDimitry Andric if (Expr *E = TransExpr.dyn_cast<Expr *>())
272255e4f9d5SDimitry Andric return RebuildExprRequirement(E, Req->isSimple(), Req->getNoexceptLoc(),
272355e4f9d5SDimitry Andric std::move(*TransRetReq));
272455e4f9d5SDimitry Andric return RebuildExprRequirement(
272555e4f9d5SDimitry Andric TransExpr.get<concepts::Requirement::SubstitutionDiagnostic *>(),
272655e4f9d5SDimitry Andric Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
272755e4f9d5SDimitry Andric }
272855e4f9d5SDimitry Andric
272955e4f9d5SDimitry Andric concepts::NestedRequirement *
TransformNestedRequirement(concepts::NestedRequirement * Req)273055e4f9d5SDimitry Andric TemplateInstantiator::TransformNestedRequirement(
273155e4f9d5SDimitry Andric concepts::NestedRequirement *Req) {
273255e4f9d5SDimitry Andric if (!Req->isDependent() && !AlwaysRebuild())
273355e4f9d5SDimitry Andric return Req;
2734bdd1243dSDimitry Andric if (Req->hasInvalidConstraint()) {
273555e4f9d5SDimitry Andric if (AlwaysRebuild())
2736bdd1243dSDimitry Andric return RebuildNestedRequirement(Req->getInvalidConstraintEntity(),
2737bdd1243dSDimitry Andric Req->getConstraintSatisfaction());
273855e4f9d5SDimitry Andric return Req;
273955e4f9d5SDimitry Andric }
274055e4f9d5SDimitry Andric Sema::InstantiatingTemplate ReqInst(SemaRef,
274155e4f9d5SDimitry Andric Req->getConstraintExpr()->getBeginLoc(), Req,
274255e4f9d5SDimitry Andric Sema::InstantiatingTemplate::ConstraintsCheck{},
274355e4f9d5SDimitry Andric Req->getConstraintExpr()->getSourceRange());
27441db9f3b2SDimitry Andric if (!getEvaluateConstraints()) {
27451db9f3b2SDimitry Andric ExprResult TransConstraint = TransformExpr(Req->getConstraintExpr());
27461db9f3b2SDimitry Andric if (TransConstraint.isInvalid() || !TransConstraint.get())
27471db9f3b2SDimitry Andric return nullptr;
27481db9f3b2SDimitry Andric if (TransConstraint.get()->isInstantiationDependent())
27491db9f3b2SDimitry Andric return new (SemaRef.Context)
27501db9f3b2SDimitry Andric concepts::NestedRequirement(TransConstraint.get());
27511db9f3b2SDimitry Andric ConstraintSatisfaction Satisfaction;
27521db9f3b2SDimitry Andric return new (SemaRef.Context) concepts::NestedRequirement(
27531db9f3b2SDimitry Andric SemaRef.Context, TransConstraint.get(), Satisfaction);
27541db9f3b2SDimitry Andric }
275555e4f9d5SDimitry Andric
275655e4f9d5SDimitry Andric ExprResult TransConstraint;
275781ad6265SDimitry Andric ConstraintSatisfaction Satisfaction;
275855e4f9d5SDimitry Andric TemplateDeductionInfo Info(Req->getConstraintExpr()->getBeginLoc());
275955e4f9d5SDimitry Andric {
276055e4f9d5SDimitry Andric EnterExpressionEvaluationContext ContextRAII(
276155e4f9d5SDimitry Andric SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
276255e4f9d5SDimitry Andric Sema::SFINAETrap Trap(SemaRef);
276355e4f9d5SDimitry Andric Sema::InstantiatingTemplate ConstrInst(SemaRef,
276455e4f9d5SDimitry Andric Req->getConstraintExpr()->getBeginLoc(), Req, Info,
276555e4f9d5SDimitry Andric Req->getConstraintExpr()->getSourceRange());
276655e4f9d5SDimitry Andric if (ConstrInst.isInvalid())
276755e4f9d5SDimitry Andric return nullptr;
2768bdd1243dSDimitry Andric llvm::SmallVector<Expr *> Result;
2769bdd1243dSDimitry Andric if (!SemaRef.CheckConstraintSatisfaction(
2770bdd1243dSDimitry Andric nullptr, {Req->getConstraintExpr()}, Result, TemplateArgs,
2771bdd1243dSDimitry Andric Req->getConstraintExpr()->getSourceRange(), Satisfaction) &&
2772bdd1243dSDimitry Andric !Result.empty())
2773bdd1243dSDimitry Andric TransConstraint = Result[0];
2774bdd1243dSDimitry Andric assert(!Trap.hasErrorOccurred() && "Substitution failures must be handled "
2775bdd1243dSDimitry Andric "by CheckConstraintSatisfaction.");
277681ad6265SDimitry Andric }
27770fca6ea1SDimitry Andric ASTContext &C = SemaRef.Context;
2778bdd1243dSDimitry Andric if (TransConstraint.isUsable() &&
2779bdd1243dSDimitry Andric TransConstraint.get()->isInstantiationDependent())
27800fca6ea1SDimitry Andric return new (C) concepts::NestedRequirement(TransConstraint.get());
2781bdd1243dSDimitry Andric if (TransConstraint.isInvalid() || !TransConstraint.get() ||
2782bdd1243dSDimitry Andric Satisfaction.HasSubstitutionFailure()) {
2783bdd1243dSDimitry Andric SmallString<128> Entity;
2784bdd1243dSDimitry Andric llvm::raw_svector_ostream OS(Entity);
2785bdd1243dSDimitry Andric Req->getConstraintExpr()->printPretty(OS, nullptr,
2786bdd1243dSDimitry Andric SemaRef.getPrintingPolicy());
27870fca6ea1SDimitry Andric return new (C) concepts::NestedRequirement(
27880fca6ea1SDimitry Andric SemaRef.Context, C.backupStr(Entity), Satisfaction);
2789bdd1243dSDimitry Andric }
27900fca6ea1SDimitry Andric return new (C)
27910fca6ea1SDimitry Andric concepts::NestedRequirement(C, TransConstraint.get(), Satisfaction);
279255e4f9d5SDimitry Andric }
279355e4f9d5SDimitry Andric
SubstType(TypeSourceInfo * T,const MultiLevelTemplateArgumentList & Args,SourceLocation Loc,DeclarationName Entity,bool AllowDeducedTST)27940b57cec5SDimitry Andric TypeSourceInfo *Sema::SubstType(TypeSourceInfo *T,
27950b57cec5SDimitry Andric const MultiLevelTemplateArgumentList &Args,
27960b57cec5SDimitry Andric SourceLocation Loc,
27970b57cec5SDimitry Andric DeclarationName Entity,
27980b57cec5SDimitry Andric bool AllowDeducedTST) {
27990b57cec5SDimitry Andric assert(!CodeSynthesisContexts.empty() &&
28000b57cec5SDimitry Andric "Cannot perform an instantiation without some context on the "
28010b57cec5SDimitry Andric "instantiation stack");
28020b57cec5SDimitry Andric
28030b57cec5SDimitry Andric if (!T->getType()->isInstantiationDependentType() &&
28040b57cec5SDimitry Andric !T->getType()->isVariablyModifiedType())
28050b57cec5SDimitry Andric return T;
28060b57cec5SDimitry Andric
28070b57cec5SDimitry Andric TemplateInstantiator Instantiator(*this, Args, Loc, Entity);
28080b57cec5SDimitry Andric return AllowDeducedTST ? Instantiator.TransformTypeWithDeducedTST(T)
28090b57cec5SDimitry Andric : Instantiator.TransformType(T);
28100b57cec5SDimitry Andric }
28110b57cec5SDimitry Andric
SubstType(TypeLoc TL,const MultiLevelTemplateArgumentList & Args,SourceLocation Loc,DeclarationName Entity)28120b57cec5SDimitry Andric TypeSourceInfo *Sema::SubstType(TypeLoc TL,
28130b57cec5SDimitry Andric const MultiLevelTemplateArgumentList &Args,
28140b57cec5SDimitry Andric SourceLocation Loc,
28150b57cec5SDimitry Andric DeclarationName Entity) {
28160b57cec5SDimitry Andric assert(!CodeSynthesisContexts.empty() &&
28170b57cec5SDimitry Andric "Cannot perform an instantiation without some context on the "
28180b57cec5SDimitry Andric "instantiation stack");
28190b57cec5SDimitry Andric
28200b57cec5SDimitry Andric if (TL.getType().isNull())
28210b57cec5SDimitry Andric return nullptr;
28220b57cec5SDimitry Andric
28230b57cec5SDimitry Andric if (!TL.getType()->isInstantiationDependentType() &&
28240b57cec5SDimitry Andric !TL.getType()->isVariablyModifiedType()) {
28250b57cec5SDimitry Andric // FIXME: Make a copy of the TypeLoc data here, so that we can
28260b57cec5SDimitry Andric // return a new TypeSourceInfo. Inefficient!
28270b57cec5SDimitry Andric TypeLocBuilder TLB;
28280b57cec5SDimitry Andric TLB.pushFullCopy(TL);
28290b57cec5SDimitry Andric return TLB.getTypeSourceInfo(Context, TL.getType());
28300b57cec5SDimitry Andric }
28310b57cec5SDimitry Andric
28320b57cec5SDimitry Andric TemplateInstantiator Instantiator(*this, Args, Loc, Entity);
28330b57cec5SDimitry Andric TypeLocBuilder TLB;
28340b57cec5SDimitry Andric TLB.reserve(TL.getFullDataSize());
28350b57cec5SDimitry Andric QualType Result = Instantiator.TransformType(TLB, TL);
28360b57cec5SDimitry Andric if (Result.isNull())
28370b57cec5SDimitry Andric return nullptr;
28380b57cec5SDimitry Andric
28390b57cec5SDimitry Andric return TLB.getTypeSourceInfo(Context, Result);
28400b57cec5SDimitry Andric }
28410b57cec5SDimitry Andric
28420b57cec5SDimitry Andric /// Deprecated form of the above.
SubstType(QualType T,const MultiLevelTemplateArgumentList & TemplateArgs,SourceLocation Loc,DeclarationName Entity)28430b57cec5SDimitry Andric QualType Sema::SubstType(QualType T,
28440b57cec5SDimitry Andric const MultiLevelTemplateArgumentList &TemplateArgs,
28450b57cec5SDimitry Andric SourceLocation Loc, DeclarationName Entity) {
28460b57cec5SDimitry Andric assert(!CodeSynthesisContexts.empty() &&
28470b57cec5SDimitry Andric "Cannot perform an instantiation without some context on the "
28480b57cec5SDimitry Andric "instantiation stack");
28490b57cec5SDimitry Andric
28500b57cec5SDimitry Andric // If T is not a dependent type or a variably-modified type, there
28510b57cec5SDimitry Andric // is nothing to do.
28520b57cec5SDimitry Andric if (!T->isInstantiationDependentType() && !T->isVariablyModifiedType())
28530b57cec5SDimitry Andric return T;
28540b57cec5SDimitry Andric
28550b57cec5SDimitry Andric TemplateInstantiator Instantiator(*this, TemplateArgs, Loc, Entity);
28560b57cec5SDimitry Andric return Instantiator.TransformType(T);
28570b57cec5SDimitry Andric }
28580b57cec5SDimitry Andric
NeedsInstantiationAsFunctionType(TypeSourceInfo * T)28590b57cec5SDimitry Andric static bool NeedsInstantiationAsFunctionType(TypeSourceInfo *T) {
28600b57cec5SDimitry Andric if (T->getType()->isInstantiationDependentType() ||
28610b57cec5SDimitry Andric T->getType()->isVariablyModifiedType())
28620b57cec5SDimitry Andric return true;
28630b57cec5SDimitry Andric
28640b57cec5SDimitry Andric TypeLoc TL = T->getTypeLoc().IgnoreParens();
28650b57cec5SDimitry Andric if (!TL.getAs<FunctionProtoTypeLoc>())
28660b57cec5SDimitry Andric return false;
28670b57cec5SDimitry Andric
28680b57cec5SDimitry Andric FunctionProtoTypeLoc FP = TL.castAs<FunctionProtoTypeLoc>();
28690b57cec5SDimitry Andric for (ParmVarDecl *P : FP.getParams()) {
28700b57cec5SDimitry Andric // This must be synthesized from a typedef.
28710b57cec5SDimitry Andric if (!P) continue;
28720b57cec5SDimitry Andric
28730b57cec5SDimitry Andric // If there are any parameters, a new TypeSourceInfo that refers to the
28740b57cec5SDimitry Andric // instantiated parameters must be built.
28750b57cec5SDimitry Andric return true;
28760b57cec5SDimitry Andric }
28770b57cec5SDimitry Andric
28780b57cec5SDimitry Andric return false;
28790b57cec5SDimitry Andric }
28800b57cec5SDimitry Andric
SubstFunctionDeclType(TypeSourceInfo * T,const MultiLevelTemplateArgumentList & Args,SourceLocation Loc,DeclarationName Entity,CXXRecordDecl * ThisContext,Qualifiers ThisTypeQuals,bool EvaluateConstraints)28810b57cec5SDimitry Andric TypeSourceInfo *Sema::SubstFunctionDeclType(TypeSourceInfo *T,
28820b57cec5SDimitry Andric const MultiLevelTemplateArgumentList &Args,
28830b57cec5SDimitry Andric SourceLocation Loc,
28840b57cec5SDimitry Andric DeclarationName Entity,
28850b57cec5SDimitry Andric CXXRecordDecl *ThisContext,
2886bdd1243dSDimitry Andric Qualifiers ThisTypeQuals,
2887bdd1243dSDimitry Andric bool EvaluateConstraints) {
28880b57cec5SDimitry Andric assert(!CodeSynthesisContexts.empty() &&
28890b57cec5SDimitry Andric "Cannot perform an instantiation without some context on the "
28900b57cec5SDimitry Andric "instantiation stack");
28910b57cec5SDimitry Andric
28920b57cec5SDimitry Andric if (!NeedsInstantiationAsFunctionType(T))
28930b57cec5SDimitry Andric return T;
28940b57cec5SDimitry Andric
28950b57cec5SDimitry Andric TemplateInstantiator Instantiator(*this, Args, Loc, Entity);
2896bdd1243dSDimitry Andric Instantiator.setEvaluateConstraints(EvaluateConstraints);
28970b57cec5SDimitry Andric
28980b57cec5SDimitry Andric TypeLocBuilder TLB;
28990b57cec5SDimitry Andric
29000b57cec5SDimitry Andric TypeLoc TL = T->getTypeLoc();
29010b57cec5SDimitry Andric TLB.reserve(TL.getFullDataSize());
29020b57cec5SDimitry Andric
29030b57cec5SDimitry Andric QualType Result;
29040b57cec5SDimitry Andric
29050b57cec5SDimitry Andric if (FunctionProtoTypeLoc Proto =
29060b57cec5SDimitry Andric TL.IgnoreParens().getAs<FunctionProtoTypeLoc>()) {
29070b57cec5SDimitry Andric // Instantiate the type, other than its exception specification. The
29080b57cec5SDimitry Andric // exception specification is instantiated in InitFunctionInstantiation
29090b57cec5SDimitry Andric // once we've built the FunctionDecl.
29100b57cec5SDimitry Andric // FIXME: Set the exception specification to EST_Uninstantiated here,
29110b57cec5SDimitry Andric // instead of rebuilding the function type again later.
29120b57cec5SDimitry Andric Result = Instantiator.TransformFunctionProtoType(
29130b57cec5SDimitry Andric TLB, Proto, ThisContext, ThisTypeQuals,
29140b57cec5SDimitry Andric [](FunctionProtoType::ExceptionSpecInfo &ESI,
29150b57cec5SDimitry Andric bool &Changed) { return false; });
29160b57cec5SDimitry Andric } else {
29170b57cec5SDimitry Andric Result = Instantiator.TransformType(TLB, TL);
29180b57cec5SDimitry Andric }
29195f757f3fSDimitry Andric // When there are errors resolving types, clang may use IntTy as a fallback,
29205f757f3fSDimitry Andric // breaking our assumption that function declarations have function types.
29215f757f3fSDimitry Andric if (Result.isNull() || !Result->isFunctionType())
29220b57cec5SDimitry Andric return nullptr;
29230b57cec5SDimitry Andric
29240b57cec5SDimitry Andric return TLB.getTypeSourceInfo(Context, Result);
29250b57cec5SDimitry Andric }
29260b57cec5SDimitry Andric
SubstExceptionSpec(SourceLocation Loc,FunctionProtoType::ExceptionSpecInfo & ESI,SmallVectorImpl<QualType> & ExceptionStorage,const MultiLevelTemplateArgumentList & Args)29270b57cec5SDimitry Andric bool Sema::SubstExceptionSpec(SourceLocation Loc,
29280b57cec5SDimitry Andric FunctionProtoType::ExceptionSpecInfo &ESI,
29290b57cec5SDimitry Andric SmallVectorImpl<QualType> &ExceptionStorage,
29300b57cec5SDimitry Andric const MultiLevelTemplateArgumentList &Args) {
29310b57cec5SDimitry Andric bool Changed = false;
29320b57cec5SDimitry Andric TemplateInstantiator Instantiator(*this, Args, Loc, DeclarationName());
29330b57cec5SDimitry Andric return Instantiator.TransformExceptionSpec(Loc, ESI, ExceptionStorage,
29340b57cec5SDimitry Andric Changed);
29350b57cec5SDimitry Andric }
29360b57cec5SDimitry Andric
SubstExceptionSpec(FunctionDecl * New,const FunctionProtoType * Proto,const MultiLevelTemplateArgumentList & Args)29370b57cec5SDimitry Andric void Sema::SubstExceptionSpec(FunctionDecl *New, const FunctionProtoType *Proto,
29380b57cec5SDimitry Andric const MultiLevelTemplateArgumentList &Args) {
29390b57cec5SDimitry Andric FunctionProtoType::ExceptionSpecInfo ESI =
29400b57cec5SDimitry Andric Proto->getExtProtoInfo().ExceptionSpec;
29410b57cec5SDimitry Andric
29420b57cec5SDimitry Andric SmallVector<QualType, 4> ExceptionStorage;
29430b57cec5SDimitry Andric if (SubstExceptionSpec(New->getTypeSourceInfo()->getTypeLoc().getEndLoc(),
29440b57cec5SDimitry Andric ESI, ExceptionStorage, Args))
29450b57cec5SDimitry Andric // On error, recover by dropping the exception specification.
29460b57cec5SDimitry Andric ESI.Type = EST_None;
29470b57cec5SDimitry Andric
29480b57cec5SDimitry Andric UpdateExceptionSpec(New, ESI);
29490b57cec5SDimitry Andric }
29500b57cec5SDimitry Andric
295113138422SDimitry Andric namespace {
295213138422SDimitry Andric
295313138422SDimitry Andric struct GetContainedInventedTypeParmVisitor :
295413138422SDimitry Andric public TypeVisitor<GetContainedInventedTypeParmVisitor,
295513138422SDimitry Andric TemplateTypeParmDecl *> {
295613138422SDimitry Andric using TypeVisitor<GetContainedInventedTypeParmVisitor,
295713138422SDimitry Andric TemplateTypeParmDecl *>::Visit;
295813138422SDimitry Andric
Visit__anondb690eb50911::GetContainedInventedTypeParmVisitor295913138422SDimitry Andric TemplateTypeParmDecl *Visit(QualType T) {
296013138422SDimitry Andric if (T.isNull())
296113138422SDimitry Andric return nullptr;
296213138422SDimitry Andric return Visit(T.getTypePtr());
296313138422SDimitry Andric }
296413138422SDimitry Andric // The deduced type itself.
VisitTemplateTypeParmType__anondb690eb50911::GetContainedInventedTypeParmVisitor296513138422SDimitry Andric TemplateTypeParmDecl *VisitTemplateTypeParmType(
296613138422SDimitry Andric const TemplateTypeParmType *T) {
2967cd675bb6SDimitry Andric if (!T->getDecl() || !T->getDecl()->isImplicit())
296813138422SDimitry Andric return nullptr;
296913138422SDimitry Andric return T->getDecl();
297013138422SDimitry Andric }
297113138422SDimitry Andric
297213138422SDimitry Andric // Only these types can contain 'auto' types, and subsequently be replaced
297313138422SDimitry Andric // by references to invented parameters.
297413138422SDimitry Andric
VisitElaboratedType__anondb690eb50911::GetContainedInventedTypeParmVisitor297513138422SDimitry Andric TemplateTypeParmDecl *VisitElaboratedType(const ElaboratedType *T) {
297613138422SDimitry Andric return Visit(T->getNamedType());
297713138422SDimitry Andric }
297813138422SDimitry Andric
VisitPointerType__anondb690eb50911::GetContainedInventedTypeParmVisitor297913138422SDimitry Andric TemplateTypeParmDecl *VisitPointerType(const PointerType *T) {
298013138422SDimitry Andric return Visit(T->getPointeeType());
298113138422SDimitry Andric }
298213138422SDimitry Andric
VisitBlockPointerType__anondb690eb50911::GetContainedInventedTypeParmVisitor298313138422SDimitry Andric TemplateTypeParmDecl *VisitBlockPointerType(const BlockPointerType *T) {
298413138422SDimitry Andric return Visit(T->getPointeeType());
298513138422SDimitry Andric }
298613138422SDimitry Andric
VisitReferenceType__anondb690eb50911::GetContainedInventedTypeParmVisitor298713138422SDimitry Andric TemplateTypeParmDecl *VisitReferenceType(const ReferenceType *T) {
298813138422SDimitry Andric return Visit(T->getPointeeTypeAsWritten());
298913138422SDimitry Andric }
299013138422SDimitry Andric
VisitMemberPointerType__anondb690eb50911::GetContainedInventedTypeParmVisitor299113138422SDimitry Andric TemplateTypeParmDecl *VisitMemberPointerType(const MemberPointerType *T) {
299213138422SDimitry Andric return Visit(T->getPointeeType());
299313138422SDimitry Andric }
299413138422SDimitry Andric
VisitArrayType__anondb690eb50911::GetContainedInventedTypeParmVisitor299513138422SDimitry Andric TemplateTypeParmDecl *VisitArrayType(const ArrayType *T) {
299613138422SDimitry Andric return Visit(T->getElementType());
299713138422SDimitry Andric }
299813138422SDimitry Andric
VisitDependentSizedExtVectorType__anondb690eb50911::GetContainedInventedTypeParmVisitor299913138422SDimitry Andric TemplateTypeParmDecl *VisitDependentSizedExtVectorType(
300013138422SDimitry Andric const DependentSizedExtVectorType *T) {
300113138422SDimitry Andric return Visit(T->getElementType());
300213138422SDimitry Andric }
300313138422SDimitry Andric
VisitVectorType__anondb690eb50911::GetContainedInventedTypeParmVisitor300413138422SDimitry Andric TemplateTypeParmDecl *VisitVectorType(const VectorType *T) {
300513138422SDimitry Andric return Visit(T->getElementType());
300613138422SDimitry Andric }
300713138422SDimitry Andric
VisitFunctionProtoType__anondb690eb50911::GetContainedInventedTypeParmVisitor300813138422SDimitry Andric TemplateTypeParmDecl *VisitFunctionProtoType(const FunctionProtoType *T) {
300913138422SDimitry Andric return VisitFunctionType(T);
301013138422SDimitry Andric }
301113138422SDimitry Andric
VisitFunctionType__anondb690eb50911::GetContainedInventedTypeParmVisitor301213138422SDimitry Andric TemplateTypeParmDecl *VisitFunctionType(const FunctionType *T) {
301313138422SDimitry Andric return Visit(T->getReturnType());
301413138422SDimitry Andric }
301513138422SDimitry Andric
VisitParenType__anondb690eb50911::GetContainedInventedTypeParmVisitor301613138422SDimitry Andric TemplateTypeParmDecl *VisitParenType(const ParenType *T) {
301713138422SDimitry Andric return Visit(T->getInnerType());
301813138422SDimitry Andric }
301913138422SDimitry Andric
VisitAttributedType__anondb690eb50911::GetContainedInventedTypeParmVisitor302013138422SDimitry Andric TemplateTypeParmDecl *VisitAttributedType(const AttributedType *T) {
302113138422SDimitry Andric return Visit(T->getModifiedType());
302213138422SDimitry Andric }
302313138422SDimitry Andric
VisitMacroQualifiedType__anondb690eb50911::GetContainedInventedTypeParmVisitor302413138422SDimitry Andric TemplateTypeParmDecl *VisitMacroQualifiedType(const MacroQualifiedType *T) {
302513138422SDimitry Andric return Visit(T->getUnderlyingType());
302613138422SDimitry Andric }
302713138422SDimitry Andric
VisitAdjustedType__anondb690eb50911::GetContainedInventedTypeParmVisitor302813138422SDimitry Andric TemplateTypeParmDecl *VisitAdjustedType(const AdjustedType *T) {
302913138422SDimitry Andric return Visit(T->getOriginalType());
303013138422SDimitry Andric }
303113138422SDimitry Andric
VisitPackExpansionType__anondb690eb50911::GetContainedInventedTypeParmVisitor303213138422SDimitry Andric TemplateTypeParmDecl *VisitPackExpansionType(const PackExpansionType *T) {
303313138422SDimitry Andric return Visit(T->getPattern());
303413138422SDimitry Andric }
303513138422SDimitry Andric };
303613138422SDimitry Andric
303713138422SDimitry Andric } // namespace
303813138422SDimitry Andric
SubstTypeConstraint(TemplateTypeParmDecl * Inst,const TypeConstraint * TC,const MultiLevelTemplateArgumentList & TemplateArgs,bool EvaluateConstraints)3039349cc55cSDimitry Andric bool Sema::SubstTypeConstraint(
3040349cc55cSDimitry Andric TemplateTypeParmDecl *Inst, const TypeConstraint *TC,
3041bdd1243dSDimitry Andric const MultiLevelTemplateArgumentList &TemplateArgs,
3042bdd1243dSDimitry Andric bool EvaluateConstraints) {
3043349cc55cSDimitry Andric const ASTTemplateArgumentListInfo *TemplArgInfo =
3044349cc55cSDimitry Andric TC->getTemplateArgsAsWritten();
3045bdd1243dSDimitry Andric
3046bdd1243dSDimitry Andric if (!EvaluateConstraints) {
30475f757f3fSDimitry Andric Inst->setTypeConstraint(TC->getConceptReference(),
3048bdd1243dSDimitry Andric TC->getImmediatelyDeclaredConstraint());
3049bdd1243dSDimitry Andric return false;
3050bdd1243dSDimitry Andric }
3051bdd1243dSDimitry Andric
3052349cc55cSDimitry Andric TemplateArgumentListInfo InstArgs;
3053349cc55cSDimitry Andric
3054349cc55cSDimitry Andric if (TemplArgInfo) {
3055349cc55cSDimitry Andric InstArgs.setLAngleLoc(TemplArgInfo->LAngleLoc);
3056349cc55cSDimitry Andric InstArgs.setRAngleLoc(TemplArgInfo->RAngleLoc);
3057349cc55cSDimitry Andric if (SubstTemplateArguments(TemplArgInfo->arguments(), TemplateArgs,
3058349cc55cSDimitry Andric InstArgs))
3059349cc55cSDimitry Andric return true;
3060349cc55cSDimitry Andric }
3061349cc55cSDimitry Andric return AttachTypeConstraint(
3062349cc55cSDimitry Andric TC->getNestedNameSpecifierLoc(), TC->getConceptNameInfo(),
30630fca6ea1SDimitry Andric TC->getNamedConcept(),
30640fca6ea1SDimitry Andric /*FoundDecl=*/TC->getConceptReference()->getFoundDecl(), &InstArgs, Inst,
3065349cc55cSDimitry Andric Inst->isParameterPack()
3066349cc55cSDimitry Andric ? cast<CXXFoldExpr>(TC->getImmediatelyDeclaredConstraint())
3067349cc55cSDimitry Andric ->getEllipsisLoc()
3068349cc55cSDimitry Andric : SourceLocation());
3069349cc55cSDimitry Andric }
3070349cc55cSDimitry Andric
SubstParmVarDecl(ParmVarDecl * OldParm,const MultiLevelTemplateArgumentList & TemplateArgs,int indexAdjustment,std::optional<unsigned> NumExpansions,bool ExpectParameterPack,bool EvaluateConstraint)3071bdd1243dSDimitry Andric ParmVarDecl *Sema::SubstParmVarDecl(
3072bdd1243dSDimitry Andric ParmVarDecl *OldParm, const MultiLevelTemplateArgumentList &TemplateArgs,
3073bdd1243dSDimitry Andric int indexAdjustment, std::optional<unsigned> NumExpansions,
3074bdd1243dSDimitry Andric bool ExpectParameterPack, bool EvaluateConstraint) {
30750b57cec5SDimitry Andric TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
30760b57cec5SDimitry Andric TypeSourceInfo *NewDI = nullptr;
30770b57cec5SDimitry Andric
30780b57cec5SDimitry Andric TypeLoc OldTL = OldDI->getTypeLoc();
30790b57cec5SDimitry Andric if (PackExpansionTypeLoc ExpansionTL = OldTL.getAs<PackExpansionTypeLoc>()) {
30800b57cec5SDimitry Andric
30810b57cec5SDimitry Andric // We have a function parameter pack. Substitute into the pattern of the
30820b57cec5SDimitry Andric // expansion.
30830b57cec5SDimitry Andric NewDI = SubstType(ExpansionTL.getPatternLoc(), TemplateArgs,
30840b57cec5SDimitry Andric OldParm->getLocation(), OldParm->getDeclName());
30850b57cec5SDimitry Andric if (!NewDI)
30860b57cec5SDimitry Andric return nullptr;
30870b57cec5SDimitry Andric
30880b57cec5SDimitry Andric if (NewDI->getType()->containsUnexpandedParameterPack()) {
30890b57cec5SDimitry Andric // We still have unexpanded parameter packs, which means that
30900b57cec5SDimitry Andric // our function parameter is still a function parameter pack.
30910b57cec5SDimitry Andric // Therefore, make its type a pack expansion type.
30920b57cec5SDimitry Andric NewDI = CheckPackExpansion(NewDI, ExpansionTL.getEllipsisLoc(),
30930b57cec5SDimitry Andric NumExpansions);
30940b57cec5SDimitry Andric } else if (ExpectParameterPack) {
30950b57cec5SDimitry Andric // We expected to get a parameter pack but didn't (because the type
30960b57cec5SDimitry Andric // itself is not a pack expansion type), so complain. This can occur when
30970b57cec5SDimitry Andric // the substitution goes through an alias template that "loses" the
30980b57cec5SDimitry Andric // pack expansion.
30990b57cec5SDimitry Andric Diag(OldParm->getLocation(),
31000b57cec5SDimitry Andric diag::err_function_parameter_pack_without_parameter_packs)
31010b57cec5SDimitry Andric << NewDI->getType();
31020b57cec5SDimitry Andric return nullptr;
31030b57cec5SDimitry Andric }
31040b57cec5SDimitry Andric } else {
31050b57cec5SDimitry Andric NewDI = SubstType(OldDI, TemplateArgs, OldParm->getLocation(),
31060b57cec5SDimitry Andric OldParm->getDeclName());
31070b57cec5SDimitry Andric }
31080b57cec5SDimitry Andric
31090b57cec5SDimitry Andric if (!NewDI)
31100b57cec5SDimitry Andric return nullptr;
31110b57cec5SDimitry Andric
31120b57cec5SDimitry Andric if (NewDI->getType()->isVoidType()) {
31130b57cec5SDimitry Andric Diag(OldParm->getLocation(), diag::err_param_with_void_type);
31140b57cec5SDimitry Andric return nullptr;
31150b57cec5SDimitry Andric }
31160b57cec5SDimitry Andric
311713138422SDimitry Andric // In abbreviated templates, TemplateTypeParmDecls with possible
311813138422SDimitry Andric // TypeConstraints are created when the parameter list is originally parsed.
311913138422SDimitry Andric // The TypeConstraints can therefore reference other functions parameters in
312013138422SDimitry Andric // the abbreviated function template, which is why we must instantiate them
312113138422SDimitry Andric // here, when the instantiated versions of those referenced parameters are in
312213138422SDimitry Andric // scope.
312313138422SDimitry Andric if (TemplateTypeParmDecl *TTP =
312413138422SDimitry Andric GetContainedInventedTypeParmVisitor().Visit(OldDI->getType())) {
312513138422SDimitry Andric if (const TypeConstraint *TC = TTP->getTypeConstraint()) {
312613138422SDimitry Andric auto *Inst = cast_or_null<TemplateTypeParmDecl>(
312713138422SDimitry Andric FindInstantiatedDecl(TTP->getLocation(), TTP, TemplateArgs));
312813138422SDimitry Andric // We will first get here when instantiating the abbreviated function
312913138422SDimitry Andric // template's described function, but we might also get here later.
313013138422SDimitry Andric // Make sure we do not instantiate the TypeConstraint more than once.
313113138422SDimitry Andric if (Inst && !Inst->getTypeConstraint()) {
3132bdd1243dSDimitry Andric if (SubstTypeConstraint(Inst, TC, TemplateArgs, EvaluateConstraint))
313313138422SDimitry Andric return nullptr;
313413138422SDimitry Andric }
313513138422SDimitry Andric }
313613138422SDimitry Andric }
313713138422SDimitry Andric
31380b57cec5SDimitry Andric ParmVarDecl *NewParm = CheckParameter(Context.getTranslationUnitDecl(),
31390b57cec5SDimitry Andric OldParm->getInnerLocStart(),
31400b57cec5SDimitry Andric OldParm->getLocation(),
31410b57cec5SDimitry Andric OldParm->getIdentifier(),
31420b57cec5SDimitry Andric NewDI->getType(), NewDI,
31430b57cec5SDimitry Andric OldParm->getStorageClass());
31440b57cec5SDimitry Andric if (!NewParm)
31450b57cec5SDimitry Andric return nullptr;
31460b57cec5SDimitry Andric
31470b57cec5SDimitry Andric // Mark the (new) default argument as uninstantiated (if any).
31480b57cec5SDimitry Andric if (OldParm->hasUninstantiatedDefaultArg()) {
31490b57cec5SDimitry Andric Expr *Arg = OldParm->getUninstantiatedDefaultArg();
31500b57cec5SDimitry Andric NewParm->setUninstantiatedDefaultArg(Arg);
31510b57cec5SDimitry Andric } else if (OldParm->hasUnparsedDefaultArg()) {
31520b57cec5SDimitry Andric NewParm->setUnparsedDefaultArg();
31530b57cec5SDimitry Andric UnparsedDefaultArgInstantiations[OldParm].push_back(NewParm);
31540b57cec5SDimitry Andric } else if (Expr *Arg = OldParm->getDefaultArg()) {
3155bdd1243dSDimitry Andric // Default arguments cannot be substituted until the declaration context
3156bdd1243dSDimitry Andric // for the associated function or lambda capture class is available.
3157bdd1243dSDimitry Andric // This is necessary for cases like the following where construction of
3158bdd1243dSDimitry Andric // the lambda capture class for the outer lambda is dependent on the
3159bdd1243dSDimitry Andric // parameter types but where the default argument is dependent on the
3160bdd1243dSDimitry Andric // outer lambda's declaration context.
3161bdd1243dSDimitry Andric // template <typename T>
3162bdd1243dSDimitry Andric // auto f() {
3163bdd1243dSDimitry Andric // return [](T = []{ return T{}; }()) { return 0; };
3164bdd1243dSDimitry Andric // }
31650b57cec5SDimitry Andric NewParm->setUninstantiatedDefaultArg(Arg);
31660b57cec5SDimitry Andric }
31670b57cec5SDimitry Andric
31685f757f3fSDimitry Andric NewParm->setExplicitObjectParameterLoc(
31695f757f3fSDimitry Andric OldParm->getExplicitObjectParamThisLoc());
31700b57cec5SDimitry Andric NewParm->setHasInheritedDefaultArg(OldParm->hasInheritedDefaultArg());
31710b57cec5SDimitry Andric
31720b57cec5SDimitry Andric if (OldParm->isParameterPack() && !NewParm->isParameterPack()) {
31730b57cec5SDimitry Andric // Add the new parameter to the instantiated parameter pack.
31740b57cec5SDimitry Andric CurrentInstantiationScope->InstantiatedLocalPackArg(OldParm, NewParm);
31750b57cec5SDimitry Andric } else {
31760b57cec5SDimitry Andric // Introduce an Old -> New mapping
31770b57cec5SDimitry Andric CurrentInstantiationScope->InstantiatedLocal(OldParm, NewParm);
31780b57cec5SDimitry Andric }
31790b57cec5SDimitry Andric
31800b57cec5SDimitry Andric // FIXME: OldParm may come from a FunctionProtoType, in which case CurContext
31810b57cec5SDimitry Andric // can be anything, is this right ?
31820b57cec5SDimitry Andric NewParm->setDeclContext(CurContext);
31830b57cec5SDimitry Andric
31840b57cec5SDimitry Andric NewParm->setScopeInfo(OldParm->getFunctionScopeDepth(),
31850b57cec5SDimitry Andric OldParm->getFunctionScopeIndex() + indexAdjustment);
31860b57cec5SDimitry Andric
31870b57cec5SDimitry Andric InstantiateAttrs(TemplateArgs, OldParm, NewParm);
31880b57cec5SDimitry Andric
31890b57cec5SDimitry Andric return NewParm;
31900b57cec5SDimitry Andric }
31910b57cec5SDimitry Andric
SubstParmTypes(SourceLocation Loc,ArrayRef<ParmVarDecl * > Params,const FunctionProtoType::ExtParameterInfo * ExtParamInfos,const MultiLevelTemplateArgumentList & TemplateArgs,SmallVectorImpl<QualType> & ParamTypes,SmallVectorImpl<ParmVarDecl * > * OutParams,ExtParameterInfoBuilder & ParamInfos)31920b57cec5SDimitry Andric bool Sema::SubstParmTypes(
31930b57cec5SDimitry Andric SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
31940b57cec5SDimitry Andric const FunctionProtoType::ExtParameterInfo *ExtParamInfos,
31950b57cec5SDimitry Andric const MultiLevelTemplateArgumentList &TemplateArgs,
31960b57cec5SDimitry Andric SmallVectorImpl<QualType> &ParamTypes,
31970b57cec5SDimitry Andric SmallVectorImpl<ParmVarDecl *> *OutParams,
31980b57cec5SDimitry Andric ExtParameterInfoBuilder &ParamInfos) {
31990b57cec5SDimitry Andric assert(!CodeSynthesisContexts.empty() &&
32000b57cec5SDimitry Andric "Cannot perform an instantiation without some context on the "
32010b57cec5SDimitry Andric "instantiation stack");
32020b57cec5SDimitry Andric
32030b57cec5SDimitry Andric TemplateInstantiator Instantiator(*this, TemplateArgs, Loc,
32040b57cec5SDimitry Andric DeclarationName());
32050b57cec5SDimitry Andric return Instantiator.TransformFunctionTypeParams(
32060b57cec5SDimitry Andric Loc, Params, nullptr, ExtParamInfos, ParamTypes, OutParams, ParamInfos);
32070b57cec5SDimitry Andric }
32080b57cec5SDimitry Andric
SubstDefaultArgument(SourceLocation Loc,ParmVarDecl * Param,const MultiLevelTemplateArgumentList & TemplateArgs,bool ForCallExpr)3209bdd1243dSDimitry Andric bool Sema::SubstDefaultArgument(
3210bdd1243dSDimitry Andric SourceLocation Loc,
3211bdd1243dSDimitry Andric ParmVarDecl *Param,
3212bdd1243dSDimitry Andric const MultiLevelTemplateArgumentList &TemplateArgs,
3213bdd1243dSDimitry Andric bool ForCallExpr) {
3214bdd1243dSDimitry Andric FunctionDecl *FD = cast<FunctionDecl>(Param->getDeclContext());
3215bdd1243dSDimitry Andric Expr *PatternExpr = Param->getUninstantiatedDefaultArg();
3216bdd1243dSDimitry Andric
3217bdd1243dSDimitry Andric EnterExpressionEvaluationContext EvalContext(
3218bdd1243dSDimitry Andric *this, ExpressionEvaluationContext::PotentiallyEvaluated, Param);
3219bdd1243dSDimitry Andric
3220bdd1243dSDimitry Andric InstantiatingTemplate Inst(*this, Loc, Param, TemplateArgs.getInnermost());
3221bdd1243dSDimitry Andric if (Inst.isInvalid())
3222bdd1243dSDimitry Andric return true;
3223bdd1243dSDimitry Andric if (Inst.isAlreadyInstantiating()) {
3224bdd1243dSDimitry Andric Diag(Param->getBeginLoc(), diag::err_recursive_default_argument) << FD;
3225bdd1243dSDimitry Andric Param->setInvalidDecl();
3226bdd1243dSDimitry Andric return true;
3227bdd1243dSDimitry Andric }
3228bdd1243dSDimitry Andric
3229bdd1243dSDimitry Andric ExprResult Result;
3230bdd1243dSDimitry Andric {
3231bdd1243dSDimitry Andric // C++ [dcl.fct.default]p5:
3232bdd1243dSDimitry Andric // The names in the [default argument] expression are bound, and
3233bdd1243dSDimitry Andric // the semantic constraints are checked, at the point where the
3234bdd1243dSDimitry Andric // default argument expression appears.
3235bdd1243dSDimitry Andric ContextRAII SavedContext(*this, FD);
3236bdd1243dSDimitry Andric std::unique_ptr<LocalInstantiationScope> LIS;
3237bdd1243dSDimitry Andric
3238bdd1243dSDimitry Andric if (ForCallExpr) {
3239bdd1243dSDimitry Andric // When instantiating a default argument due to use in a call expression,
3240bdd1243dSDimitry Andric // an instantiation scope that includes the parameters of the callee is
3241bdd1243dSDimitry Andric // required to satisfy references from the default argument. For example:
3242bdd1243dSDimitry Andric // template<typename T> void f(T a, int = decltype(a)());
3243bdd1243dSDimitry Andric // void g() { f(0); }
3244bdd1243dSDimitry Andric LIS = std::make_unique<LocalInstantiationScope>(*this);
3245bdd1243dSDimitry Andric FunctionDecl *PatternFD = FD->getTemplateInstantiationPattern(
3246bdd1243dSDimitry Andric /*ForDefinition*/ false);
3247bdd1243dSDimitry Andric if (addInstantiatedParametersToScope(FD, PatternFD, *LIS, TemplateArgs))
3248bdd1243dSDimitry Andric return true;
3249bdd1243dSDimitry Andric }
3250bdd1243dSDimitry Andric
3251bdd1243dSDimitry Andric runWithSufficientStackSpace(Loc, [&] {
3252*ffc5ee0fSDimitry Andric Result = SubstInitializer(PatternExpr, TemplateArgs,
3253bdd1243dSDimitry Andric /*DirectInit*/ false);
3254bdd1243dSDimitry Andric });
3255bdd1243dSDimitry Andric }
3256bdd1243dSDimitry Andric if (Result.isInvalid())
3257bdd1243dSDimitry Andric return true;
3258bdd1243dSDimitry Andric
3259bdd1243dSDimitry Andric if (ForCallExpr) {
3260bdd1243dSDimitry Andric // Check the expression as an initializer for the parameter.
3261bdd1243dSDimitry Andric InitializedEntity Entity
3262bdd1243dSDimitry Andric = InitializedEntity::InitializeParameter(Context, Param);
3263bdd1243dSDimitry Andric InitializationKind Kind = InitializationKind::CreateCopy(
3264bdd1243dSDimitry Andric Param->getLocation(),
3265bdd1243dSDimitry Andric /*FIXME:EqualLoc*/ PatternExpr->getBeginLoc());
3266bdd1243dSDimitry Andric Expr *ResultE = Result.getAs<Expr>();
3267bdd1243dSDimitry Andric
3268bdd1243dSDimitry Andric InitializationSequence InitSeq(*this, Entity, Kind, ResultE);
3269bdd1243dSDimitry Andric Result = InitSeq.Perform(*this, Entity, Kind, ResultE);
3270bdd1243dSDimitry Andric if (Result.isInvalid())
3271bdd1243dSDimitry Andric return true;
3272bdd1243dSDimitry Andric
3273bdd1243dSDimitry Andric Result =
3274bdd1243dSDimitry Andric ActOnFinishFullExpr(Result.getAs<Expr>(), Param->getOuterLocStart(),
3275bdd1243dSDimitry Andric /*DiscardedValue*/ false);
3276bdd1243dSDimitry Andric } else {
3277bdd1243dSDimitry Andric // FIXME: Obtain the source location for the '=' token.
3278bdd1243dSDimitry Andric SourceLocation EqualLoc = PatternExpr->getBeginLoc();
3279bdd1243dSDimitry Andric Result = ConvertParamDefaultArgument(Param, Result.getAs<Expr>(), EqualLoc);
3280bdd1243dSDimitry Andric }
3281bdd1243dSDimitry Andric if (Result.isInvalid())
3282bdd1243dSDimitry Andric return true;
3283bdd1243dSDimitry Andric
3284bdd1243dSDimitry Andric // Remember the instantiated default argument.
3285bdd1243dSDimitry Andric Param->setDefaultArg(Result.getAs<Expr>());
3286bdd1243dSDimitry Andric
3287bdd1243dSDimitry Andric return false;
3288bdd1243dSDimitry Andric }
3289bdd1243dSDimitry Andric
32900b57cec5SDimitry Andric bool
SubstBaseSpecifiers(CXXRecordDecl * Instantiation,CXXRecordDecl * Pattern,const MultiLevelTemplateArgumentList & TemplateArgs)32910b57cec5SDimitry Andric Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
32920b57cec5SDimitry Andric CXXRecordDecl *Pattern,
32930b57cec5SDimitry Andric const MultiLevelTemplateArgumentList &TemplateArgs) {
32940b57cec5SDimitry Andric bool Invalid = false;
32950b57cec5SDimitry Andric SmallVector<CXXBaseSpecifier*, 4> InstantiatedBases;
32960b57cec5SDimitry Andric for (const auto &Base : Pattern->bases()) {
32970b57cec5SDimitry Andric if (!Base.getType()->isDependentType()) {
32980b57cec5SDimitry Andric if (const CXXRecordDecl *RD = Base.getType()->getAsCXXRecordDecl()) {
32990b57cec5SDimitry Andric if (RD->isInvalidDecl())
33000b57cec5SDimitry Andric Instantiation->setInvalidDecl();
33010b57cec5SDimitry Andric }
33020b57cec5SDimitry Andric InstantiatedBases.push_back(new (Context) CXXBaseSpecifier(Base));
33030b57cec5SDimitry Andric continue;
33040b57cec5SDimitry Andric }
33050b57cec5SDimitry Andric
33060b57cec5SDimitry Andric SourceLocation EllipsisLoc;
33070b57cec5SDimitry Andric TypeSourceInfo *BaseTypeLoc;
33080b57cec5SDimitry Andric if (Base.isPackExpansion()) {
33090b57cec5SDimitry Andric // This is a pack expansion. See whether we should expand it now, or
33100b57cec5SDimitry Andric // wait until later.
33110b57cec5SDimitry Andric SmallVector<UnexpandedParameterPack, 2> Unexpanded;
33120b57cec5SDimitry Andric collectUnexpandedParameterPacks(Base.getTypeSourceInfo()->getTypeLoc(),
33130b57cec5SDimitry Andric Unexpanded);
33140b57cec5SDimitry Andric bool ShouldExpand = false;
33150b57cec5SDimitry Andric bool RetainExpansion = false;
3316bdd1243dSDimitry Andric std::optional<unsigned> NumExpansions;
33170b57cec5SDimitry Andric if (CheckParameterPacksForExpansion(Base.getEllipsisLoc(),
33180b57cec5SDimitry Andric Base.getSourceRange(),
33190b57cec5SDimitry Andric Unexpanded,
33200b57cec5SDimitry Andric TemplateArgs, ShouldExpand,
33210b57cec5SDimitry Andric RetainExpansion,
33220b57cec5SDimitry Andric NumExpansions)) {
33230b57cec5SDimitry Andric Invalid = true;
33240b57cec5SDimitry Andric continue;
33250b57cec5SDimitry Andric }
33260b57cec5SDimitry Andric
33270b57cec5SDimitry Andric // If we should expand this pack expansion now, do so.
33280b57cec5SDimitry Andric if (ShouldExpand) {
33290b57cec5SDimitry Andric for (unsigned I = 0; I != *NumExpansions; ++I) {
33300b57cec5SDimitry Andric Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, I);
33310b57cec5SDimitry Andric
33320b57cec5SDimitry Andric TypeSourceInfo *BaseTypeLoc = SubstType(Base.getTypeSourceInfo(),
33330b57cec5SDimitry Andric TemplateArgs,
33340b57cec5SDimitry Andric Base.getSourceRange().getBegin(),
33350b57cec5SDimitry Andric DeclarationName());
33360b57cec5SDimitry Andric if (!BaseTypeLoc) {
33370b57cec5SDimitry Andric Invalid = true;
33380b57cec5SDimitry Andric continue;
33390b57cec5SDimitry Andric }
33400b57cec5SDimitry Andric
33410b57cec5SDimitry Andric if (CXXBaseSpecifier *InstantiatedBase
33420b57cec5SDimitry Andric = CheckBaseSpecifier(Instantiation,
33430b57cec5SDimitry Andric Base.getSourceRange(),
33440b57cec5SDimitry Andric Base.isVirtual(),
33450b57cec5SDimitry Andric Base.getAccessSpecifierAsWritten(),
33460b57cec5SDimitry Andric BaseTypeLoc,
33470b57cec5SDimitry Andric SourceLocation()))
33480b57cec5SDimitry Andric InstantiatedBases.push_back(InstantiatedBase);
33490b57cec5SDimitry Andric else
33500b57cec5SDimitry Andric Invalid = true;
33510b57cec5SDimitry Andric }
33520b57cec5SDimitry Andric
33530b57cec5SDimitry Andric continue;
33540b57cec5SDimitry Andric }
33550b57cec5SDimitry Andric
33560b57cec5SDimitry Andric // The resulting base specifier will (still) be a pack expansion.
33570b57cec5SDimitry Andric EllipsisLoc = Base.getEllipsisLoc();
33580b57cec5SDimitry Andric Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, -1);
33590b57cec5SDimitry Andric BaseTypeLoc = SubstType(Base.getTypeSourceInfo(),
33600b57cec5SDimitry Andric TemplateArgs,
33610b57cec5SDimitry Andric Base.getSourceRange().getBegin(),
33620b57cec5SDimitry Andric DeclarationName());
33630b57cec5SDimitry Andric } else {
33640b57cec5SDimitry Andric BaseTypeLoc = SubstType(Base.getTypeSourceInfo(),
33650b57cec5SDimitry Andric TemplateArgs,
33660b57cec5SDimitry Andric Base.getSourceRange().getBegin(),
33670b57cec5SDimitry Andric DeclarationName());
33680b57cec5SDimitry Andric }
33690b57cec5SDimitry Andric
33700b57cec5SDimitry Andric if (!BaseTypeLoc) {
33710b57cec5SDimitry Andric Invalid = true;
33720b57cec5SDimitry Andric continue;
33730b57cec5SDimitry Andric }
33740b57cec5SDimitry Andric
33750b57cec5SDimitry Andric if (CXXBaseSpecifier *InstantiatedBase
33760b57cec5SDimitry Andric = CheckBaseSpecifier(Instantiation,
33770b57cec5SDimitry Andric Base.getSourceRange(),
33780b57cec5SDimitry Andric Base.isVirtual(),
33790b57cec5SDimitry Andric Base.getAccessSpecifierAsWritten(),
33800b57cec5SDimitry Andric BaseTypeLoc,
33810b57cec5SDimitry Andric EllipsisLoc))
33820b57cec5SDimitry Andric InstantiatedBases.push_back(InstantiatedBase);
33830b57cec5SDimitry Andric else
33840b57cec5SDimitry Andric Invalid = true;
33850b57cec5SDimitry Andric }
33860b57cec5SDimitry Andric
33870b57cec5SDimitry Andric if (!Invalid && AttachBaseSpecifiers(Instantiation, InstantiatedBases))
33880b57cec5SDimitry Andric Invalid = true;
33890b57cec5SDimitry Andric
33900b57cec5SDimitry Andric return Invalid;
33910b57cec5SDimitry Andric }
33920b57cec5SDimitry Andric
33930b57cec5SDimitry Andric // Defined via #include from SemaTemplateInstantiateDecl.cpp
33940b57cec5SDimitry Andric namespace clang {
33950b57cec5SDimitry Andric namespace sema {
33960b57cec5SDimitry Andric Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C, Sema &S,
33970b57cec5SDimitry Andric const MultiLevelTemplateArgumentList &TemplateArgs);
33980b57cec5SDimitry Andric Attr *instantiateTemplateAttributeForDecl(
33990b57cec5SDimitry Andric const Attr *At, ASTContext &C, Sema &S,
34000b57cec5SDimitry Andric const MultiLevelTemplateArgumentList &TemplateArgs);
34010b57cec5SDimitry Andric }
34020b57cec5SDimitry Andric }
34030b57cec5SDimitry Andric
34040b57cec5SDimitry Andric bool
InstantiateClass(SourceLocation PointOfInstantiation,CXXRecordDecl * Instantiation,CXXRecordDecl * Pattern,const MultiLevelTemplateArgumentList & TemplateArgs,TemplateSpecializationKind TSK,bool Complain)34050b57cec5SDimitry Andric Sema::InstantiateClass(SourceLocation PointOfInstantiation,
34060b57cec5SDimitry Andric CXXRecordDecl *Instantiation, CXXRecordDecl *Pattern,
34070b57cec5SDimitry Andric const MultiLevelTemplateArgumentList &TemplateArgs,
34080b57cec5SDimitry Andric TemplateSpecializationKind TSK,
34090b57cec5SDimitry Andric bool Complain) {
34100b57cec5SDimitry Andric CXXRecordDecl *PatternDef
34110b57cec5SDimitry Andric = cast_or_null<CXXRecordDecl>(Pattern->getDefinition());
34120b57cec5SDimitry Andric if (DiagnoseUninstantiableTemplate(PointOfInstantiation, Instantiation,
34130b57cec5SDimitry Andric Instantiation->getInstantiatedFromMemberClass(),
34140b57cec5SDimitry Andric Pattern, PatternDef, TSK, Complain))
34150b57cec5SDimitry Andric return true;
34160b57cec5SDimitry Andric
34170b57cec5SDimitry Andric llvm::TimeTraceScope TimeScope("InstantiateClass", [&]() {
34180fca6ea1SDimitry Andric llvm::TimeTraceMetadata M;
34190fca6ea1SDimitry Andric llvm::raw_string_ostream OS(M.Detail);
34200b57cec5SDimitry Andric Instantiation->getNameForDiagnostic(OS, getPrintingPolicy(),
34210b57cec5SDimitry Andric /*Qualified=*/true);
34220fca6ea1SDimitry Andric if (llvm::isTimeTraceVerbose()) {
34230fca6ea1SDimitry Andric auto Loc = SourceMgr.getExpansionLoc(Instantiation->getLocation());
34240fca6ea1SDimitry Andric M.File = SourceMgr.getFilename(Loc);
34250fca6ea1SDimitry Andric M.Line = SourceMgr.getExpansionLineNumber(Loc);
34260fca6ea1SDimitry Andric }
34270fca6ea1SDimitry Andric return M;
34280b57cec5SDimitry Andric });
34290b57cec5SDimitry Andric
34300b57cec5SDimitry Andric Pattern = PatternDef;
34310b57cec5SDimitry Andric
34320b57cec5SDimitry Andric // Record the point of instantiation.
34330b57cec5SDimitry Andric if (MemberSpecializationInfo *MSInfo
34340b57cec5SDimitry Andric = Instantiation->getMemberSpecializationInfo()) {
34350b57cec5SDimitry Andric MSInfo->setTemplateSpecializationKind(TSK);
34360b57cec5SDimitry Andric MSInfo->setPointOfInstantiation(PointOfInstantiation);
34370b57cec5SDimitry Andric } else if (ClassTemplateSpecializationDecl *Spec
34380b57cec5SDimitry Andric = dyn_cast<ClassTemplateSpecializationDecl>(Instantiation)) {
34390b57cec5SDimitry Andric Spec->setTemplateSpecializationKind(TSK);
34400b57cec5SDimitry Andric Spec->setPointOfInstantiation(PointOfInstantiation);
34410b57cec5SDimitry Andric }
34420b57cec5SDimitry Andric
34430b57cec5SDimitry Andric InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);
34440b57cec5SDimitry Andric if (Inst.isInvalid())
34450b57cec5SDimitry Andric return true;
34460b57cec5SDimitry Andric assert(!Inst.isAlreadyInstantiating() && "should have been caught by caller");
34470b57cec5SDimitry Andric PrettyDeclStackTraceEntry CrashInfo(Context, Instantiation, SourceLocation(),
34480b57cec5SDimitry Andric "instantiating class definition");
34490b57cec5SDimitry Andric
34500b57cec5SDimitry Andric // Enter the scope of this instantiation. We don't use
34510b57cec5SDimitry Andric // PushDeclContext because we don't have a scope.
34520b57cec5SDimitry Andric ContextRAII SavedContext(*this, Instantiation);
34530b57cec5SDimitry Andric EnterExpressionEvaluationContext EvalContext(
34540b57cec5SDimitry Andric *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
34550b57cec5SDimitry Andric
34560b57cec5SDimitry Andric // If this is an instantiation of a local class, merge this local
34570b57cec5SDimitry Andric // instantiation scope with the enclosing scope. Otherwise, every
34580b57cec5SDimitry Andric // instantiation of a class has its own local instantiation scope.
34590b57cec5SDimitry Andric bool MergeWithParentScope = !Instantiation->isDefinedOutsideFunctionOrMethod();
34600b57cec5SDimitry Andric LocalInstantiationScope Scope(*this, MergeWithParentScope);
34610b57cec5SDimitry Andric
34620b57cec5SDimitry Andric // Some class state isn't processed immediately but delayed till class
34630b57cec5SDimitry Andric // instantiation completes. We may not be ready to handle any delayed state
34640b57cec5SDimitry Andric // already on the stack as it might correspond to a different class, so save
34650b57cec5SDimitry Andric // it now and put it back later.
34660b57cec5SDimitry Andric SavePendingParsedClassStateRAII SavedPendingParsedClassState(*this);
34670b57cec5SDimitry Andric
34680b57cec5SDimitry Andric // Pull attributes from the pattern onto the instantiation.
34690b57cec5SDimitry Andric InstantiateAttrs(TemplateArgs, Pattern, Instantiation);
34700b57cec5SDimitry Andric
34710b57cec5SDimitry Andric // Start the definition of this instantiation.
34720b57cec5SDimitry Andric Instantiation->startDefinition();
34730b57cec5SDimitry Andric
34740b57cec5SDimitry Andric // The instantiation is visible here, even if it was first declared in an
34750b57cec5SDimitry Andric // unimported module.
34760b57cec5SDimitry Andric Instantiation->setVisibleDespiteOwningModule();
34770b57cec5SDimitry Andric
34780b57cec5SDimitry Andric // FIXME: This loses the as-written tag kind for an explicit instantiation.
34790b57cec5SDimitry Andric Instantiation->setTagKind(Pattern->getTagKind());
34800b57cec5SDimitry Andric
34810b57cec5SDimitry Andric // Do substitution on the base class specifiers.
34820b57cec5SDimitry Andric if (SubstBaseSpecifiers(Instantiation, Pattern, TemplateArgs))
34830b57cec5SDimitry Andric Instantiation->setInvalidDecl();
34840b57cec5SDimitry Andric
34850b57cec5SDimitry Andric TemplateDeclInstantiator Instantiator(*this, Instantiation, TemplateArgs);
3486bdd1243dSDimitry Andric Instantiator.setEvaluateConstraints(false);
34870b57cec5SDimitry Andric SmallVector<Decl*, 4> Fields;
34880b57cec5SDimitry Andric // Delay instantiation of late parsed attributes.
34890b57cec5SDimitry Andric LateInstantiatedAttrVec LateAttrs;
34900b57cec5SDimitry Andric Instantiator.enableLateAttributeInstantiation(&LateAttrs);
34910b57cec5SDimitry Andric
34920b57cec5SDimitry Andric bool MightHaveConstexprVirtualFunctions = false;
34930b57cec5SDimitry Andric for (auto *Member : Pattern->decls()) {
34940b57cec5SDimitry Andric // Don't instantiate members not belonging in this semantic context.
34950b57cec5SDimitry Andric // e.g. for:
34960b57cec5SDimitry Andric // @code
34970b57cec5SDimitry Andric // template <int i> class A {
34980b57cec5SDimitry Andric // class B *g;
34990b57cec5SDimitry Andric // };
35000b57cec5SDimitry Andric // @endcode
35010b57cec5SDimitry Andric // 'class B' has the template as lexical context but semantically it is
35020b57cec5SDimitry Andric // introduced in namespace scope.
35030b57cec5SDimitry Andric if (Member->getDeclContext() != Pattern)
35040b57cec5SDimitry Andric continue;
35050b57cec5SDimitry Andric
35060b57cec5SDimitry Andric // BlockDecls can appear in a default-member-initializer. They must be the
35070b57cec5SDimitry Andric // child of a BlockExpr, so we only know how to instantiate them from there.
3508e8d8bef9SDimitry Andric // Similarly, lambda closure types are recreated when instantiating the
3509e8d8bef9SDimitry Andric // corresponding LambdaExpr.
3510e8d8bef9SDimitry Andric if (isa<BlockDecl>(Member) ||
3511e8d8bef9SDimitry Andric (isa<CXXRecordDecl>(Member) && cast<CXXRecordDecl>(Member)->isLambda()))
35120b57cec5SDimitry Andric continue;
35130b57cec5SDimitry Andric
35140b57cec5SDimitry Andric if (Member->isInvalidDecl()) {
35150b57cec5SDimitry Andric Instantiation->setInvalidDecl();
35160b57cec5SDimitry Andric continue;
35170b57cec5SDimitry Andric }
35180b57cec5SDimitry Andric
35190b57cec5SDimitry Andric Decl *NewMember = Instantiator.Visit(Member);
35200b57cec5SDimitry Andric if (NewMember) {
35210b57cec5SDimitry Andric if (FieldDecl *Field = dyn_cast<FieldDecl>(NewMember)) {
35220b57cec5SDimitry Andric Fields.push_back(Field);
35230b57cec5SDimitry Andric } else if (EnumDecl *Enum = dyn_cast<EnumDecl>(NewMember)) {
35240b57cec5SDimitry Andric // C++11 [temp.inst]p1: The implicit instantiation of a class template
35250b57cec5SDimitry Andric // specialization causes the implicit instantiation of the definitions
35260b57cec5SDimitry Andric // of unscoped member enumerations.
35270b57cec5SDimitry Andric // Record a point of instantiation for this implicit instantiation.
35280b57cec5SDimitry Andric if (TSK == TSK_ImplicitInstantiation && !Enum->isScoped() &&
35290b57cec5SDimitry Andric Enum->isCompleteDefinition()) {
35300b57cec5SDimitry Andric MemberSpecializationInfo *MSInfo =Enum->getMemberSpecializationInfo();
35310b57cec5SDimitry Andric assert(MSInfo && "no spec info for member enum specialization");
35320b57cec5SDimitry Andric MSInfo->setTemplateSpecializationKind(TSK_ImplicitInstantiation);
35330b57cec5SDimitry Andric MSInfo->setPointOfInstantiation(PointOfInstantiation);
35340b57cec5SDimitry Andric }
35350b57cec5SDimitry Andric } else if (StaticAssertDecl *SA = dyn_cast<StaticAssertDecl>(NewMember)) {
35360b57cec5SDimitry Andric if (SA->isFailed()) {
35370b57cec5SDimitry Andric // A static_assert failed. Bail out; instantiating this
35380b57cec5SDimitry Andric // class is probably not meaningful.
35390b57cec5SDimitry Andric Instantiation->setInvalidDecl();
35400b57cec5SDimitry Andric break;
35410b57cec5SDimitry Andric }
35420b57cec5SDimitry Andric } else if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewMember)) {
35430b57cec5SDimitry Andric if (MD->isConstexpr() && !MD->getFriendObjectKind() &&
35440b57cec5SDimitry Andric (MD->isVirtualAsWritten() || Instantiation->getNumBases()))
35450b57cec5SDimitry Andric MightHaveConstexprVirtualFunctions = true;
35460b57cec5SDimitry Andric }
35470b57cec5SDimitry Andric
35480b57cec5SDimitry Andric if (NewMember->isInvalidDecl())
35490b57cec5SDimitry Andric Instantiation->setInvalidDecl();
35500b57cec5SDimitry Andric } else {
35510b57cec5SDimitry Andric // FIXME: Eventually, a NULL return will mean that one of the
35520b57cec5SDimitry Andric // instantiations was a semantic disaster, and we'll want to mark the
35530b57cec5SDimitry Andric // declaration invalid.
35540b57cec5SDimitry Andric // For now, we expect to skip some members that we can't yet handle.
35550b57cec5SDimitry Andric }
35560b57cec5SDimitry Andric }
35570b57cec5SDimitry Andric
35580b57cec5SDimitry Andric // Finish checking fields.
35590b57cec5SDimitry Andric ActOnFields(nullptr, Instantiation->getLocation(), Instantiation, Fields,
35600b57cec5SDimitry Andric SourceLocation(), SourceLocation(), ParsedAttributesView());
3561480093f4SDimitry Andric CheckCompletedCXXClass(nullptr, Instantiation);
35620b57cec5SDimitry Andric
35630b57cec5SDimitry Andric // Default arguments are parsed, if not instantiated. We can go instantiate
3564480093f4SDimitry Andric // default arg exprs for default constructors if necessary now. Unless we're
3565480093f4SDimitry Andric // parsing a class, in which case wait until that's finished.
3566480093f4SDimitry Andric if (ParsingClassDepth == 0)
3567480093f4SDimitry Andric ActOnFinishCXXNonNestedClass();
35680b57cec5SDimitry Andric
35690b57cec5SDimitry Andric // Instantiate late parsed attributes, and attach them to their decls.
35700b57cec5SDimitry Andric // See Sema::InstantiateAttrs
35710b57cec5SDimitry Andric for (LateInstantiatedAttrVec::iterator I = LateAttrs.begin(),
35720b57cec5SDimitry Andric E = LateAttrs.end(); I != E; ++I) {
35730b57cec5SDimitry Andric assert(CurrentInstantiationScope == Instantiator.getStartingScope());
35740b57cec5SDimitry Andric CurrentInstantiationScope = I->Scope;
35750b57cec5SDimitry Andric
35760b57cec5SDimitry Andric // Allow 'this' within late-parsed attributes.
357704eeddc0SDimitry Andric auto *ND = cast<NamedDecl>(I->NewDecl);
357804eeddc0SDimitry Andric auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext());
35790b57cec5SDimitry Andric CXXThisScopeRAII ThisScope(*this, ThisContext, Qualifiers(),
358004eeddc0SDimitry Andric ND->isCXXInstanceMember());
35810b57cec5SDimitry Andric
35820b57cec5SDimitry Andric Attr *NewAttr =
35830b57cec5SDimitry Andric instantiateTemplateAttribute(I->TmplAttr, Context, *this, TemplateArgs);
3584e8d8bef9SDimitry Andric if (NewAttr)
35850b57cec5SDimitry Andric I->NewDecl->addAttr(NewAttr);
35860b57cec5SDimitry Andric LocalInstantiationScope::deleteScopes(I->Scope,
35870b57cec5SDimitry Andric Instantiator.getStartingScope());
35880b57cec5SDimitry Andric }
35890b57cec5SDimitry Andric Instantiator.disableLateAttributeInstantiation();
35900b57cec5SDimitry Andric LateAttrs.clear();
35910b57cec5SDimitry Andric
35920b57cec5SDimitry Andric ActOnFinishDelayedMemberInitializers(Instantiation);
35930b57cec5SDimitry Andric
35940b57cec5SDimitry Andric // FIXME: We should do something similar for explicit instantiations so they
35950b57cec5SDimitry Andric // end up in the right module.
35960b57cec5SDimitry Andric if (TSK == TSK_ImplicitInstantiation) {
35970b57cec5SDimitry Andric Instantiation->setLocation(Pattern->getLocation());
35980b57cec5SDimitry Andric Instantiation->setLocStart(Pattern->getInnerLocStart());
35990b57cec5SDimitry Andric Instantiation->setBraceRange(Pattern->getBraceRange());
36000b57cec5SDimitry Andric }
36010b57cec5SDimitry Andric
36020b57cec5SDimitry Andric if (!Instantiation->isInvalidDecl()) {
36030b57cec5SDimitry Andric // Perform any dependent diagnostics from the pattern.
3604fe6060f1SDimitry Andric if (Pattern->isDependentContext())
36050b57cec5SDimitry Andric PerformDependentDiagnostics(Pattern, TemplateArgs);
36060b57cec5SDimitry Andric
36070b57cec5SDimitry Andric // Instantiate any out-of-line class template partial
36080b57cec5SDimitry Andric // specializations now.
36090b57cec5SDimitry Andric for (TemplateDeclInstantiator::delayed_partial_spec_iterator
36100b57cec5SDimitry Andric P = Instantiator.delayed_partial_spec_begin(),
36110b57cec5SDimitry Andric PEnd = Instantiator.delayed_partial_spec_end();
36120b57cec5SDimitry Andric P != PEnd; ++P) {
36130b57cec5SDimitry Andric if (!Instantiator.InstantiateClassTemplatePartialSpecialization(
36140b57cec5SDimitry Andric P->first, P->second)) {
36150b57cec5SDimitry Andric Instantiation->setInvalidDecl();
36160b57cec5SDimitry Andric break;
36170b57cec5SDimitry Andric }
36180b57cec5SDimitry Andric }
36190b57cec5SDimitry Andric
36200b57cec5SDimitry Andric // Instantiate any out-of-line variable template partial
36210b57cec5SDimitry Andric // specializations now.
36220b57cec5SDimitry Andric for (TemplateDeclInstantiator::delayed_var_partial_spec_iterator
36230b57cec5SDimitry Andric P = Instantiator.delayed_var_partial_spec_begin(),
36240b57cec5SDimitry Andric PEnd = Instantiator.delayed_var_partial_spec_end();
36250b57cec5SDimitry Andric P != PEnd; ++P) {
36260b57cec5SDimitry Andric if (!Instantiator.InstantiateVarTemplatePartialSpecialization(
36270b57cec5SDimitry Andric P->first, P->second)) {
36280b57cec5SDimitry Andric Instantiation->setInvalidDecl();
36290b57cec5SDimitry Andric break;
36300b57cec5SDimitry Andric }
36310b57cec5SDimitry Andric }
36320b57cec5SDimitry Andric }
36330b57cec5SDimitry Andric
36340b57cec5SDimitry Andric // Exit the scope of this instantiation.
36350b57cec5SDimitry Andric SavedContext.pop();
36360b57cec5SDimitry Andric
36370b57cec5SDimitry Andric if (!Instantiation->isInvalidDecl()) {
36380b57cec5SDimitry Andric // Always emit the vtable for an explicit instantiation definition
36390b57cec5SDimitry Andric // of a polymorphic class template specialization. Otherwise, eagerly
36400b57cec5SDimitry Andric // instantiate only constexpr virtual functions in preparation for their use
36410b57cec5SDimitry Andric // in constant evaluation.
36420b57cec5SDimitry Andric if (TSK == TSK_ExplicitInstantiationDefinition)
36430b57cec5SDimitry Andric MarkVTableUsed(PointOfInstantiation, Instantiation, true);
36440b57cec5SDimitry Andric else if (MightHaveConstexprVirtualFunctions)
36450b57cec5SDimitry Andric MarkVirtualMembersReferenced(PointOfInstantiation, Instantiation,
36460b57cec5SDimitry Andric /*ConstexprOnly*/ true);
36470b57cec5SDimitry Andric }
36480b57cec5SDimitry Andric
3649e8d8bef9SDimitry Andric Consumer.HandleTagDeclDefinition(Instantiation);
3650e8d8bef9SDimitry Andric
36510b57cec5SDimitry Andric return Instantiation->isInvalidDecl();
36520b57cec5SDimitry Andric }
36530b57cec5SDimitry Andric
InstantiateEnum(SourceLocation PointOfInstantiation,EnumDecl * Instantiation,EnumDecl * Pattern,const MultiLevelTemplateArgumentList & TemplateArgs,TemplateSpecializationKind TSK)36540b57cec5SDimitry Andric bool Sema::InstantiateEnum(SourceLocation PointOfInstantiation,
36550b57cec5SDimitry Andric EnumDecl *Instantiation, EnumDecl *Pattern,
36560b57cec5SDimitry Andric const MultiLevelTemplateArgumentList &TemplateArgs,
36570b57cec5SDimitry Andric TemplateSpecializationKind TSK) {
36580b57cec5SDimitry Andric EnumDecl *PatternDef = Pattern->getDefinition();
36590b57cec5SDimitry Andric if (DiagnoseUninstantiableTemplate(PointOfInstantiation, Instantiation,
36600b57cec5SDimitry Andric Instantiation->getInstantiatedFromMemberEnum(),
36610b57cec5SDimitry Andric Pattern, PatternDef, TSK,/*Complain*/true))
36620b57cec5SDimitry Andric return true;
36630b57cec5SDimitry Andric Pattern = PatternDef;
36640b57cec5SDimitry Andric
36650b57cec5SDimitry Andric // Record the point of instantiation.
36660b57cec5SDimitry Andric if (MemberSpecializationInfo *MSInfo
36670b57cec5SDimitry Andric = Instantiation->getMemberSpecializationInfo()) {
36680b57cec5SDimitry Andric MSInfo->setTemplateSpecializationKind(TSK);
36690b57cec5SDimitry Andric MSInfo->setPointOfInstantiation(PointOfInstantiation);
36700b57cec5SDimitry Andric }
36710b57cec5SDimitry Andric
36720b57cec5SDimitry Andric InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);
36730b57cec5SDimitry Andric if (Inst.isInvalid())
36740b57cec5SDimitry Andric return true;
36750b57cec5SDimitry Andric if (Inst.isAlreadyInstantiating())
36760b57cec5SDimitry Andric return false;
36770b57cec5SDimitry Andric PrettyDeclStackTraceEntry CrashInfo(Context, Instantiation, SourceLocation(),
36780b57cec5SDimitry Andric "instantiating enum definition");
36790b57cec5SDimitry Andric
36800b57cec5SDimitry Andric // The instantiation is visible here, even if it was first declared in an
36810b57cec5SDimitry Andric // unimported module.
36820b57cec5SDimitry Andric Instantiation->setVisibleDespiteOwningModule();
36830b57cec5SDimitry Andric
36840b57cec5SDimitry Andric // Enter the scope of this instantiation. We don't use
36850b57cec5SDimitry Andric // PushDeclContext because we don't have a scope.
36860b57cec5SDimitry Andric ContextRAII SavedContext(*this, Instantiation);
36870b57cec5SDimitry Andric EnterExpressionEvaluationContext EvalContext(
36880b57cec5SDimitry Andric *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
36890b57cec5SDimitry Andric
36900b57cec5SDimitry Andric LocalInstantiationScope Scope(*this, /*MergeWithParentScope*/true);
36910b57cec5SDimitry Andric
36920b57cec5SDimitry Andric // Pull attributes from the pattern onto the instantiation.
36930b57cec5SDimitry Andric InstantiateAttrs(TemplateArgs, Pattern, Instantiation);
36940b57cec5SDimitry Andric
36950b57cec5SDimitry Andric TemplateDeclInstantiator Instantiator(*this, Instantiation, TemplateArgs);
36960b57cec5SDimitry Andric Instantiator.InstantiateEnumDefinition(Instantiation, Pattern);
36970b57cec5SDimitry Andric
36980b57cec5SDimitry Andric // Exit the scope of this instantiation.
36990b57cec5SDimitry Andric SavedContext.pop();
37000b57cec5SDimitry Andric
37010b57cec5SDimitry Andric return Instantiation->isInvalidDecl();
37020b57cec5SDimitry Andric }
37030b57cec5SDimitry Andric
InstantiateInClassInitializer(SourceLocation PointOfInstantiation,FieldDecl * Instantiation,FieldDecl * Pattern,const MultiLevelTemplateArgumentList & TemplateArgs)37040b57cec5SDimitry Andric bool Sema::InstantiateInClassInitializer(
37050b57cec5SDimitry Andric SourceLocation PointOfInstantiation, FieldDecl *Instantiation,
37060b57cec5SDimitry Andric FieldDecl *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs) {
37070b57cec5SDimitry Andric // If there is no initializer, we don't need to do anything.
37080b57cec5SDimitry Andric if (!Pattern->hasInClassInitializer())
37090b57cec5SDimitry Andric return false;
37100b57cec5SDimitry Andric
37110b57cec5SDimitry Andric assert(Instantiation->getInClassInitStyle() ==
37120b57cec5SDimitry Andric Pattern->getInClassInitStyle() &&
37130b57cec5SDimitry Andric "pattern and instantiation disagree about init style");
37140b57cec5SDimitry Andric
37150b57cec5SDimitry Andric // Error out if we haven't parsed the initializer of the pattern yet because
37160b57cec5SDimitry Andric // we are waiting for the closing brace of the outer class.
37170b57cec5SDimitry Andric Expr *OldInit = Pattern->getInClassInitializer();
37180b57cec5SDimitry Andric if (!OldInit) {
37190b57cec5SDimitry Andric RecordDecl *PatternRD = Pattern->getParent();
37200b57cec5SDimitry Andric RecordDecl *OutermostClass = PatternRD->getOuterLexicalRecordContext();
37210b57cec5SDimitry Andric Diag(PointOfInstantiation,
3722e8d8bef9SDimitry Andric diag::err_default_member_initializer_not_yet_parsed)
37230b57cec5SDimitry Andric << OutermostClass << Pattern;
3724e8d8bef9SDimitry Andric Diag(Pattern->getEndLoc(),
3725e8d8bef9SDimitry Andric diag::note_default_member_initializer_not_yet_parsed);
37260b57cec5SDimitry Andric Instantiation->setInvalidDecl();
37270b57cec5SDimitry Andric return true;
37280b57cec5SDimitry Andric }
37290b57cec5SDimitry Andric
37300b57cec5SDimitry Andric InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);
37310b57cec5SDimitry Andric if (Inst.isInvalid())
37320b57cec5SDimitry Andric return true;
37330b57cec5SDimitry Andric if (Inst.isAlreadyInstantiating()) {
37340b57cec5SDimitry Andric // Error out if we hit an instantiation cycle for this initializer.
3735e8d8bef9SDimitry Andric Diag(PointOfInstantiation, diag::err_default_member_initializer_cycle)
37360b57cec5SDimitry Andric << Instantiation;
37370b57cec5SDimitry Andric return true;
37380b57cec5SDimitry Andric }
37390b57cec5SDimitry Andric PrettyDeclStackTraceEntry CrashInfo(Context, Instantiation, SourceLocation(),
37400b57cec5SDimitry Andric "instantiating default member init");
37410b57cec5SDimitry Andric
37420b57cec5SDimitry Andric // Enter the scope of this instantiation. We don't use PushDeclContext because
37430b57cec5SDimitry Andric // we don't have a scope.
37440b57cec5SDimitry Andric ContextRAII SavedContext(*this, Instantiation->getParent());
37450b57cec5SDimitry Andric EnterExpressionEvaluationContext EvalContext(
37460b57cec5SDimitry Andric *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
3747bdd1243dSDimitry Andric ExprEvalContexts.back().DelayedDefaultInitializationContext = {
3748bdd1243dSDimitry Andric PointOfInstantiation, Instantiation, CurContext};
37490b57cec5SDimitry Andric
37500b57cec5SDimitry Andric LocalInstantiationScope Scope(*this, true);
37510b57cec5SDimitry Andric
37520b57cec5SDimitry Andric // Instantiate the initializer.
37530b57cec5SDimitry Andric ActOnStartCXXInClassMemberInitializer();
37540b57cec5SDimitry Andric CXXThisScopeRAII ThisScope(*this, Instantiation->getParent(), Qualifiers());
37550b57cec5SDimitry Andric
37560b57cec5SDimitry Andric ExprResult NewInit = SubstInitializer(OldInit, TemplateArgs,
37570b57cec5SDimitry Andric /*CXXDirectInit=*/false);
37580b57cec5SDimitry Andric Expr *Init = NewInit.get();
37590b57cec5SDimitry Andric assert((!Init || !isa<ParenListExpr>(Init)) && "call-style init in class");
37600b57cec5SDimitry Andric ActOnFinishCXXInClassMemberInitializer(
37610b57cec5SDimitry Andric Instantiation, Init ? Init->getBeginLoc() : SourceLocation(), Init);
37620b57cec5SDimitry Andric
37630b57cec5SDimitry Andric if (auto *L = getASTMutationListener())
37640b57cec5SDimitry Andric L->DefaultMemberInitializerInstantiated(Instantiation);
37650b57cec5SDimitry Andric
37660b57cec5SDimitry Andric // Return true if the in-class initializer is still missing.
37670b57cec5SDimitry Andric return !Instantiation->getInClassInitializer();
37680b57cec5SDimitry Andric }
37690b57cec5SDimitry Andric
37700b57cec5SDimitry Andric namespace {
37710b57cec5SDimitry Andric /// A partial specialization whose template arguments have matched
37720b57cec5SDimitry Andric /// a given template-id.
37730b57cec5SDimitry Andric struct PartialSpecMatchResult {
37740b57cec5SDimitry Andric ClassTemplatePartialSpecializationDecl *Partial;
37750b57cec5SDimitry Andric TemplateArgumentList *Args;
37760b57cec5SDimitry Andric };
37770b57cec5SDimitry Andric }
37780b57cec5SDimitry Andric
usesPartialOrExplicitSpecialization(SourceLocation Loc,ClassTemplateSpecializationDecl * ClassTemplateSpec)37790b57cec5SDimitry Andric bool Sema::usesPartialOrExplicitSpecialization(
37800b57cec5SDimitry Andric SourceLocation Loc, ClassTemplateSpecializationDecl *ClassTemplateSpec) {
37810b57cec5SDimitry Andric if (ClassTemplateSpec->getTemplateSpecializationKind() ==
37820b57cec5SDimitry Andric TSK_ExplicitSpecialization)
37830b57cec5SDimitry Andric return true;
37840b57cec5SDimitry Andric
37850b57cec5SDimitry Andric SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs;
37860b57cec5SDimitry Andric ClassTemplateSpec->getSpecializedTemplate()
37870b57cec5SDimitry Andric ->getPartialSpecializations(PartialSpecs);
37880b57cec5SDimitry Andric for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I) {
37890b57cec5SDimitry Andric TemplateDeductionInfo Info(Loc);
37900fca6ea1SDimitry Andric if (DeduceTemplateArguments(PartialSpecs[I],
37910fca6ea1SDimitry Andric ClassTemplateSpec->getTemplateArgs().asArray(),
37920fca6ea1SDimitry Andric Info) == TemplateDeductionResult::Success)
37930b57cec5SDimitry Andric return true;
37940b57cec5SDimitry Andric }
37950b57cec5SDimitry Andric
37960b57cec5SDimitry Andric return false;
37970b57cec5SDimitry Andric }
37980b57cec5SDimitry Andric
37990b57cec5SDimitry Andric /// Get the instantiation pattern to use to instantiate the definition of a
38000b57cec5SDimitry Andric /// given ClassTemplateSpecializationDecl (either the pattern of the primary
38010b57cec5SDimitry Andric /// template or of a partial specialization).
3802e8d8bef9SDimitry Andric static ActionResult<CXXRecordDecl *>
getPatternForClassTemplateSpecialization(Sema & S,SourceLocation PointOfInstantiation,ClassTemplateSpecializationDecl * ClassTemplateSpec,TemplateSpecializationKind TSK)38030b57cec5SDimitry Andric getPatternForClassTemplateSpecialization(
38040b57cec5SDimitry Andric Sema &S, SourceLocation PointOfInstantiation,
38050b57cec5SDimitry Andric ClassTemplateSpecializationDecl *ClassTemplateSpec,
3806e8d8bef9SDimitry Andric TemplateSpecializationKind TSK) {
38070b57cec5SDimitry Andric Sema::InstantiatingTemplate Inst(S, PointOfInstantiation, ClassTemplateSpec);
3808e8d8bef9SDimitry Andric if (Inst.isInvalid())
3809e8d8bef9SDimitry Andric return {/*Invalid=*/true};
3810e8d8bef9SDimitry Andric if (Inst.isAlreadyInstantiating())
3811e8d8bef9SDimitry Andric return {/*Invalid=*/false};
38120b57cec5SDimitry Andric
38130b57cec5SDimitry Andric llvm::PointerUnion<ClassTemplateDecl *,
38140b57cec5SDimitry Andric ClassTemplatePartialSpecializationDecl *>
38150b57cec5SDimitry Andric Specialized = ClassTemplateSpec->getSpecializedTemplateOrPartial();
38160b57cec5SDimitry Andric if (!Specialized.is<ClassTemplatePartialSpecializationDecl *>()) {
38170b57cec5SDimitry Andric // Find best matching specialization.
38180b57cec5SDimitry Andric ClassTemplateDecl *Template = ClassTemplateSpec->getSpecializedTemplate();
38190b57cec5SDimitry Andric
38200b57cec5SDimitry Andric // C++ [temp.class.spec.match]p1:
38210b57cec5SDimitry Andric // When a class template is used in a context that requires an
38220b57cec5SDimitry Andric // instantiation of the class, it is necessary to determine
38230b57cec5SDimitry Andric // whether the instantiation is to be generated using the primary
38240b57cec5SDimitry Andric // template or one of the partial specializations. This is done by
38250b57cec5SDimitry Andric // matching the template arguments of the class template
38260b57cec5SDimitry Andric // specialization with the template argument lists of the partial
38270b57cec5SDimitry Andric // specializations.
38280b57cec5SDimitry Andric typedef PartialSpecMatchResult MatchResult;
38290b57cec5SDimitry Andric SmallVector<MatchResult, 4> Matched;
38300b57cec5SDimitry Andric SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs;
38310b57cec5SDimitry Andric Template->getPartialSpecializations(PartialSpecs);
38320b57cec5SDimitry Andric TemplateSpecCandidateSet FailedCandidates(PointOfInstantiation);
38330b57cec5SDimitry Andric for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I) {
38340b57cec5SDimitry Andric ClassTemplatePartialSpecializationDecl *Partial = PartialSpecs[I];
38350b57cec5SDimitry Andric TemplateDeductionInfo Info(FailedCandidates.getLocation());
38360fca6ea1SDimitry Andric if (TemplateDeductionResult Result = S.DeduceTemplateArguments(
38370fca6ea1SDimitry Andric Partial, ClassTemplateSpec->getTemplateArgs().asArray(), Info);
38380fca6ea1SDimitry Andric Result != TemplateDeductionResult::Success) {
38390b57cec5SDimitry Andric // Store the failed-deduction information for use in diagnostics, later.
38400b57cec5SDimitry Andric // TODO: Actually use the failed-deduction info?
38410b57cec5SDimitry Andric FailedCandidates.addCandidate().set(
38420b57cec5SDimitry Andric DeclAccessPair::make(Template, AS_public), Partial,
38430b57cec5SDimitry Andric MakeDeductionFailureInfo(S.Context, Result, Info));
38440b57cec5SDimitry Andric (void)Result;
38450b57cec5SDimitry Andric } else {
38460b57cec5SDimitry Andric Matched.push_back(PartialSpecMatchResult());
38470b57cec5SDimitry Andric Matched.back().Partial = Partial;
3848bdd1243dSDimitry Andric Matched.back().Args = Info.takeCanonical();
38490b57cec5SDimitry Andric }
38500b57cec5SDimitry Andric }
38510b57cec5SDimitry Andric
38520b57cec5SDimitry Andric // If we're dealing with a member template where the template parameters
38530b57cec5SDimitry Andric // have been instantiated, this provides the original template parameters
38540b57cec5SDimitry Andric // from which the member template's parameters were instantiated.
38550b57cec5SDimitry Andric
38560b57cec5SDimitry Andric if (Matched.size() >= 1) {
38570b57cec5SDimitry Andric SmallVectorImpl<MatchResult>::iterator Best = Matched.begin();
38580b57cec5SDimitry Andric if (Matched.size() == 1) {
38590b57cec5SDimitry Andric // -- If exactly one matching specialization is found, the
38600b57cec5SDimitry Andric // instantiation is generated from that specialization.
38610b57cec5SDimitry Andric // We don't need to do anything for this.
38620b57cec5SDimitry Andric } else {
38630b57cec5SDimitry Andric // -- If more than one matching specialization is found, the
38640b57cec5SDimitry Andric // partial order rules (14.5.4.2) are used to determine
38650b57cec5SDimitry Andric // whether one of the specializations is more specialized
38660b57cec5SDimitry Andric // than the others. If none of the specializations is more
38670b57cec5SDimitry Andric // specialized than all of the other matching
38680b57cec5SDimitry Andric // specializations, then the use of the class template is
38690b57cec5SDimitry Andric // ambiguous and the program is ill-formed.
38700b57cec5SDimitry Andric for (SmallVectorImpl<MatchResult>::iterator P = Best + 1,
38710b57cec5SDimitry Andric PEnd = Matched.end();
38720b57cec5SDimitry Andric P != PEnd; ++P) {
38730b57cec5SDimitry Andric if (S.getMoreSpecializedPartialSpecialization(
38740b57cec5SDimitry Andric P->Partial, Best->Partial, PointOfInstantiation) ==
38750b57cec5SDimitry Andric P->Partial)
38760b57cec5SDimitry Andric Best = P;
38770b57cec5SDimitry Andric }
38780b57cec5SDimitry Andric
38790b57cec5SDimitry Andric // Determine if the best partial specialization is more specialized than
38800b57cec5SDimitry Andric // the others.
38810b57cec5SDimitry Andric bool Ambiguous = false;
38820b57cec5SDimitry Andric for (SmallVectorImpl<MatchResult>::iterator P = Matched.begin(),
38830b57cec5SDimitry Andric PEnd = Matched.end();
38840b57cec5SDimitry Andric P != PEnd; ++P) {
38850b57cec5SDimitry Andric if (P != Best && S.getMoreSpecializedPartialSpecialization(
38860b57cec5SDimitry Andric P->Partial, Best->Partial,
38870b57cec5SDimitry Andric PointOfInstantiation) != Best->Partial) {
38880b57cec5SDimitry Andric Ambiguous = true;
38890b57cec5SDimitry Andric break;
38900b57cec5SDimitry Andric }
38910b57cec5SDimitry Andric }
38920b57cec5SDimitry Andric
38930b57cec5SDimitry Andric if (Ambiguous) {
38940b57cec5SDimitry Andric // Partial ordering did not produce a clear winner. Complain.
38950b57cec5SDimitry Andric Inst.Clear();
38960b57cec5SDimitry Andric ClassTemplateSpec->setInvalidDecl();
38970b57cec5SDimitry Andric S.Diag(PointOfInstantiation,
38980b57cec5SDimitry Andric diag::err_partial_spec_ordering_ambiguous)
38990b57cec5SDimitry Andric << ClassTemplateSpec;
39000b57cec5SDimitry Andric
39010b57cec5SDimitry Andric // Print the matching partial specializations.
39020b57cec5SDimitry Andric for (SmallVectorImpl<MatchResult>::iterator P = Matched.begin(),
39030b57cec5SDimitry Andric PEnd = Matched.end();
39040b57cec5SDimitry Andric P != PEnd; ++P)
39050b57cec5SDimitry Andric S.Diag(P->Partial->getLocation(), diag::note_partial_spec_match)
39060b57cec5SDimitry Andric << S.getTemplateArgumentBindingsText(
39070b57cec5SDimitry Andric P->Partial->getTemplateParameters(), *P->Args);
39080b57cec5SDimitry Andric
3909e8d8bef9SDimitry Andric return {/*Invalid=*/true};
39100b57cec5SDimitry Andric }
39110b57cec5SDimitry Andric }
39120b57cec5SDimitry Andric
39130b57cec5SDimitry Andric ClassTemplateSpec->setInstantiationOf(Best->Partial, Best->Args);
39140b57cec5SDimitry Andric } else {
39150b57cec5SDimitry Andric // -- If no matches are found, the instantiation is generated
39160b57cec5SDimitry Andric // from the primary template.
39170b57cec5SDimitry Andric }
39180b57cec5SDimitry Andric }
39190b57cec5SDimitry Andric
39200b57cec5SDimitry Andric CXXRecordDecl *Pattern = nullptr;
39210b57cec5SDimitry Andric Specialized = ClassTemplateSpec->getSpecializedTemplateOrPartial();
39220b57cec5SDimitry Andric if (auto *PartialSpec =
39230b57cec5SDimitry Andric Specialized.dyn_cast<ClassTemplatePartialSpecializationDecl *>()) {
39240b57cec5SDimitry Andric // Instantiate using the best class template partial specialization.
39250b57cec5SDimitry Andric while (PartialSpec->getInstantiatedFromMember()) {
39260b57cec5SDimitry Andric // If we've found an explicit specialization of this class template,
39270b57cec5SDimitry Andric // stop here and use that as the pattern.
39280b57cec5SDimitry Andric if (PartialSpec->isMemberSpecialization())
39290b57cec5SDimitry Andric break;
39300b57cec5SDimitry Andric
39310b57cec5SDimitry Andric PartialSpec = PartialSpec->getInstantiatedFromMember();
39320b57cec5SDimitry Andric }
39330b57cec5SDimitry Andric Pattern = PartialSpec;
39340b57cec5SDimitry Andric } else {
39350b57cec5SDimitry Andric ClassTemplateDecl *Template = ClassTemplateSpec->getSpecializedTemplate();
39360b57cec5SDimitry Andric while (Template->getInstantiatedFromMemberTemplate()) {
39370b57cec5SDimitry Andric // If we've found an explicit specialization of this class template,
39380b57cec5SDimitry Andric // stop here and use that as the pattern.
39390b57cec5SDimitry Andric if (Template->isMemberSpecialization())
39400b57cec5SDimitry Andric break;
39410b57cec5SDimitry Andric
39420b57cec5SDimitry Andric Template = Template->getInstantiatedFromMemberTemplate();
39430b57cec5SDimitry Andric }
39440b57cec5SDimitry Andric Pattern = Template->getTemplatedDecl();
39450b57cec5SDimitry Andric }
39460b57cec5SDimitry Andric
39470b57cec5SDimitry Andric return Pattern;
39480b57cec5SDimitry Andric }
39490b57cec5SDimitry Andric
InstantiateClassTemplateSpecialization(SourceLocation PointOfInstantiation,ClassTemplateSpecializationDecl * ClassTemplateSpec,TemplateSpecializationKind TSK,bool Complain)39500b57cec5SDimitry Andric bool Sema::InstantiateClassTemplateSpecialization(
39510b57cec5SDimitry Andric SourceLocation PointOfInstantiation,
39520b57cec5SDimitry Andric ClassTemplateSpecializationDecl *ClassTemplateSpec,
39530b57cec5SDimitry Andric TemplateSpecializationKind TSK, bool Complain) {
39540b57cec5SDimitry Andric // Perform the actual instantiation on the canonical declaration.
39550b57cec5SDimitry Andric ClassTemplateSpec = cast<ClassTemplateSpecializationDecl>(
39560b57cec5SDimitry Andric ClassTemplateSpec->getCanonicalDecl());
39570b57cec5SDimitry Andric if (ClassTemplateSpec->isInvalidDecl())
39580b57cec5SDimitry Andric return true;
39590b57cec5SDimitry Andric
3960e8d8bef9SDimitry Andric ActionResult<CXXRecordDecl *> Pattern =
3961e8d8bef9SDimitry Andric getPatternForClassTemplateSpecialization(*this, PointOfInstantiation,
3962e8d8bef9SDimitry Andric ClassTemplateSpec, TSK);
3963e8d8bef9SDimitry Andric if (!Pattern.isUsable())
3964e8d8bef9SDimitry Andric return Pattern.isInvalid();
39650b57cec5SDimitry Andric
3966e8d8bef9SDimitry Andric return InstantiateClass(
3967e8d8bef9SDimitry Andric PointOfInstantiation, ClassTemplateSpec, Pattern.get(),
3968e8d8bef9SDimitry Andric getTemplateInstantiationArgs(ClassTemplateSpec), TSK, Complain);
39690b57cec5SDimitry Andric }
39700b57cec5SDimitry Andric
39710b57cec5SDimitry Andric void
InstantiateClassMembers(SourceLocation PointOfInstantiation,CXXRecordDecl * Instantiation,const MultiLevelTemplateArgumentList & TemplateArgs,TemplateSpecializationKind TSK)39720b57cec5SDimitry Andric Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
39730b57cec5SDimitry Andric CXXRecordDecl *Instantiation,
39740b57cec5SDimitry Andric const MultiLevelTemplateArgumentList &TemplateArgs,
39750b57cec5SDimitry Andric TemplateSpecializationKind TSK) {
39760b57cec5SDimitry Andric // FIXME: We need to notify the ASTMutationListener that we did all of these
39770b57cec5SDimitry Andric // things, in case we have an explicit instantiation definition in a PCM, a
39780b57cec5SDimitry Andric // module, or preamble, and the declaration is in an imported AST.
39790b57cec5SDimitry Andric assert(
39800b57cec5SDimitry Andric (TSK == TSK_ExplicitInstantiationDefinition ||
39810b57cec5SDimitry Andric TSK == TSK_ExplicitInstantiationDeclaration ||
39820b57cec5SDimitry Andric (TSK == TSK_ImplicitInstantiation && Instantiation->isLocalClass())) &&
39830b57cec5SDimitry Andric "Unexpected template specialization kind!");
39840b57cec5SDimitry Andric for (auto *D : Instantiation->decls()) {
39850b57cec5SDimitry Andric bool SuppressNew = false;
39860b57cec5SDimitry Andric if (auto *Function = dyn_cast<FunctionDecl>(D)) {
39870b57cec5SDimitry Andric if (FunctionDecl *Pattern =
39880b57cec5SDimitry Andric Function->getInstantiatedFromMemberFunction()) {
39890b57cec5SDimitry Andric
399081ad6265SDimitry Andric if (Function->isIneligibleOrNotSelected())
399181ad6265SDimitry Andric continue;
399281ad6265SDimitry Andric
399381ad6265SDimitry Andric if (Function->getTrailingRequiresClause()) {
399481ad6265SDimitry Andric ConstraintSatisfaction Satisfaction;
399581ad6265SDimitry Andric if (CheckFunctionConstraints(Function, Satisfaction) ||
399681ad6265SDimitry Andric !Satisfaction.IsSatisfied) {
399781ad6265SDimitry Andric continue;
399881ad6265SDimitry Andric }
399981ad6265SDimitry Andric }
400081ad6265SDimitry Andric
40010b57cec5SDimitry Andric if (Function->hasAttr<ExcludeFromExplicitInstantiationAttr>())
40020b57cec5SDimitry Andric continue;
40030b57cec5SDimitry Andric
40040b57cec5SDimitry Andric MemberSpecializationInfo *MSInfo =
40050b57cec5SDimitry Andric Function->getMemberSpecializationInfo();
40060b57cec5SDimitry Andric assert(MSInfo && "No member specialization information?");
40070b57cec5SDimitry Andric if (MSInfo->getTemplateSpecializationKind()
40080b57cec5SDimitry Andric == TSK_ExplicitSpecialization)
40090b57cec5SDimitry Andric continue;
40100b57cec5SDimitry Andric
40110b57cec5SDimitry Andric if (CheckSpecializationInstantiationRedecl(PointOfInstantiation, TSK,
40120b57cec5SDimitry Andric Function,
40130b57cec5SDimitry Andric MSInfo->getTemplateSpecializationKind(),
40140b57cec5SDimitry Andric MSInfo->getPointOfInstantiation(),
40150b57cec5SDimitry Andric SuppressNew) ||
40160b57cec5SDimitry Andric SuppressNew)
40170b57cec5SDimitry Andric continue;
40180b57cec5SDimitry Andric
40190b57cec5SDimitry Andric // C++11 [temp.explicit]p8:
40200b57cec5SDimitry Andric // An explicit instantiation definition that names a class template
40210b57cec5SDimitry Andric // specialization explicitly instantiates the class template
40220b57cec5SDimitry Andric // specialization and is only an explicit instantiation definition
40230b57cec5SDimitry Andric // of members whose definition is visible at the point of
40240b57cec5SDimitry Andric // instantiation.
40250b57cec5SDimitry Andric if (TSK == TSK_ExplicitInstantiationDefinition && !Pattern->isDefined())
40260b57cec5SDimitry Andric continue;
40270b57cec5SDimitry Andric
40280b57cec5SDimitry Andric Function->setTemplateSpecializationKind(TSK, PointOfInstantiation);
40290b57cec5SDimitry Andric
40300b57cec5SDimitry Andric if (Function->isDefined()) {
40310b57cec5SDimitry Andric // Let the ASTConsumer know that this function has been explicitly
40320b57cec5SDimitry Andric // instantiated now, and its linkage might have changed.
40330b57cec5SDimitry Andric Consumer.HandleTopLevelDecl(DeclGroupRef(Function));
40340b57cec5SDimitry Andric } else if (TSK == TSK_ExplicitInstantiationDefinition) {
40350b57cec5SDimitry Andric InstantiateFunctionDefinition(PointOfInstantiation, Function);
40360b57cec5SDimitry Andric } else if (TSK == TSK_ImplicitInstantiation) {
40370b57cec5SDimitry Andric PendingLocalImplicitInstantiations.push_back(
40380b57cec5SDimitry Andric std::make_pair(Function, PointOfInstantiation));
40390b57cec5SDimitry Andric }
40400b57cec5SDimitry Andric }
40410b57cec5SDimitry Andric } else if (auto *Var = dyn_cast<VarDecl>(D)) {
40420b57cec5SDimitry Andric if (isa<VarTemplateSpecializationDecl>(Var))
40430b57cec5SDimitry Andric continue;
40440b57cec5SDimitry Andric
40450b57cec5SDimitry Andric if (Var->isStaticDataMember()) {
40460b57cec5SDimitry Andric if (Var->hasAttr<ExcludeFromExplicitInstantiationAttr>())
40470b57cec5SDimitry Andric continue;
40480b57cec5SDimitry Andric
40490b57cec5SDimitry Andric MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo();
40500b57cec5SDimitry Andric assert(MSInfo && "No member specialization information?");
40510b57cec5SDimitry Andric if (MSInfo->getTemplateSpecializationKind()
40520b57cec5SDimitry Andric == TSK_ExplicitSpecialization)
40530b57cec5SDimitry Andric continue;
40540b57cec5SDimitry Andric
40550b57cec5SDimitry Andric if (CheckSpecializationInstantiationRedecl(PointOfInstantiation, TSK,
40560b57cec5SDimitry Andric Var,
40570b57cec5SDimitry Andric MSInfo->getTemplateSpecializationKind(),
40580b57cec5SDimitry Andric MSInfo->getPointOfInstantiation(),
40590b57cec5SDimitry Andric SuppressNew) ||
40600b57cec5SDimitry Andric SuppressNew)
40610b57cec5SDimitry Andric continue;
40620b57cec5SDimitry Andric
40630b57cec5SDimitry Andric if (TSK == TSK_ExplicitInstantiationDefinition) {
40640b57cec5SDimitry Andric // C++0x [temp.explicit]p8:
40650b57cec5SDimitry Andric // An explicit instantiation definition that names a class template
40660b57cec5SDimitry Andric // specialization explicitly instantiates the class template
40670b57cec5SDimitry Andric // specialization and is only an explicit instantiation definition
40680b57cec5SDimitry Andric // of members whose definition is visible at the point of
40690b57cec5SDimitry Andric // instantiation.
40700b57cec5SDimitry Andric if (!Var->getInstantiatedFromStaticDataMember()->getDefinition())
40710b57cec5SDimitry Andric continue;
40720b57cec5SDimitry Andric
40730b57cec5SDimitry Andric Var->setTemplateSpecializationKind(TSK, PointOfInstantiation);
40740b57cec5SDimitry Andric InstantiateVariableDefinition(PointOfInstantiation, Var);
40750b57cec5SDimitry Andric } else {
40760b57cec5SDimitry Andric Var->setTemplateSpecializationKind(TSK, PointOfInstantiation);
40770b57cec5SDimitry Andric }
40780b57cec5SDimitry Andric }
40790b57cec5SDimitry Andric } else if (auto *Record = dyn_cast<CXXRecordDecl>(D)) {
40800b57cec5SDimitry Andric if (Record->hasAttr<ExcludeFromExplicitInstantiationAttr>())
40810b57cec5SDimitry Andric continue;
40820b57cec5SDimitry Andric
40830b57cec5SDimitry Andric // Always skip the injected-class-name, along with any
40840b57cec5SDimitry Andric // redeclarations of nested classes, since both would cause us
40850b57cec5SDimitry Andric // to try to instantiate the members of a class twice.
40860b57cec5SDimitry Andric // Skip closure types; they'll get instantiated when we instantiate
40870b57cec5SDimitry Andric // the corresponding lambda-expression.
40880b57cec5SDimitry Andric if (Record->isInjectedClassName() || Record->getPreviousDecl() ||
40890b57cec5SDimitry Andric Record->isLambda())
40900b57cec5SDimitry Andric continue;
40910b57cec5SDimitry Andric
40920b57cec5SDimitry Andric MemberSpecializationInfo *MSInfo = Record->getMemberSpecializationInfo();
40930b57cec5SDimitry Andric assert(MSInfo && "No member specialization information?");
40940b57cec5SDimitry Andric
40950b57cec5SDimitry Andric if (MSInfo->getTemplateSpecializationKind()
40960b57cec5SDimitry Andric == TSK_ExplicitSpecialization)
40970b57cec5SDimitry Andric continue;
40980b57cec5SDimitry Andric
40990b57cec5SDimitry Andric if (Context.getTargetInfo().getTriple().isOSWindows() &&
41000b57cec5SDimitry Andric TSK == TSK_ExplicitInstantiationDeclaration) {
41010b57cec5SDimitry Andric // On Windows, explicit instantiation decl of the outer class doesn't
41020b57cec5SDimitry Andric // affect the inner class. Typically extern template declarations are
41030b57cec5SDimitry Andric // used in combination with dll import/export annotations, but those
41040b57cec5SDimitry Andric // are not propagated from the outer class templates to inner classes.
41050b57cec5SDimitry Andric // Therefore, do not instantiate inner classes on this platform, so
41060b57cec5SDimitry Andric // that users don't end up with undefined symbols during linking.
41070b57cec5SDimitry Andric continue;
41080b57cec5SDimitry Andric }
41090b57cec5SDimitry Andric
41100b57cec5SDimitry Andric if (CheckSpecializationInstantiationRedecl(PointOfInstantiation, TSK,
41110b57cec5SDimitry Andric Record,
41120b57cec5SDimitry Andric MSInfo->getTemplateSpecializationKind(),
41130b57cec5SDimitry Andric MSInfo->getPointOfInstantiation(),
41140b57cec5SDimitry Andric SuppressNew) ||
41150b57cec5SDimitry Andric SuppressNew)
41160b57cec5SDimitry Andric continue;
41170b57cec5SDimitry Andric
41180b57cec5SDimitry Andric CXXRecordDecl *Pattern = Record->getInstantiatedFromMemberClass();
41190b57cec5SDimitry Andric assert(Pattern && "Missing instantiated-from-template information");
41200b57cec5SDimitry Andric
41210b57cec5SDimitry Andric if (!Record->getDefinition()) {
41220b57cec5SDimitry Andric if (!Pattern->getDefinition()) {
41230b57cec5SDimitry Andric // C++0x [temp.explicit]p8:
41240b57cec5SDimitry Andric // An explicit instantiation definition that names a class template
41250b57cec5SDimitry Andric // specialization explicitly instantiates the class template
41260b57cec5SDimitry Andric // specialization and is only an explicit instantiation definition
41270b57cec5SDimitry Andric // of members whose definition is visible at the point of
41280b57cec5SDimitry Andric // instantiation.
41290b57cec5SDimitry Andric if (TSK == TSK_ExplicitInstantiationDeclaration) {
41300b57cec5SDimitry Andric MSInfo->setTemplateSpecializationKind(TSK);
41310b57cec5SDimitry Andric MSInfo->setPointOfInstantiation(PointOfInstantiation);
41320b57cec5SDimitry Andric }
41330b57cec5SDimitry Andric
41340b57cec5SDimitry Andric continue;
41350b57cec5SDimitry Andric }
41360b57cec5SDimitry Andric
41370b57cec5SDimitry Andric InstantiateClass(PointOfInstantiation, Record, Pattern,
41380b57cec5SDimitry Andric TemplateArgs,
41390b57cec5SDimitry Andric TSK);
41400b57cec5SDimitry Andric } else {
41410b57cec5SDimitry Andric if (TSK == TSK_ExplicitInstantiationDefinition &&
41420b57cec5SDimitry Andric Record->getTemplateSpecializationKind() ==
41430b57cec5SDimitry Andric TSK_ExplicitInstantiationDeclaration) {
41440b57cec5SDimitry Andric Record->setTemplateSpecializationKind(TSK);
41450b57cec5SDimitry Andric MarkVTableUsed(PointOfInstantiation, Record, true);
41460b57cec5SDimitry Andric }
41470b57cec5SDimitry Andric }
41480b57cec5SDimitry Andric
41490b57cec5SDimitry Andric Pattern = cast_or_null<CXXRecordDecl>(Record->getDefinition());
41500b57cec5SDimitry Andric if (Pattern)
41510b57cec5SDimitry Andric InstantiateClassMembers(PointOfInstantiation, Pattern, TemplateArgs,
41520b57cec5SDimitry Andric TSK);
41530b57cec5SDimitry Andric } else if (auto *Enum = dyn_cast<EnumDecl>(D)) {
41540b57cec5SDimitry Andric MemberSpecializationInfo *MSInfo = Enum->getMemberSpecializationInfo();
41550b57cec5SDimitry Andric assert(MSInfo && "No member specialization information?");
41560b57cec5SDimitry Andric
41570b57cec5SDimitry Andric if (MSInfo->getTemplateSpecializationKind()
41580b57cec5SDimitry Andric == TSK_ExplicitSpecialization)
41590b57cec5SDimitry Andric continue;
41600b57cec5SDimitry Andric
41610b57cec5SDimitry Andric if (CheckSpecializationInstantiationRedecl(
41620b57cec5SDimitry Andric PointOfInstantiation, TSK, Enum,
41630b57cec5SDimitry Andric MSInfo->getTemplateSpecializationKind(),
41640b57cec5SDimitry Andric MSInfo->getPointOfInstantiation(), SuppressNew) ||
41650b57cec5SDimitry Andric SuppressNew)
41660b57cec5SDimitry Andric continue;
41670b57cec5SDimitry Andric
41680b57cec5SDimitry Andric if (Enum->getDefinition())
41690b57cec5SDimitry Andric continue;
41700b57cec5SDimitry Andric
41710b57cec5SDimitry Andric EnumDecl *Pattern = Enum->getTemplateInstantiationPattern();
41720b57cec5SDimitry Andric assert(Pattern && "Missing instantiated-from-template information");
41730b57cec5SDimitry Andric
41740b57cec5SDimitry Andric if (TSK == TSK_ExplicitInstantiationDefinition) {
41750b57cec5SDimitry Andric if (!Pattern->getDefinition())
41760b57cec5SDimitry Andric continue;
41770b57cec5SDimitry Andric
41780b57cec5SDimitry Andric InstantiateEnum(PointOfInstantiation, Enum, Pattern, TemplateArgs, TSK);
41790b57cec5SDimitry Andric } else {
41800b57cec5SDimitry Andric MSInfo->setTemplateSpecializationKind(TSK);
41810b57cec5SDimitry Andric MSInfo->setPointOfInstantiation(PointOfInstantiation);
41820b57cec5SDimitry Andric }
41830b57cec5SDimitry Andric } else if (auto *Field = dyn_cast<FieldDecl>(D)) {
41840b57cec5SDimitry Andric // No need to instantiate in-class initializers during explicit
41850b57cec5SDimitry Andric // instantiation.
41860b57cec5SDimitry Andric if (Field->hasInClassInitializer() && TSK == TSK_ImplicitInstantiation) {
41870b57cec5SDimitry Andric CXXRecordDecl *ClassPattern =
41880b57cec5SDimitry Andric Instantiation->getTemplateInstantiationPattern();
41890b57cec5SDimitry Andric DeclContext::lookup_result Lookup =
41900b57cec5SDimitry Andric ClassPattern->lookup(Field->getDeclName());
4191fe6060f1SDimitry Andric FieldDecl *Pattern = Lookup.find_first<FieldDecl>();
4192fe6060f1SDimitry Andric assert(Pattern);
41930b57cec5SDimitry Andric InstantiateInClassInitializer(PointOfInstantiation, Field, Pattern,
41940b57cec5SDimitry Andric TemplateArgs);
41950b57cec5SDimitry Andric }
41960b57cec5SDimitry Andric }
41970b57cec5SDimitry Andric }
41980b57cec5SDimitry Andric }
41990b57cec5SDimitry Andric
42000b57cec5SDimitry Andric void
InstantiateClassTemplateSpecializationMembers(SourceLocation PointOfInstantiation,ClassTemplateSpecializationDecl * ClassTemplateSpec,TemplateSpecializationKind TSK)42010b57cec5SDimitry Andric Sema::InstantiateClassTemplateSpecializationMembers(
42020b57cec5SDimitry Andric SourceLocation PointOfInstantiation,
42030b57cec5SDimitry Andric ClassTemplateSpecializationDecl *ClassTemplateSpec,
42040b57cec5SDimitry Andric TemplateSpecializationKind TSK) {
42050b57cec5SDimitry Andric // C++0x [temp.explicit]p7:
42060b57cec5SDimitry Andric // An explicit instantiation that names a class template
42070b57cec5SDimitry Andric // specialization is an explicit instantion of the same kind
42080b57cec5SDimitry Andric // (declaration or definition) of each of its members (not
42090b57cec5SDimitry Andric // including members inherited from base classes) that has not
42100b57cec5SDimitry Andric // been previously explicitly specialized in the translation unit
42110b57cec5SDimitry Andric // containing the explicit instantiation, except as described
42120b57cec5SDimitry Andric // below.
42130b57cec5SDimitry Andric InstantiateClassMembers(PointOfInstantiation, ClassTemplateSpec,
42140b57cec5SDimitry Andric getTemplateInstantiationArgs(ClassTemplateSpec),
42150b57cec5SDimitry Andric TSK);
42160b57cec5SDimitry Andric }
42170b57cec5SDimitry Andric
42180b57cec5SDimitry Andric StmtResult
SubstStmt(Stmt * S,const MultiLevelTemplateArgumentList & TemplateArgs)42190b57cec5SDimitry Andric Sema::SubstStmt(Stmt *S, const MultiLevelTemplateArgumentList &TemplateArgs) {
42200b57cec5SDimitry Andric if (!S)
42210b57cec5SDimitry Andric return S;
42220b57cec5SDimitry Andric
42230b57cec5SDimitry Andric TemplateInstantiator Instantiator(*this, TemplateArgs,
42240b57cec5SDimitry Andric SourceLocation(),
42250b57cec5SDimitry Andric DeclarationName());
42260b57cec5SDimitry Andric return Instantiator.TransformStmt(S);
42270b57cec5SDimitry Andric }
42280b57cec5SDimitry Andric
SubstTemplateArgument(const TemplateArgumentLoc & Input,const MultiLevelTemplateArgumentList & TemplateArgs,TemplateArgumentLoc & Output,SourceLocation Loc,const DeclarationName & Entity)42290fca6ea1SDimitry Andric bool Sema::SubstTemplateArgument(
42300fca6ea1SDimitry Andric const TemplateArgumentLoc &Input,
42310fca6ea1SDimitry Andric const MultiLevelTemplateArgumentList &TemplateArgs,
42320fca6ea1SDimitry Andric TemplateArgumentLoc &Output, SourceLocation Loc,
42330fca6ea1SDimitry Andric const DeclarationName &Entity) {
42340fca6ea1SDimitry Andric TemplateInstantiator Instantiator(*this, TemplateArgs, Loc, Entity);
42350fca6ea1SDimitry Andric return Instantiator.TransformTemplateArgument(Input, Output);
42360fca6ea1SDimitry Andric }
42370fca6ea1SDimitry Andric
SubstTemplateArguments(ArrayRef<TemplateArgumentLoc> Args,const MultiLevelTemplateArgumentList & TemplateArgs,TemplateArgumentListInfo & Out)4238480093f4SDimitry Andric bool Sema::SubstTemplateArguments(
4239480093f4SDimitry Andric ArrayRef<TemplateArgumentLoc> Args,
4240480093f4SDimitry Andric const MultiLevelTemplateArgumentList &TemplateArgs,
4241480093f4SDimitry Andric TemplateArgumentListInfo &Out) {
4242bdd1243dSDimitry Andric TemplateInstantiator Instantiator(*this, TemplateArgs, SourceLocation(),
4243480093f4SDimitry Andric DeclarationName());
4244bdd1243dSDimitry Andric return Instantiator.TransformTemplateArguments(Args.begin(), Args.end(), Out);
4245480093f4SDimitry Andric }
4246480093f4SDimitry Andric
42470b57cec5SDimitry Andric ExprResult
SubstExpr(Expr * E,const MultiLevelTemplateArgumentList & TemplateArgs)42480b57cec5SDimitry Andric Sema::SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs) {
42490b57cec5SDimitry Andric if (!E)
42500b57cec5SDimitry Andric return E;
42510b57cec5SDimitry Andric
42520b57cec5SDimitry Andric TemplateInstantiator Instantiator(*this, TemplateArgs,
42530b57cec5SDimitry Andric SourceLocation(),
42540b57cec5SDimitry Andric DeclarationName());
42550b57cec5SDimitry Andric return Instantiator.TransformExpr(E);
42560b57cec5SDimitry Andric }
42570b57cec5SDimitry Andric
4258bdd1243dSDimitry Andric ExprResult
SubstConstraintExpr(Expr * E,const MultiLevelTemplateArgumentList & TemplateArgs)4259bdd1243dSDimitry Andric Sema::SubstConstraintExpr(Expr *E,
4260bdd1243dSDimitry Andric const MultiLevelTemplateArgumentList &TemplateArgs) {
42611db9f3b2SDimitry Andric // FIXME: should call SubstExpr directly if this function is equivalent or
42621db9f3b2SDimitry Andric // should it be different?
42631db9f3b2SDimitry Andric return SubstExpr(E, TemplateArgs);
42641db9f3b2SDimitry Andric }
42651db9f3b2SDimitry Andric
SubstConstraintExprWithoutSatisfaction(Expr * E,const MultiLevelTemplateArgumentList & TemplateArgs)42661db9f3b2SDimitry Andric ExprResult Sema::SubstConstraintExprWithoutSatisfaction(
42671db9f3b2SDimitry Andric Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs) {
4268bdd1243dSDimitry Andric if (!E)
4269bdd1243dSDimitry Andric return E;
4270bdd1243dSDimitry Andric
4271bdd1243dSDimitry Andric TemplateInstantiator Instantiator(*this, TemplateArgs, SourceLocation(),
4272bdd1243dSDimitry Andric DeclarationName());
42731db9f3b2SDimitry Andric Instantiator.setEvaluateConstraints(false);
4274bdd1243dSDimitry Andric return Instantiator.TransformExpr(E);
4275bdd1243dSDimitry Andric }
4276bdd1243dSDimitry Andric
SubstInitializer(Expr * Init,const MultiLevelTemplateArgumentList & TemplateArgs,bool CXXDirectInit)42770b57cec5SDimitry Andric ExprResult Sema::SubstInitializer(Expr *Init,
42780b57cec5SDimitry Andric const MultiLevelTemplateArgumentList &TemplateArgs,
42790b57cec5SDimitry Andric bool CXXDirectInit) {
4280bdd1243dSDimitry Andric TemplateInstantiator Instantiator(*this, TemplateArgs, SourceLocation(),
42810b57cec5SDimitry Andric DeclarationName());
42820b57cec5SDimitry Andric return Instantiator.TransformInitializer(Init, CXXDirectInit);
42830b57cec5SDimitry Andric }
42840b57cec5SDimitry Andric
SubstExprs(ArrayRef<Expr * > Exprs,bool IsCall,const MultiLevelTemplateArgumentList & TemplateArgs,SmallVectorImpl<Expr * > & Outputs)42850b57cec5SDimitry Andric bool Sema::SubstExprs(ArrayRef<Expr *> Exprs, bool IsCall,
42860b57cec5SDimitry Andric const MultiLevelTemplateArgumentList &TemplateArgs,
42870b57cec5SDimitry Andric SmallVectorImpl<Expr *> &Outputs) {
42880b57cec5SDimitry Andric if (Exprs.empty())
42890b57cec5SDimitry Andric return false;
42900b57cec5SDimitry Andric
42910b57cec5SDimitry Andric TemplateInstantiator Instantiator(*this, TemplateArgs,
42920b57cec5SDimitry Andric SourceLocation(),
42930b57cec5SDimitry Andric DeclarationName());
42940b57cec5SDimitry Andric return Instantiator.TransformExprs(Exprs.data(), Exprs.size(),
42950b57cec5SDimitry Andric IsCall, Outputs);
42960b57cec5SDimitry Andric }
42970b57cec5SDimitry Andric
42980b57cec5SDimitry Andric NestedNameSpecifierLoc
SubstNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,const MultiLevelTemplateArgumentList & TemplateArgs)42990b57cec5SDimitry Andric Sema::SubstNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
43000b57cec5SDimitry Andric const MultiLevelTemplateArgumentList &TemplateArgs) {
43010b57cec5SDimitry Andric if (!NNS)
43020b57cec5SDimitry Andric return NestedNameSpecifierLoc();
43030b57cec5SDimitry Andric
43040b57cec5SDimitry Andric TemplateInstantiator Instantiator(*this, TemplateArgs, NNS.getBeginLoc(),
43050b57cec5SDimitry Andric DeclarationName());
43060b57cec5SDimitry Andric return Instantiator.TransformNestedNameSpecifierLoc(NNS);
43070b57cec5SDimitry Andric }
43080b57cec5SDimitry Andric
43090b57cec5SDimitry Andric DeclarationNameInfo
SubstDeclarationNameInfo(const DeclarationNameInfo & NameInfo,const MultiLevelTemplateArgumentList & TemplateArgs)43100b57cec5SDimitry Andric Sema::SubstDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
43110b57cec5SDimitry Andric const MultiLevelTemplateArgumentList &TemplateArgs) {
43120b57cec5SDimitry Andric TemplateInstantiator Instantiator(*this, TemplateArgs, NameInfo.getLoc(),
43130b57cec5SDimitry Andric NameInfo.getName());
43140b57cec5SDimitry Andric return Instantiator.TransformDeclarationNameInfo(NameInfo);
43150b57cec5SDimitry Andric }
43160b57cec5SDimitry Andric
43170b57cec5SDimitry Andric TemplateName
SubstTemplateName(NestedNameSpecifierLoc QualifierLoc,TemplateName Name,SourceLocation Loc,const MultiLevelTemplateArgumentList & TemplateArgs)43180b57cec5SDimitry Andric Sema::SubstTemplateName(NestedNameSpecifierLoc QualifierLoc,
43190b57cec5SDimitry Andric TemplateName Name, SourceLocation Loc,
43200b57cec5SDimitry Andric const MultiLevelTemplateArgumentList &TemplateArgs) {
43210b57cec5SDimitry Andric TemplateInstantiator Instantiator(*this, TemplateArgs, Loc,
43220b57cec5SDimitry Andric DeclarationName());
43230b57cec5SDimitry Andric CXXScopeSpec SS;
43240b57cec5SDimitry Andric SS.Adopt(QualifierLoc);
43250b57cec5SDimitry Andric return Instantiator.TransformTemplateName(SS, Name, Loc);
43260b57cec5SDimitry Andric }
43270b57cec5SDimitry Andric
getCanonicalParmVarDecl(const Decl * D)43280b57cec5SDimitry Andric static const Decl *getCanonicalParmVarDecl(const Decl *D) {
43290b57cec5SDimitry Andric // When storing ParmVarDecls in the local instantiation scope, we always
43300b57cec5SDimitry Andric // want to use the ParmVarDecl from the canonical function declaration,
43310b57cec5SDimitry Andric // since the map is then valid for any redeclaration or definition of that
43320b57cec5SDimitry Andric // function.
43330b57cec5SDimitry Andric if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(D)) {
43340b57cec5SDimitry Andric if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
43350b57cec5SDimitry Andric unsigned i = PV->getFunctionScopeIndex();
43360b57cec5SDimitry Andric // This parameter might be from a freestanding function type within the
43370b57cec5SDimitry Andric // function and isn't necessarily referring to one of FD's parameters.
43380b57cec5SDimitry Andric if (i < FD->getNumParams() && FD->getParamDecl(i) == PV)
43390b57cec5SDimitry Andric return FD->getCanonicalDecl()->getParamDecl(i);
43400b57cec5SDimitry Andric }
43410b57cec5SDimitry Andric }
43420b57cec5SDimitry Andric return D;
43430b57cec5SDimitry Andric }
43440b57cec5SDimitry Andric
43450b57cec5SDimitry Andric
43460b57cec5SDimitry Andric llvm::PointerUnion<Decl *, LocalInstantiationScope::DeclArgumentPack *> *
findInstantiationOf(const Decl * D)43470b57cec5SDimitry Andric LocalInstantiationScope::findInstantiationOf(const Decl *D) {
43480b57cec5SDimitry Andric D = getCanonicalParmVarDecl(D);
43490b57cec5SDimitry Andric for (LocalInstantiationScope *Current = this; Current;
43500b57cec5SDimitry Andric Current = Current->Outer) {
43510b57cec5SDimitry Andric
43520b57cec5SDimitry Andric // Check if we found something within this scope.
43530b57cec5SDimitry Andric const Decl *CheckD = D;
43540b57cec5SDimitry Andric do {
43550b57cec5SDimitry Andric LocalDeclsMap::iterator Found = Current->LocalDecls.find(CheckD);
43560b57cec5SDimitry Andric if (Found != Current->LocalDecls.end())
43570b57cec5SDimitry Andric return &Found->second;
43580b57cec5SDimitry Andric
43590b57cec5SDimitry Andric // If this is a tag declaration, it's possible that we need to look for
43600b57cec5SDimitry Andric // a previous declaration.
43610b57cec5SDimitry Andric if (const TagDecl *Tag = dyn_cast<TagDecl>(CheckD))
43620b57cec5SDimitry Andric CheckD = Tag->getPreviousDecl();
43630b57cec5SDimitry Andric else
43640b57cec5SDimitry Andric CheckD = nullptr;
43650b57cec5SDimitry Andric } while (CheckD);
43660b57cec5SDimitry Andric
43670b57cec5SDimitry Andric // If we aren't combined with our outer scope, we're done.
43680b57cec5SDimitry Andric if (!Current->CombineWithOuterScope)
43690b57cec5SDimitry Andric break;
43700b57cec5SDimitry Andric }
43710b57cec5SDimitry Andric
43720b57cec5SDimitry Andric // If we're performing a partial substitution during template argument
43730b57cec5SDimitry Andric // deduction, we may not have values for template parameters yet.
43740b57cec5SDimitry Andric if (isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D) ||
43750b57cec5SDimitry Andric isa<TemplateTemplateParmDecl>(D))
43760b57cec5SDimitry Andric return nullptr;
43770b57cec5SDimitry Andric
43780b57cec5SDimitry Andric // Local types referenced prior to definition may require instantiation.
43790b57cec5SDimitry Andric if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
43800b57cec5SDimitry Andric if (RD->isLocalClass())
43810b57cec5SDimitry Andric return nullptr;
43820b57cec5SDimitry Andric
43830b57cec5SDimitry Andric // Enumeration types referenced prior to definition may appear as a result of
43840b57cec5SDimitry Andric // error recovery.
43850b57cec5SDimitry Andric if (isa<EnumDecl>(D))
43860b57cec5SDimitry Andric return nullptr;
43870b57cec5SDimitry Andric
43885ffd83dbSDimitry Andric // Materialized typedefs/type alias for implicit deduction guides may require
43895ffd83dbSDimitry Andric // instantiation.
43905ffd83dbSDimitry Andric if (isa<TypedefNameDecl>(D) &&
43915ffd83dbSDimitry Andric isa<CXXDeductionGuideDecl>(D->getDeclContext()))
43925ffd83dbSDimitry Andric return nullptr;
43935ffd83dbSDimitry Andric
43940b57cec5SDimitry Andric // If we didn't find the decl, then we either have a sema bug, or we have a
43950b57cec5SDimitry Andric // forward reference to a label declaration. Return null to indicate that
43960b57cec5SDimitry Andric // we have an uninstantiated label.
43970b57cec5SDimitry Andric assert(isa<LabelDecl>(D) && "declaration not instantiated in this scope");
43980b57cec5SDimitry Andric return nullptr;
43990b57cec5SDimitry Andric }
44000b57cec5SDimitry Andric
InstantiatedLocal(const Decl * D,Decl * Inst)44010b57cec5SDimitry Andric void LocalInstantiationScope::InstantiatedLocal(const Decl *D, Decl *Inst) {
44020b57cec5SDimitry Andric D = getCanonicalParmVarDecl(D);
44030b57cec5SDimitry Andric llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored = LocalDecls[D];
44040b57cec5SDimitry Andric if (Stored.isNull()) {
44050b57cec5SDimitry Andric #ifndef NDEBUG
44060b57cec5SDimitry Andric // It should not be present in any surrounding scope either.
44070b57cec5SDimitry Andric LocalInstantiationScope *Current = this;
44080b57cec5SDimitry Andric while (Current->CombineWithOuterScope && Current->Outer) {
44090b57cec5SDimitry Andric Current = Current->Outer;
44105f757f3fSDimitry Andric assert(!Current->LocalDecls.contains(D) &&
44110b57cec5SDimitry Andric "Instantiated local in inner and outer scopes");
44120b57cec5SDimitry Andric }
44130b57cec5SDimitry Andric #endif
44140b57cec5SDimitry Andric Stored = Inst;
44150b57cec5SDimitry Andric } else if (DeclArgumentPack *Pack = Stored.dyn_cast<DeclArgumentPack *>()) {
44160b57cec5SDimitry Andric Pack->push_back(cast<VarDecl>(Inst));
44170b57cec5SDimitry Andric } else {
44180b57cec5SDimitry Andric assert(Stored.get<Decl *>() == Inst && "Already instantiated this local");
44190b57cec5SDimitry Andric }
44200b57cec5SDimitry Andric }
44210b57cec5SDimitry Andric
InstantiatedLocalPackArg(const Decl * D,VarDecl * Inst)44220b57cec5SDimitry Andric void LocalInstantiationScope::InstantiatedLocalPackArg(const Decl *D,
44230b57cec5SDimitry Andric VarDecl *Inst) {
44240b57cec5SDimitry Andric D = getCanonicalParmVarDecl(D);
44250b57cec5SDimitry Andric DeclArgumentPack *Pack = LocalDecls[D].get<DeclArgumentPack *>();
44260b57cec5SDimitry Andric Pack->push_back(Inst);
44270b57cec5SDimitry Andric }
44280b57cec5SDimitry Andric
MakeInstantiatedLocalArgPack(const Decl * D)44290b57cec5SDimitry Andric void LocalInstantiationScope::MakeInstantiatedLocalArgPack(const Decl *D) {
44300b57cec5SDimitry Andric #ifndef NDEBUG
44310b57cec5SDimitry Andric // This should be the first time we've been told about this decl.
44320b57cec5SDimitry Andric for (LocalInstantiationScope *Current = this;
44330b57cec5SDimitry Andric Current && Current->CombineWithOuterScope; Current = Current->Outer)
44345f757f3fSDimitry Andric assert(!Current->LocalDecls.contains(D) &&
44350b57cec5SDimitry Andric "Creating local pack after instantiation of local");
44360b57cec5SDimitry Andric #endif
44370b57cec5SDimitry Andric
44380b57cec5SDimitry Andric D = getCanonicalParmVarDecl(D);
44390b57cec5SDimitry Andric llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored = LocalDecls[D];
44400b57cec5SDimitry Andric DeclArgumentPack *Pack = new DeclArgumentPack;
44410b57cec5SDimitry Andric Stored = Pack;
44420b57cec5SDimitry Andric ArgumentPacks.push_back(Pack);
44430b57cec5SDimitry Andric }
44440b57cec5SDimitry Andric
isLocalPackExpansion(const Decl * D)44455ffd83dbSDimitry Andric bool LocalInstantiationScope::isLocalPackExpansion(const Decl *D) {
44465ffd83dbSDimitry Andric for (DeclArgumentPack *Pack : ArgumentPacks)
4447349cc55cSDimitry Andric if (llvm::is_contained(*Pack, D))
44485ffd83dbSDimitry Andric return true;
44495ffd83dbSDimitry Andric return false;
44505ffd83dbSDimitry Andric }
44515ffd83dbSDimitry Andric
SetPartiallySubstitutedPack(NamedDecl * Pack,const TemplateArgument * ExplicitArgs,unsigned NumExplicitArgs)44520b57cec5SDimitry Andric void LocalInstantiationScope::SetPartiallySubstitutedPack(NamedDecl *Pack,
44530b57cec5SDimitry Andric const TemplateArgument *ExplicitArgs,
44540b57cec5SDimitry Andric unsigned NumExplicitArgs) {
44550b57cec5SDimitry Andric assert((!PartiallySubstitutedPack || PartiallySubstitutedPack == Pack) &&
44560b57cec5SDimitry Andric "Already have a partially-substituted pack");
44570b57cec5SDimitry Andric assert((!PartiallySubstitutedPack
44580b57cec5SDimitry Andric || NumArgsInPartiallySubstitutedPack == NumExplicitArgs) &&
44590b57cec5SDimitry Andric "Wrong number of arguments in partially-substituted pack");
44600b57cec5SDimitry Andric PartiallySubstitutedPack = Pack;
44610b57cec5SDimitry Andric ArgsInPartiallySubstitutedPack = ExplicitArgs;
44620b57cec5SDimitry Andric NumArgsInPartiallySubstitutedPack = NumExplicitArgs;
44630b57cec5SDimitry Andric }
44640b57cec5SDimitry Andric
getPartiallySubstitutedPack(const TemplateArgument ** ExplicitArgs,unsigned * NumExplicitArgs) const44650b57cec5SDimitry Andric NamedDecl *LocalInstantiationScope::getPartiallySubstitutedPack(
44660b57cec5SDimitry Andric const TemplateArgument **ExplicitArgs,
44670b57cec5SDimitry Andric unsigned *NumExplicitArgs) const {
44680b57cec5SDimitry Andric if (ExplicitArgs)
44690b57cec5SDimitry Andric *ExplicitArgs = nullptr;
44700b57cec5SDimitry Andric if (NumExplicitArgs)
44710b57cec5SDimitry Andric *NumExplicitArgs = 0;
44720b57cec5SDimitry Andric
44730b57cec5SDimitry Andric for (const LocalInstantiationScope *Current = this; Current;
44740b57cec5SDimitry Andric Current = Current->Outer) {
44750b57cec5SDimitry Andric if (Current->PartiallySubstitutedPack) {
44760b57cec5SDimitry Andric if (ExplicitArgs)
44770b57cec5SDimitry Andric *ExplicitArgs = Current->ArgsInPartiallySubstitutedPack;
44780b57cec5SDimitry Andric if (NumExplicitArgs)
44790b57cec5SDimitry Andric *NumExplicitArgs = Current->NumArgsInPartiallySubstitutedPack;
44800b57cec5SDimitry Andric
44810b57cec5SDimitry Andric return Current->PartiallySubstitutedPack;
44820b57cec5SDimitry Andric }
44830b57cec5SDimitry Andric
44840b57cec5SDimitry Andric if (!Current->CombineWithOuterScope)
44850b57cec5SDimitry Andric break;
44860b57cec5SDimitry Andric }
44870b57cec5SDimitry Andric
44880b57cec5SDimitry Andric return nullptr;
44890b57cec5SDimitry Andric }
4490