xref: /freebsd-src/contrib/llvm-project/clang/lib/Sema/SemaTemplateInstantiate.cpp (revision 6c4b055cfb6bf549e9145dde6454cc6b178c35e4)
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"
23*6c4b055cSDimitry 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;
59bdd1243dSDimitry Andric   static Response Done() {
60bdd1243dSDimitry Andric     Response R;
61bdd1243dSDimitry Andric     R.IsDone = true;
62bdd1243dSDimitry Andric     return R;
63bdd1243dSDimitry Andric   }
64bdd1243dSDimitry Andric   static Response ChangeDecl(const Decl *ND) {
65bdd1243dSDimitry Andric     Response R;
66bdd1243dSDimitry Andric     R.NextDecl = ND;
67bdd1243dSDimitry Andric     return R;
68bdd1243dSDimitry Andric   }
69bdd1243dSDimitry 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 
75bdd1243dSDimitry Andric   static Response UseNextDecl(const Decl *CurDecl) {
76bdd1243dSDimitry Andric     return ChangeDecl(CurDecl->getDeclContext());
77bdd1243dSDimitry Andric   }
780b57cec5SDimitry Andric 
79bdd1243dSDimitry 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 *
900fca6ea1SDimitry Andric getPrimaryTemplateOfGenericLambda(const FunctionDecl *LambdaCallOperator) {
91*6c4b055cSDimitry Andric   if (!isLambdaCallOperator(LambdaCallOperator))
92*6c4b055cSDimitry 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();
99*6c4b055cSDimitry Andric     } else if (LambdaCallOperator->getPrimaryTemplate()) {
100*6c4b055cSDimitry Andric       // Cases where the lambda operator is instantiated in
101*6c4b055cSDimitry Andric       // TemplateDeclInstantiator::VisitCXXMethodDecl.
102*6c4b055cSDimitry Andric       LambdaCallOperator =
103*6c4b055cSDimitry 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 
1180fca6ea1SDimitry 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
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.
1520fca6ea1SDimitry Andric bool isLambdaEnclosedByTypeAliasDecl(
153*6c4b055cSDimitry Andric     const FunctionDecl *LambdaCallOperator,
1540fca6ea1SDimitry Andric     const TypeAliasTemplateDecl *PrimaryTypeAliasDecl) {
155*6c4b055cSDimitry Andric   struct Visitor : RecursiveASTVisitor<Visitor> {
156*6c4b055cSDimitry Andric     Visitor(const FunctionDecl *CallOperator) : CallOperator(CallOperator) {}
157*6c4b055cSDimitry Andric     bool VisitLambdaExpr(const LambdaExpr *LE) {
158*6c4b055cSDimitry Andric       // Return true to bail out of the traversal, implying the Decl contains
159*6c4b055cSDimitry Andric       // the lambda.
160*6c4b055cSDimitry Andric       return getPrimaryTemplateOfGenericLambda(LE->getCallOperator()) !=
161*6c4b055cSDimitry Andric              CallOperator;
162*6c4b055cSDimitry Andric     }
163*6c4b055cSDimitry Andric     const FunctionDecl *CallOperator;
164*6c4b055cSDimitry Andric   };
165*6c4b055cSDimitry Andric 
166*6c4b055cSDimitry Andric   QualType Underlying =
167*6c4b055cSDimitry Andric       PrimaryTypeAliasDecl->getTemplatedDecl()->getUnderlyingType();
168*6c4b055cSDimitry Andric 
169*6c4b055cSDimitry Andric   return !Visitor(getPrimaryTemplateOfGenericLambda(LambdaCallOperator))
170*6c4b055cSDimitry Andric               .TraverseType(Underlying);
1710fca6ea1SDimitry Andric }
1720fca6ea1SDimitry Andric 
173bdd1243dSDimitry Andric // Add template arguments from a variable template instantiation.
174bdd1243dSDimitry Andric Response
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
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 
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
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 
2690fca6ea1SDimitry Andric Response HandleFunction(Sema &SemaRef, const FunctionDecl *Function,
270bdd1243dSDimitry Andric                         MultiLevelTemplateArgumentList &Result,
271bdd1243dSDimitry Andric                         const FunctionDecl *Pattern, bool RelativeToPrimary,
272bdd1243dSDimitry Andric                         bool ForConstraintInstantiation) {
2730b57cec5SDimitry Andric   // Add template arguments from a function template specialization.
2740b57cec5SDimitry Andric   if (!RelativeToPrimary &&
2750b57cec5SDimitry Andric       Function->getTemplateSpecializationKindForInstantiation() ==
2760b57cec5SDimitry Andric           TSK_ExplicitSpecialization)
277bdd1243dSDimitry Andric     return Response::Done();
2780b57cec5SDimitry Andric 
279bdd1243dSDimitry Andric   if (!RelativeToPrimary &&
280bdd1243dSDimitry Andric       Function->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) {
281e8d8bef9SDimitry Andric     // This is an implicit instantiation of an explicit specialization. We
282e8d8bef9SDimitry Andric     // don't get any template arguments from this function but might get
283e8d8bef9SDimitry Andric     // some from an enclosing template.
284bdd1243dSDimitry Andric     return Response::UseNextDecl(Function);
285bdd1243dSDimitry Andric   } else if (const TemplateArgumentList *TemplateArgs =
286bdd1243dSDimitry Andric                  Function->getTemplateSpecializationArgs()) {
2870b57cec5SDimitry Andric     // Add the template arguments for this specialization.
288bdd1243dSDimitry Andric     Result.addOuterTemplateArguments(const_cast<FunctionDecl *>(Function),
289bdd1243dSDimitry Andric                                      TemplateArgs->asArray(),
290bdd1243dSDimitry Andric                                      /*Final=*/false);
2910b57cec5SDimitry Andric 
2920fca6ea1SDimitry Andric     if (RelativeToPrimary &&
2930fca6ea1SDimitry Andric         (Function->getTemplateSpecializationKind() ==
2940fca6ea1SDimitry Andric              TSK_ExplicitSpecialization ||
2950fca6ea1SDimitry Andric          (Function->getFriendObjectKind() &&
2960fca6ea1SDimitry Andric           !Function->getPrimaryTemplate()->getFriendObjectKind())))
2970fca6ea1SDimitry Andric       return Response::UseNextDecl(Function);
2980fca6ea1SDimitry Andric 
2990b57cec5SDimitry Andric     // If this function was instantiated from a specialized member that is
3000b57cec5SDimitry Andric     // a function template, we're done.
3010b57cec5SDimitry Andric     assert(Function->getPrimaryTemplate() && "No function template?");
3020b57cec5SDimitry Andric     if (Function->getPrimaryTemplate()->isMemberSpecialization())
303bdd1243dSDimitry Andric       return Response::Done();
3040b57cec5SDimitry Andric 
3050b57cec5SDimitry Andric     // If this function is a generic lambda specialization, we are done.
306bdd1243dSDimitry Andric     if (!ForConstraintInstantiation &&
307*6c4b055cSDimitry Andric         isGenericLambdaCallOperatorOrStaticInvokerSpecialization(Function))
308bdd1243dSDimitry Andric       return Response::Done();
3090b57cec5SDimitry Andric 
310349cc55cSDimitry Andric   } else if (Function->getDescribedFunctionTemplate()) {
311bdd1243dSDimitry Andric     assert(
312bdd1243dSDimitry Andric         (ForConstraintInstantiation || Result.getNumSubstitutedLevels() == 0) &&
313349cc55cSDimitry Andric         "Outer template not instantiated?");
3140b57cec5SDimitry Andric   }
315bdd1243dSDimitry Andric   // If this is a friend or local declaration and it declares an entity at
3160b57cec5SDimitry Andric   // namespace scope, take arguments from its lexical parent
3170b57cec5SDimitry Andric   // instead of its semantic parent, unless of course the pattern we're
3180b57cec5SDimitry Andric   // instantiating actually comes from the file's context!
319bdd1243dSDimitry Andric   if ((Function->getFriendObjectKind() || Function->isLocalExternDecl()) &&
320bdd1243dSDimitry Andric       Function->getNonTransparentDeclContext()->isFileContext() &&
3210b57cec5SDimitry Andric       (!Pattern || !Pattern->getLexicalDeclContext()->isFileContext())) {
322bdd1243dSDimitry Andric     return Response::ChangeDecl(Function->getLexicalDeclContext());
3230b57cec5SDimitry Andric   }
3247a6dacacSDimitry Andric 
3257a6dacacSDimitry Andric   if (ForConstraintInstantiation && Function->getFriendObjectKind())
3267a6dacacSDimitry Andric     return Response::ChangeDecl(Function->getLexicalDeclContext());
327bdd1243dSDimitry Andric   return Response::UseNextDecl(Function);
328bdd1243dSDimitry Andric }
329bdd1243dSDimitry Andric 
33006c3fb27SDimitry Andric Response HandleFunctionTemplateDecl(const FunctionTemplateDecl *FTD,
33106c3fb27SDimitry Andric                                     MultiLevelTemplateArgumentList &Result) {
33206c3fb27SDimitry Andric   if (!isa<ClassTemplateSpecializationDecl>(FTD->getDeclContext())) {
3335f757f3fSDimitry Andric     Result.addOuterTemplateArguments(
3345f757f3fSDimitry Andric         const_cast<FunctionTemplateDecl *>(FTD),
3355f757f3fSDimitry Andric         const_cast<FunctionTemplateDecl *>(FTD)->getInjectedTemplateArgs(),
3365f757f3fSDimitry Andric         /*Final=*/false);
3375f757f3fSDimitry Andric 
33806c3fb27SDimitry Andric     NestedNameSpecifier *NNS = FTD->getTemplatedDecl()->getQualifier();
3395f757f3fSDimitry Andric 
3405f757f3fSDimitry Andric     while (const Type *Ty = NNS ? NNS->getAsType() : nullptr) {
3415f757f3fSDimitry Andric       if (NNS->isInstantiationDependent()) {
3420fca6ea1SDimitry Andric         if (const auto *TSTy = Ty->getAs<TemplateSpecializationType>()) {
3430fca6ea1SDimitry Andric           ArrayRef<TemplateArgument> Arguments = TSTy->template_arguments();
3440fca6ea1SDimitry Andric           // Prefer template arguments from the injected-class-type if possible.
3450fca6ea1SDimitry Andric           // For example,
3460fca6ea1SDimitry Andric           // ```cpp
3470fca6ea1SDimitry Andric           // template <class... Pack> struct S {
3480fca6ea1SDimitry Andric           //   template <class T> void foo();
3490fca6ea1SDimitry Andric           // };
3500fca6ea1SDimitry Andric           // template <class... Pack> template <class T>
3510fca6ea1SDimitry Andric           //           ^^^^^^^^^^^^^ InjectedTemplateArgs
3520fca6ea1SDimitry Andric           //           They're of kind TemplateArgument::Pack, not of
3530fca6ea1SDimitry Andric           //           TemplateArgument::Type.
3540fca6ea1SDimitry Andric           // void S<Pack...>::foo() {}
3550fca6ea1SDimitry Andric           //        ^^^^^^^
3560fca6ea1SDimitry Andric           //        TSTy->template_arguments() (which are of PackExpansionType)
3570fca6ea1SDimitry Andric           // ```
3580fca6ea1SDimitry Andric           // This meets the contract in
3590fca6ea1SDimitry Andric           // TreeTransform::TryExpandParameterPacks that the template arguments
3600fca6ea1SDimitry Andric           // for unexpanded parameters should be of a Pack kind.
3610fca6ea1SDimitry Andric           if (TSTy->isCurrentInstantiation()) {
3620fca6ea1SDimitry Andric             auto *RD = TSTy->getCanonicalTypeInternal()->getAsCXXRecordDecl();
3630fca6ea1SDimitry Andric             if (ClassTemplateDecl *CTD = RD->getDescribedClassTemplate())
3640fca6ea1SDimitry Andric               Arguments = CTD->getInjectedTemplateArgs();
3650fca6ea1SDimitry Andric             else if (auto *Specialization =
3660fca6ea1SDimitry Andric                          dyn_cast<ClassTemplateSpecializationDecl>(RD))
3670fca6ea1SDimitry Andric               Arguments =
3680fca6ea1SDimitry Andric                   Specialization->getTemplateInstantiationArgs().asArray();
3690fca6ea1SDimitry Andric           }
3705f757f3fSDimitry Andric           Result.addOuterTemplateArguments(
3710fca6ea1SDimitry Andric               const_cast<FunctionTemplateDecl *>(FTD), Arguments,
37206c3fb27SDimitry Andric               /*Final=*/false);
37306c3fb27SDimitry Andric         }
3740fca6ea1SDimitry Andric       }
3755f757f3fSDimitry Andric 
3765f757f3fSDimitry Andric       NNS = NNS->getPrefix();
3775f757f3fSDimitry Andric     }
3785f757f3fSDimitry Andric   }
3795f757f3fSDimitry Andric 
38006c3fb27SDimitry Andric   return Response::ChangeDecl(FTD->getLexicalDeclContext());
38106c3fb27SDimitry Andric }
38206c3fb27SDimitry Andric 
3830fca6ea1SDimitry Andric Response HandleRecordDecl(Sema &SemaRef, const CXXRecordDecl *Rec,
384bdd1243dSDimitry Andric                           MultiLevelTemplateArgumentList &Result,
385bdd1243dSDimitry Andric                           ASTContext &Context,
386bdd1243dSDimitry Andric                           bool ForConstraintInstantiation) {
3870b57cec5SDimitry Andric   if (ClassTemplateDecl *ClassTemplate = Rec->getDescribedClassTemplate()) {
388bdd1243dSDimitry Andric     assert(
389bdd1243dSDimitry Andric         (ForConstraintInstantiation || Result.getNumSubstitutedLevels() == 0) &&
390349cc55cSDimitry Andric         "Outer template not instantiated?");
3910b57cec5SDimitry Andric     if (ClassTemplate->isMemberSpecialization())
392bdd1243dSDimitry Andric       return Response::Done();
39306c3fb27SDimitry Andric     if (ForConstraintInstantiation)
394bdd1243dSDimitry Andric       Result.addOuterTemplateArguments(const_cast<CXXRecordDecl *>(Rec),
39506c3fb27SDimitry Andric                                        ClassTemplate->getInjectedTemplateArgs(),
396bdd1243dSDimitry Andric                                        /*Final=*/false);
3970b57cec5SDimitry Andric   }
39806c3fb27SDimitry Andric 
39906c3fb27SDimitry Andric   if (const MemberSpecializationInfo *MSInfo =
40006c3fb27SDimitry Andric           Rec->getMemberSpecializationInfo())
40106c3fb27SDimitry Andric     if (MSInfo->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
40206c3fb27SDimitry Andric       return Response::Done();
4030b57cec5SDimitry Andric 
404bdd1243dSDimitry Andric   bool IsFriend = Rec->getFriendObjectKind() ||
405bdd1243dSDimitry Andric                   (Rec->getDescribedClassTemplate() &&
406bdd1243dSDimitry Andric                    Rec->getDescribedClassTemplate()->getFriendObjectKind());
407bdd1243dSDimitry Andric   if (ForConstraintInstantiation && IsFriend &&
408bdd1243dSDimitry Andric       Rec->getNonTransparentDeclContext()->isFileContext()) {
409bdd1243dSDimitry Andric     return Response::ChangeDecl(Rec->getLexicalDeclContext());
410bdd1243dSDimitry Andric   }
411bdd1243dSDimitry Andric 
4120fca6ea1SDimitry Andric   // This is to make sure we pick up the VarTemplateSpecializationDecl or the
4130fca6ea1SDimitry Andric   // TypeAliasTemplateDecl that this lambda is defined inside of.
4140fca6ea1SDimitry Andric   if (Rec->isLambda()) {
415bdd1243dSDimitry Andric     if (const Decl *LCD = Rec->getLambdaContextDecl())
416bdd1243dSDimitry Andric       return Response::ChangeDecl(LCD);
4170fca6ea1SDimitry Andric     // Retrieve the template arguments for a using alias declaration.
4180fca6ea1SDimitry Andric     // This is necessary for constraint checking, since we always keep
4190fca6ea1SDimitry Andric     // constraints relative to the primary template.
420*6c4b055cSDimitry Andric     if (auto TypeAlias = getEnclosingTypeAliasTemplateDecl(SemaRef);
421*6c4b055cSDimitry Andric         ForConstraintInstantiation && TypeAlias) {
422*6c4b055cSDimitry Andric       if (isLambdaEnclosedByTypeAliasDecl(Rec->getLambdaCallOperator(),
4230fca6ea1SDimitry Andric                                           TypeAlias.PrimaryTypeAliasDecl)) {
4240fca6ea1SDimitry Andric         Result.addOuterTemplateArguments(TypeAlias.Template,
4250fca6ea1SDimitry Andric                                          TypeAlias.AssociatedTemplateArguments,
4260fca6ea1SDimitry Andric                                          /*Final=*/false);
4270fca6ea1SDimitry Andric         // Visit the parent of the current type alias declaration rather than
4280fca6ea1SDimitry Andric         // the lambda thereof.
4290fca6ea1SDimitry Andric         // E.g., in the following example:
4300fca6ea1SDimitry Andric         // struct S {
4310fca6ea1SDimitry Andric         //  template <class> using T = decltype([]<Concept> {} ());
4320fca6ea1SDimitry Andric         // };
4330fca6ea1SDimitry Andric         // void foo() {
4340fca6ea1SDimitry Andric         //   S::T var;
4350fca6ea1SDimitry Andric         // }
4360fca6ea1SDimitry Andric         // The instantiated lambda expression (which we're visiting at 'var')
4370fca6ea1SDimitry Andric         // has a function DeclContext 'foo' rather than the Record DeclContext
4380fca6ea1SDimitry Andric         // S. This seems to be an oversight to me that we may want to set a
4390fca6ea1SDimitry Andric         // Sema Context from the CXXScopeSpec before substituting into T.
4400fca6ea1SDimitry Andric         return Response::ChangeDecl(TypeAlias.Template->getDeclContext());
4410fca6ea1SDimitry Andric       }
4420fca6ea1SDimitry Andric     }
4430fca6ea1SDimitry Andric   }
444bdd1243dSDimitry Andric 
445bdd1243dSDimitry Andric   return Response::UseNextDecl(Rec);
446bdd1243dSDimitry Andric }
447bdd1243dSDimitry Andric 
448bdd1243dSDimitry Andric Response HandleImplicitConceptSpecializationDecl(
449bdd1243dSDimitry Andric     const ImplicitConceptSpecializationDecl *CSD,
450bdd1243dSDimitry Andric     MultiLevelTemplateArgumentList &Result) {
451bdd1243dSDimitry Andric   Result.addOuterTemplateArguments(
452bdd1243dSDimitry Andric       const_cast<ImplicitConceptSpecializationDecl *>(CSD),
453bdd1243dSDimitry Andric       CSD->getTemplateArguments(),
454bdd1243dSDimitry Andric       /*Final=*/false);
455bdd1243dSDimitry Andric   return Response::UseNextDecl(CSD);
456bdd1243dSDimitry Andric }
457bdd1243dSDimitry Andric 
458bdd1243dSDimitry Andric Response HandleGenericDeclContext(const Decl *CurDecl) {
459bdd1243dSDimitry Andric   return Response::UseNextDecl(CurDecl);
460bdd1243dSDimitry Andric }
461bdd1243dSDimitry Andric } // namespace TemplateInstArgsHelpers
462bdd1243dSDimitry Andric } // namespace
463bdd1243dSDimitry Andric 
464bdd1243dSDimitry Andric MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs(
4655f757f3fSDimitry Andric     const NamedDecl *ND, const DeclContext *DC, bool Final,
4660fca6ea1SDimitry Andric     std::optional<ArrayRef<TemplateArgument>> Innermost, bool RelativeToPrimary,
4675f757f3fSDimitry Andric     const FunctionDecl *Pattern, bool ForConstraintInstantiation,
4685f757f3fSDimitry Andric     bool SkipForSpecialization) {
4695f757f3fSDimitry Andric   assert((ND || DC) && "Can't find arguments for a decl if one isn't provided");
470bdd1243dSDimitry Andric   // Accumulate the set of template argument lists in this structure.
471bdd1243dSDimitry Andric   MultiLevelTemplateArgumentList Result;
472bdd1243dSDimitry Andric 
47306c3fb27SDimitry Andric   using namespace TemplateInstArgsHelpers;
47406c3fb27SDimitry Andric   const Decl *CurDecl = ND;
4751db9f3b2SDimitry Andric 
4761db9f3b2SDimitry Andric   if (!CurDecl)
4771db9f3b2SDimitry Andric     CurDecl = Decl::castFromDeclContext(DC);
4781db9f3b2SDimitry Andric 
47906c3fb27SDimitry Andric   if (Innermost) {
4800fca6ea1SDimitry Andric     Result.addOuterTemplateArguments(const_cast<NamedDecl *>(ND), *Innermost,
4810fca6ea1SDimitry Andric                                      Final);
4821db9f3b2SDimitry Andric     // Populate placeholder template arguments for TemplateTemplateParmDecls.
4831db9f3b2SDimitry Andric     // This is essential for the case e.g.
4841db9f3b2SDimitry Andric     //
4851db9f3b2SDimitry Andric     // template <class> concept Concept = false;
4861db9f3b2SDimitry Andric     // template <template <Concept C> class T> void foo(T<int>)
4871db9f3b2SDimitry Andric     //
4881db9f3b2SDimitry Andric     // where parameter C has a depth of 1 but the substituting argument `int`
4891db9f3b2SDimitry Andric     // has a depth of 0.
4901db9f3b2SDimitry Andric     if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(CurDecl))
4911db9f3b2SDimitry Andric       HandleDefaultTempArgIntoTempTempParam(TTP, Result);
4921db9f3b2SDimitry Andric     CurDecl = Response::UseNextDecl(CurDecl).NextDecl;
49306c3fb27SDimitry Andric   }
494bdd1243dSDimitry Andric 
495bdd1243dSDimitry Andric   while (!CurDecl->isFileContextDecl()) {
496bdd1243dSDimitry Andric     Response R;
497bdd1243dSDimitry Andric     if (const auto *VarTemplSpec =
498bdd1243dSDimitry Andric             dyn_cast<VarTemplateSpecializationDecl>(CurDecl)) {
499bdd1243dSDimitry Andric       R = HandleVarTemplateSpec(VarTemplSpec, Result, SkipForSpecialization);
50006c3fb27SDimitry Andric     } else if (const auto *PartialClassTemplSpec =
50106c3fb27SDimitry Andric                    dyn_cast<ClassTemplatePartialSpecializationDecl>(CurDecl)) {
50206c3fb27SDimitry Andric       R = HandlePartialClassTemplateSpec(PartialClassTemplSpec, Result,
50306c3fb27SDimitry Andric                                          SkipForSpecialization);
504bdd1243dSDimitry Andric     } else if (const auto *ClassTemplSpec =
505bdd1243dSDimitry Andric                    dyn_cast<ClassTemplateSpecializationDecl>(CurDecl)) {
506bdd1243dSDimitry Andric       R = HandleClassTemplateSpec(ClassTemplSpec, Result,
507bdd1243dSDimitry Andric                                   SkipForSpecialization);
508bdd1243dSDimitry Andric     } else if (const auto *Function = dyn_cast<FunctionDecl>(CurDecl)) {
5090fca6ea1SDimitry Andric       R = HandleFunction(*this, Function, Result, Pattern, RelativeToPrimary,
510bdd1243dSDimitry Andric                          ForConstraintInstantiation);
511bdd1243dSDimitry Andric     } else if (const auto *Rec = dyn_cast<CXXRecordDecl>(CurDecl)) {
5120fca6ea1SDimitry Andric       R = HandleRecordDecl(*this, Rec, Result, Context,
5130fca6ea1SDimitry Andric                            ForConstraintInstantiation);
514bdd1243dSDimitry Andric     } else if (const auto *CSD =
515bdd1243dSDimitry Andric                    dyn_cast<ImplicitConceptSpecializationDecl>(CurDecl)) {
516bdd1243dSDimitry Andric       R = HandleImplicitConceptSpecializationDecl(CSD, Result);
51706c3fb27SDimitry Andric     } else if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(CurDecl)) {
51806c3fb27SDimitry Andric       R = HandleFunctionTemplateDecl(FTD, Result);
5195f757f3fSDimitry Andric     } else if (const auto *CTD = dyn_cast<ClassTemplateDecl>(CurDecl)) {
5205f757f3fSDimitry Andric       R = Response::ChangeDecl(CTD->getLexicalDeclContext());
521bdd1243dSDimitry Andric     } else if (!isa<DeclContext>(CurDecl)) {
522bdd1243dSDimitry Andric       R = Response::DontClearRelativeToPrimaryNextDecl(CurDecl);
523bdd1243dSDimitry Andric       if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(CurDecl)) {
524bdd1243dSDimitry Andric         R = HandleDefaultTempArgIntoTempTempParam(TTP, Result);
525bdd1243dSDimitry Andric       }
526bdd1243dSDimitry Andric     } else {
527bdd1243dSDimitry Andric       R = HandleGenericDeclContext(CurDecl);
528bdd1243dSDimitry Andric     }
529bdd1243dSDimitry Andric 
530bdd1243dSDimitry Andric     if (R.IsDone)
531bdd1243dSDimitry Andric       return Result;
532bdd1243dSDimitry Andric     if (R.ClearRelativeToPrimary)
5330b57cec5SDimitry Andric       RelativeToPrimary = false;
534bdd1243dSDimitry Andric     assert(R.NextDecl);
535bdd1243dSDimitry Andric     CurDecl = R.NextDecl;
5360b57cec5SDimitry Andric   }
5370b57cec5SDimitry Andric 
5380b57cec5SDimitry Andric   return Result;
5390b57cec5SDimitry Andric }
5400b57cec5SDimitry Andric 
5410b57cec5SDimitry Andric bool Sema::CodeSynthesisContext::isInstantiationRecord() const {
5420b57cec5SDimitry Andric   switch (Kind) {
5430b57cec5SDimitry Andric   case TemplateInstantiation:
5440b57cec5SDimitry Andric   case ExceptionSpecInstantiation:
5450b57cec5SDimitry Andric   case DefaultTemplateArgumentInstantiation:
5460b57cec5SDimitry Andric   case DefaultFunctionArgumentInstantiation:
5470b57cec5SDimitry Andric   case ExplicitTemplateArgumentSubstitution:
5480b57cec5SDimitry Andric   case DeducedTemplateArgumentSubstitution:
5490b57cec5SDimitry Andric   case PriorTemplateArgumentSubstitution:
550a7dea167SDimitry Andric   case ConstraintsCheck:
55155e4f9d5SDimitry Andric   case NestedRequirementConstraintsCheck:
5520b57cec5SDimitry Andric     return true;
5530b57cec5SDimitry Andric 
55455e4f9d5SDimitry Andric   case RequirementInstantiation:
555bdd1243dSDimitry Andric   case RequirementParameterInstantiation:
5560b57cec5SDimitry Andric   case DefaultTemplateArgumentChecking:
5570b57cec5SDimitry Andric   case DeclaringSpecialMember:
558480093f4SDimitry Andric   case DeclaringImplicitEqualityComparison:
5590b57cec5SDimitry Andric   case DefiningSynthesizedFunction:
5600b57cec5SDimitry Andric   case ExceptionSpecEvaluation:
561a7dea167SDimitry Andric   case ConstraintSubstitution:
562480093f4SDimitry Andric   case ParameterMappingSubstitution:
563480093f4SDimitry Andric   case ConstraintNormalization:
564a7dea167SDimitry Andric   case RewritingOperatorAsSpaceship:
5655ffd83dbSDimitry Andric   case InitializingStructuredBinding:
5665ffd83dbSDimitry Andric   case MarkingClassDllexported:
56781ad6265SDimitry Andric   case BuildingBuiltinDumpStructCall:
56806c3fb27SDimitry Andric   case LambdaExpressionSubstitution:
56906c3fb27SDimitry Andric   case BuildingDeductionGuides:
5700fca6ea1SDimitry Andric   case TypeAliasTemplateInstantiation:
5710b57cec5SDimitry Andric     return false;
5720b57cec5SDimitry Andric 
5730b57cec5SDimitry Andric   // This function should never be called when Kind's value is Memoization.
5740b57cec5SDimitry Andric   case Memoization:
5750b57cec5SDimitry Andric     break;
5760b57cec5SDimitry Andric   }
5770b57cec5SDimitry Andric 
5780b57cec5SDimitry Andric   llvm_unreachable("Invalid SynthesisKind!");
5790b57cec5SDimitry Andric }
5800b57cec5SDimitry Andric 
5810b57cec5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
5820b57cec5SDimitry Andric     Sema &SemaRef, CodeSynthesisContext::SynthesisKind Kind,
5830b57cec5SDimitry Andric     SourceLocation PointOfInstantiation, SourceRange InstantiationRange,
5840b57cec5SDimitry Andric     Decl *Entity, NamedDecl *Template, ArrayRef<TemplateArgument> TemplateArgs,
5850b57cec5SDimitry Andric     sema::TemplateDeductionInfo *DeductionInfo)
5860b57cec5SDimitry Andric     : SemaRef(SemaRef) {
5870b57cec5SDimitry Andric   // Don't allow further instantiation if a fatal error and an uncompilable
5880b57cec5SDimitry Andric   // error have occurred. Any diagnostics we might have raised will not be
5890b57cec5SDimitry Andric   // visible, and we do not need to construct a correct AST.
5900b57cec5SDimitry Andric   if (SemaRef.Diags.hasFatalErrorOccurred() &&
591e8d8bef9SDimitry Andric       SemaRef.hasUncompilableErrorOccurred()) {
5920b57cec5SDimitry Andric     Invalid = true;
5930b57cec5SDimitry Andric     return;
5940b57cec5SDimitry Andric   }
5950b57cec5SDimitry Andric   Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
5960b57cec5SDimitry Andric   if (!Invalid) {
5970b57cec5SDimitry Andric     CodeSynthesisContext Inst;
5980b57cec5SDimitry Andric     Inst.Kind = Kind;
5990b57cec5SDimitry Andric     Inst.PointOfInstantiation = PointOfInstantiation;
6000b57cec5SDimitry Andric     Inst.Entity = Entity;
6010b57cec5SDimitry Andric     Inst.Template = Template;
6020b57cec5SDimitry Andric     Inst.TemplateArgs = TemplateArgs.data();
6030b57cec5SDimitry Andric     Inst.NumTemplateArgs = TemplateArgs.size();
6040b57cec5SDimitry Andric     Inst.DeductionInfo = DeductionInfo;
6050b57cec5SDimitry Andric     Inst.InstantiationRange = InstantiationRange;
6060b57cec5SDimitry Andric     SemaRef.pushCodeSynthesisContext(Inst);
6070b57cec5SDimitry Andric 
60855e4f9d5SDimitry Andric     AlreadyInstantiating = !Inst.Entity ? false :
6090b57cec5SDimitry Andric         !SemaRef.InstantiatingSpecializations
610e8d8bef9SDimitry Andric              .insert({Inst.Entity->getCanonicalDecl(), Inst.Kind})
6110b57cec5SDimitry Andric              .second;
6120b57cec5SDimitry Andric     atTemplateBegin(SemaRef.TemplateInstCallbacks, SemaRef, Inst);
6130b57cec5SDimitry Andric   }
6140b57cec5SDimitry Andric }
6150b57cec5SDimitry Andric 
6160b57cec5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
6170b57cec5SDimitry Andric     Sema &SemaRef, SourceLocation PointOfInstantiation, Decl *Entity,
6180b57cec5SDimitry Andric     SourceRange InstantiationRange)
6190b57cec5SDimitry Andric     : InstantiatingTemplate(SemaRef,
6200b57cec5SDimitry Andric                             CodeSynthesisContext::TemplateInstantiation,
6210b57cec5SDimitry Andric                             PointOfInstantiation, InstantiationRange, Entity) {}
6220b57cec5SDimitry Andric 
6230b57cec5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
6240b57cec5SDimitry Andric     Sema &SemaRef, SourceLocation PointOfInstantiation, FunctionDecl *Entity,
6250b57cec5SDimitry Andric     ExceptionSpecification, SourceRange InstantiationRange)
6260b57cec5SDimitry Andric     : InstantiatingTemplate(
6270b57cec5SDimitry Andric           SemaRef, CodeSynthesisContext::ExceptionSpecInstantiation,
6280b57cec5SDimitry Andric           PointOfInstantiation, InstantiationRange, Entity) {}
6290b57cec5SDimitry Andric 
6300b57cec5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
6310b57cec5SDimitry Andric     Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateParameter Param,
6320b57cec5SDimitry Andric     TemplateDecl *Template, ArrayRef<TemplateArgument> TemplateArgs,
6330b57cec5SDimitry Andric     SourceRange InstantiationRange)
6340b57cec5SDimitry Andric     : InstantiatingTemplate(
6350b57cec5SDimitry Andric           SemaRef,
6360b57cec5SDimitry Andric           CodeSynthesisContext::DefaultTemplateArgumentInstantiation,
6370b57cec5SDimitry Andric           PointOfInstantiation, InstantiationRange, getAsNamedDecl(Param),
6380b57cec5SDimitry Andric           Template, TemplateArgs) {}
6390b57cec5SDimitry Andric 
6400b57cec5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
6410b57cec5SDimitry Andric     Sema &SemaRef, SourceLocation PointOfInstantiation,
6420b57cec5SDimitry Andric     FunctionTemplateDecl *FunctionTemplate,
6430b57cec5SDimitry Andric     ArrayRef<TemplateArgument> TemplateArgs,
6440b57cec5SDimitry Andric     CodeSynthesisContext::SynthesisKind Kind,
6450b57cec5SDimitry Andric     sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
6460b57cec5SDimitry Andric     : InstantiatingTemplate(SemaRef, Kind, PointOfInstantiation,
6470b57cec5SDimitry Andric                             InstantiationRange, FunctionTemplate, nullptr,
6480b57cec5SDimitry Andric                             TemplateArgs, &DeductionInfo) {
6490fca6ea1SDimitry Andric   assert(Kind == CodeSynthesisContext::ExplicitTemplateArgumentSubstitution ||
6500fca6ea1SDimitry Andric          Kind == CodeSynthesisContext::DeducedTemplateArgumentSubstitution ||
6510fca6ea1SDimitry Andric          Kind == CodeSynthesisContext::BuildingDeductionGuides);
6520b57cec5SDimitry Andric }
6530b57cec5SDimitry Andric 
6540b57cec5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
6550b57cec5SDimitry Andric     Sema &SemaRef, SourceLocation PointOfInstantiation,
6560b57cec5SDimitry Andric     TemplateDecl *Template,
6570b57cec5SDimitry Andric     ArrayRef<TemplateArgument> TemplateArgs,
6580b57cec5SDimitry Andric     sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
6590b57cec5SDimitry Andric     : InstantiatingTemplate(
6600b57cec5SDimitry Andric           SemaRef,
6610b57cec5SDimitry Andric           CodeSynthesisContext::DeducedTemplateArgumentSubstitution,
6620b57cec5SDimitry Andric           PointOfInstantiation, InstantiationRange, Template, nullptr,
6630b57cec5SDimitry Andric           TemplateArgs, &DeductionInfo) {}
6640b57cec5SDimitry Andric 
6650b57cec5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
6660b57cec5SDimitry Andric     Sema &SemaRef, SourceLocation PointOfInstantiation,
6670b57cec5SDimitry Andric     ClassTemplatePartialSpecializationDecl *PartialSpec,
6680b57cec5SDimitry Andric     ArrayRef<TemplateArgument> TemplateArgs,
6690b57cec5SDimitry Andric     sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
6700b57cec5SDimitry Andric     : InstantiatingTemplate(
6710b57cec5SDimitry Andric           SemaRef,
6720b57cec5SDimitry Andric           CodeSynthesisContext::DeducedTemplateArgumentSubstitution,
6730b57cec5SDimitry Andric           PointOfInstantiation, InstantiationRange, PartialSpec, nullptr,
6740b57cec5SDimitry Andric           TemplateArgs, &DeductionInfo) {}
6750b57cec5SDimitry Andric 
6760b57cec5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
6770b57cec5SDimitry Andric     Sema &SemaRef, SourceLocation PointOfInstantiation,
6780b57cec5SDimitry Andric     VarTemplatePartialSpecializationDecl *PartialSpec,
6790b57cec5SDimitry Andric     ArrayRef<TemplateArgument> TemplateArgs,
6800b57cec5SDimitry Andric     sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
6810b57cec5SDimitry Andric     : InstantiatingTemplate(
6820b57cec5SDimitry Andric           SemaRef,
6830b57cec5SDimitry Andric           CodeSynthesisContext::DeducedTemplateArgumentSubstitution,
6840b57cec5SDimitry Andric           PointOfInstantiation, InstantiationRange, PartialSpec, nullptr,
6850b57cec5SDimitry Andric           TemplateArgs, &DeductionInfo) {}
6860b57cec5SDimitry Andric 
6870b57cec5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
6880b57cec5SDimitry Andric     Sema &SemaRef, SourceLocation PointOfInstantiation, ParmVarDecl *Param,
6890b57cec5SDimitry Andric     ArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange)
6900b57cec5SDimitry Andric     : InstantiatingTemplate(
6910b57cec5SDimitry Andric           SemaRef,
6920b57cec5SDimitry Andric           CodeSynthesisContext::DefaultFunctionArgumentInstantiation,
6930b57cec5SDimitry Andric           PointOfInstantiation, InstantiationRange, Param, nullptr,
6940b57cec5SDimitry Andric           TemplateArgs) {}
6950b57cec5SDimitry Andric 
6960b57cec5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
6970b57cec5SDimitry Andric     Sema &SemaRef, SourceLocation PointOfInstantiation, NamedDecl *Template,
6980b57cec5SDimitry Andric     NonTypeTemplateParmDecl *Param, ArrayRef<TemplateArgument> TemplateArgs,
6990b57cec5SDimitry Andric     SourceRange InstantiationRange)
7000b57cec5SDimitry Andric     : InstantiatingTemplate(
7010b57cec5SDimitry Andric           SemaRef,
7020b57cec5SDimitry Andric           CodeSynthesisContext::PriorTemplateArgumentSubstitution,
7030b57cec5SDimitry Andric           PointOfInstantiation, InstantiationRange, Param, Template,
7040b57cec5SDimitry Andric           TemplateArgs) {}
7050b57cec5SDimitry Andric 
7060b57cec5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
7070b57cec5SDimitry Andric     Sema &SemaRef, SourceLocation PointOfInstantiation, NamedDecl *Template,
7080b57cec5SDimitry Andric     TemplateTemplateParmDecl *Param, ArrayRef<TemplateArgument> TemplateArgs,
7090b57cec5SDimitry Andric     SourceRange InstantiationRange)
7100b57cec5SDimitry Andric     : InstantiatingTemplate(
7110b57cec5SDimitry Andric           SemaRef,
7120b57cec5SDimitry Andric           CodeSynthesisContext::PriorTemplateArgumentSubstitution,
7130b57cec5SDimitry Andric           PointOfInstantiation, InstantiationRange, Param, Template,
7140b57cec5SDimitry Andric           TemplateArgs) {}
7150b57cec5SDimitry Andric 
7160b57cec5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
7170fca6ea1SDimitry Andric     Sema &SemaRef, SourceLocation PointOfInstantiation,
7180fca6ea1SDimitry Andric     TypeAliasTemplateDecl *Entity, ArrayRef<TemplateArgument> TemplateArgs,
7190fca6ea1SDimitry Andric     SourceRange InstantiationRange)
7200fca6ea1SDimitry Andric     : InstantiatingTemplate(
7210fca6ea1SDimitry Andric           SemaRef, CodeSynthesisContext::TypeAliasTemplateInstantiation,
7220fca6ea1SDimitry Andric           PointOfInstantiation, InstantiationRange, /*Entity=*/Entity,
7230fca6ea1SDimitry Andric           /*Template=*/nullptr, TemplateArgs) {}
7240fca6ea1SDimitry Andric 
7250fca6ea1SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
7260b57cec5SDimitry Andric     Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateDecl *Template,
7270b57cec5SDimitry Andric     NamedDecl *Param, ArrayRef<TemplateArgument> TemplateArgs,
7280b57cec5SDimitry Andric     SourceRange InstantiationRange)
7290b57cec5SDimitry Andric     : InstantiatingTemplate(
7300b57cec5SDimitry Andric           SemaRef, CodeSynthesisContext::DefaultTemplateArgumentChecking,
7310b57cec5SDimitry Andric           PointOfInstantiation, InstantiationRange, Param, Template,
7320b57cec5SDimitry Andric           TemplateArgs) {}
7330b57cec5SDimitry Andric 
734a7dea167SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
735a7dea167SDimitry Andric     Sema &SemaRef, SourceLocation PointOfInstantiation,
73655e4f9d5SDimitry Andric     concepts::Requirement *Req, sema::TemplateDeductionInfo &DeductionInfo,
73755e4f9d5SDimitry Andric     SourceRange InstantiationRange)
73855e4f9d5SDimitry Andric     : InstantiatingTemplate(
73955e4f9d5SDimitry Andric           SemaRef, CodeSynthesisContext::RequirementInstantiation,
74055e4f9d5SDimitry Andric           PointOfInstantiation, InstantiationRange, /*Entity=*/nullptr,
741bdd1243dSDimitry Andric           /*Template=*/nullptr, /*TemplateArgs=*/std::nullopt, &DeductionInfo) {
742bdd1243dSDimitry Andric }
74355e4f9d5SDimitry Andric 
74455e4f9d5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
74555e4f9d5SDimitry Andric     Sema &SemaRef, SourceLocation PointOfInstantiation,
74655e4f9d5SDimitry Andric     concepts::NestedRequirement *Req, ConstraintsCheck,
74755e4f9d5SDimitry Andric     SourceRange InstantiationRange)
74855e4f9d5SDimitry Andric     : InstantiatingTemplate(
74955e4f9d5SDimitry Andric           SemaRef, CodeSynthesisContext::NestedRequirementConstraintsCheck,
75055e4f9d5SDimitry Andric           PointOfInstantiation, InstantiationRange, /*Entity=*/nullptr,
751bdd1243dSDimitry Andric           /*Template=*/nullptr, /*TemplateArgs=*/std::nullopt) {}
75255e4f9d5SDimitry Andric 
753bdd1243dSDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
754bdd1243dSDimitry Andric     Sema &SemaRef, SourceLocation PointOfInstantiation, const RequiresExpr *RE,
755bdd1243dSDimitry Andric     sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
756bdd1243dSDimitry Andric     : InstantiatingTemplate(
757bdd1243dSDimitry Andric           SemaRef, CodeSynthesisContext::RequirementParameterInstantiation,
758bdd1243dSDimitry Andric           PointOfInstantiation, InstantiationRange, /*Entity=*/nullptr,
759bdd1243dSDimitry Andric           /*Template=*/nullptr, /*TemplateArgs=*/std::nullopt, &DeductionInfo) {
760bdd1243dSDimitry Andric }
76155e4f9d5SDimitry Andric 
76255e4f9d5SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
76355e4f9d5SDimitry Andric     Sema &SemaRef, SourceLocation PointOfInstantiation,
764480093f4SDimitry Andric     ConstraintsCheck, NamedDecl *Template,
765a7dea167SDimitry Andric     ArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange)
766a7dea167SDimitry Andric     : InstantiatingTemplate(
767a7dea167SDimitry Andric           SemaRef, CodeSynthesisContext::ConstraintsCheck,
768a7dea167SDimitry Andric           PointOfInstantiation, InstantiationRange, Template, nullptr,
769a7dea167SDimitry Andric           TemplateArgs) {}
770a7dea167SDimitry Andric 
771a7dea167SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
772a7dea167SDimitry Andric     Sema &SemaRef, SourceLocation PointOfInstantiation,
773480093f4SDimitry Andric     ConstraintSubstitution, NamedDecl *Template,
774a7dea167SDimitry Andric     sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
775a7dea167SDimitry Andric     : InstantiatingTemplate(
776a7dea167SDimitry Andric           SemaRef, CodeSynthesisContext::ConstraintSubstitution,
777a7dea167SDimitry Andric           PointOfInstantiation, InstantiationRange, Template, nullptr,
778a7dea167SDimitry Andric           {}, &DeductionInfo) {}
779a7dea167SDimitry Andric 
780480093f4SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
781480093f4SDimitry Andric     Sema &SemaRef, SourceLocation PointOfInstantiation,
782480093f4SDimitry Andric     ConstraintNormalization, NamedDecl *Template,
783480093f4SDimitry Andric     SourceRange InstantiationRange)
784480093f4SDimitry Andric     : InstantiatingTemplate(
785480093f4SDimitry Andric           SemaRef, CodeSynthesisContext::ConstraintNormalization,
786480093f4SDimitry Andric           PointOfInstantiation, InstantiationRange, Template) {}
787480093f4SDimitry Andric 
788480093f4SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
789480093f4SDimitry Andric     Sema &SemaRef, SourceLocation PointOfInstantiation,
790480093f4SDimitry Andric     ParameterMappingSubstitution, NamedDecl *Template,
791480093f4SDimitry Andric     SourceRange InstantiationRange)
792480093f4SDimitry Andric     : InstantiatingTemplate(
793480093f4SDimitry Andric           SemaRef, CodeSynthesisContext::ParameterMappingSubstitution,
794480093f4SDimitry Andric           PointOfInstantiation, InstantiationRange, Template) {}
795480093f4SDimitry Andric 
79606c3fb27SDimitry Andric Sema::InstantiatingTemplate::InstantiatingTemplate(
79706c3fb27SDimitry Andric     Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateDecl *Entity,
79806c3fb27SDimitry Andric     BuildingDeductionGuidesTag, SourceRange InstantiationRange)
79906c3fb27SDimitry Andric     : InstantiatingTemplate(
80006c3fb27SDimitry Andric           SemaRef, CodeSynthesisContext::BuildingDeductionGuides,
80106c3fb27SDimitry Andric           PointOfInstantiation, InstantiationRange, Entity) {}
80206c3fb27SDimitry Andric 
803bdd1243dSDimitry Andric 
8040b57cec5SDimitry Andric void Sema::pushCodeSynthesisContext(CodeSynthesisContext Ctx) {
8050b57cec5SDimitry Andric   Ctx.SavedInNonInstantiationSFINAEContext = InNonInstantiationSFINAEContext;
8060b57cec5SDimitry Andric   InNonInstantiationSFINAEContext = false;
8070b57cec5SDimitry Andric 
8080b57cec5SDimitry Andric   CodeSynthesisContexts.push_back(Ctx);
8090b57cec5SDimitry Andric 
8100b57cec5SDimitry Andric   if (!Ctx.isInstantiationRecord())
8110b57cec5SDimitry Andric     ++NonInstantiationEntries;
812a7dea167SDimitry Andric 
813a7dea167SDimitry Andric   // Check to see if we're low on stack space. We can't do anything about this
814a7dea167SDimitry Andric   // from here, but we can at least warn the user.
815a7dea167SDimitry Andric   if (isStackNearlyExhausted())
816a7dea167SDimitry Andric     warnStackExhausted(Ctx.PointOfInstantiation);
8170b57cec5SDimitry Andric }
8180b57cec5SDimitry Andric 
8190b57cec5SDimitry Andric void Sema::popCodeSynthesisContext() {
8200b57cec5SDimitry Andric   auto &Active = CodeSynthesisContexts.back();
8210b57cec5SDimitry Andric   if (!Active.isInstantiationRecord()) {
8220b57cec5SDimitry Andric     assert(NonInstantiationEntries > 0);
8230b57cec5SDimitry Andric     --NonInstantiationEntries;
8240b57cec5SDimitry Andric   }
8250b57cec5SDimitry Andric 
8260b57cec5SDimitry Andric   InNonInstantiationSFINAEContext = Active.SavedInNonInstantiationSFINAEContext;
8270b57cec5SDimitry Andric 
8280b57cec5SDimitry Andric   // Name lookup no longer looks in this template's defining module.
8290b57cec5SDimitry Andric   assert(CodeSynthesisContexts.size() >=
8300b57cec5SDimitry Andric              CodeSynthesisContextLookupModules.size() &&
8310b57cec5SDimitry Andric          "forgot to remove a lookup module for a template instantiation");
8320b57cec5SDimitry Andric   if (CodeSynthesisContexts.size() ==
8330b57cec5SDimitry Andric       CodeSynthesisContextLookupModules.size()) {
8340b57cec5SDimitry Andric     if (Module *M = CodeSynthesisContextLookupModules.back())
8350b57cec5SDimitry Andric       LookupModulesCache.erase(M);
8360b57cec5SDimitry Andric     CodeSynthesisContextLookupModules.pop_back();
8370b57cec5SDimitry Andric   }
8380b57cec5SDimitry Andric 
8390b57cec5SDimitry Andric   // If we've left the code synthesis context for the current context stack,
8400b57cec5SDimitry Andric   // stop remembering that we've emitted that stack.
8410b57cec5SDimitry Andric   if (CodeSynthesisContexts.size() ==
8420b57cec5SDimitry Andric       LastEmittedCodeSynthesisContextDepth)
8430b57cec5SDimitry Andric     LastEmittedCodeSynthesisContextDepth = 0;
8440b57cec5SDimitry Andric 
8450b57cec5SDimitry Andric   CodeSynthesisContexts.pop_back();
8460b57cec5SDimitry Andric }
8470b57cec5SDimitry Andric 
8480b57cec5SDimitry Andric void Sema::InstantiatingTemplate::Clear() {
8490b57cec5SDimitry Andric   if (!Invalid) {
8500b57cec5SDimitry Andric     if (!AlreadyInstantiating) {
8510b57cec5SDimitry Andric       auto &Active = SemaRef.CodeSynthesisContexts.back();
85255e4f9d5SDimitry Andric       if (Active.Entity)
8530b57cec5SDimitry Andric         SemaRef.InstantiatingSpecializations.erase(
854e8d8bef9SDimitry Andric             {Active.Entity->getCanonicalDecl(), Active.Kind});
8550b57cec5SDimitry Andric     }
8560b57cec5SDimitry Andric 
8570b57cec5SDimitry Andric     atTemplateEnd(SemaRef.TemplateInstCallbacks, SemaRef,
8580b57cec5SDimitry Andric                   SemaRef.CodeSynthesisContexts.back());
8590b57cec5SDimitry Andric 
8600b57cec5SDimitry Andric     SemaRef.popCodeSynthesisContext();
8610b57cec5SDimitry Andric     Invalid = true;
8620b57cec5SDimitry Andric   }
8630b57cec5SDimitry Andric }
8640b57cec5SDimitry Andric 
86581ad6265SDimitry Andric static std::string convertCallArgsToString(Sema &S,
86681ad6265SDimitry Andric                                            llvm::ArrayRef<const Expr *> Args) {
86781ad6265SDimitry Andric   std::string Result;
86881ad6265SDimitry Andric   llvm::raw_string_ostream OS(Result);
86981ad6265SDimitry Andric   llvm::ListSeparator Comma;
87081ad6265SDimitry Andric   for (const Expr *Arg : Args) {
87181ad6265SDimitry Andric     OS << Comma;
87281ad6265SDimitry Andric     Arg->IgnoreParens()->printPretty(OS, nullptr,
87381ad6265SDimitry Andric                                      S.Context.getPrintingPolicy());
87481ad6265SDimitry Andric   }
87581ad6265SDimitry Andric   return Result;
87681ad6265SDimitry Andric }
87781ad6265SDimitry Andric 
8780b57cec5SDimitry Andric bool Sema::InstantiatingTemplate::CheckInstantiationDepth(
8790b57cec5SDimitry Andric                                         SourceLocation PointOfInstantiation,
8800b57cec5SDimitry Andric                                            SourceRange InstantiationRange) {
8810b57cec5SDimitry Andric   assert(SemaRef.NonInstantiationEntries <=
8820b57cec5SDimitry Andric          SemaRef.CodeSynthesisContexts.size());
8830b57cec5SDimitry Andric   if ((SemaRef.CodeSynthesisContexts.size() -
8840b57cec5SDimitry Andric           SemaRef.NonInstantiationEntries)
8850b57cec5SDimitry Andric         <= SemaRef.getLangOpts().InstantiationDepth)
8860b57cec5SDimitry Andric     return false;
8870b57cec5SDimitry Andric 
8880b57cec5SDimitry Andric   SemaRef.Diag(PointOfInstantiation,
8890b57cec5SDimitry Andric                diag::err_template_recursion_depth_exceeded)
8900b57cec5SDimitry Andric     << SemaRef.getLangOpts().InstantiationDepth
8910b57cec5SDimitry Andric     << InstantiationRange;
8920b57cec5SDimitry Andric   SemaRef.Diag(PointOfInstantiation, diag::note_template_recursion_depth)
8930b57cec5SDimitry Andric     << SemaRef.getLangOpts().InstantiationDepth;
8940b57cec5SDimitry Andric   return true;
8950b57cec5SDimitry Andric }
8960b57cec5SDimitry Andric 
8970b57cec5SDimitry Andric void Sema::PrintInstantiationStack() {
8980b57cec5SDimitry Andric   // Determine which template instantiations to skip, if any.
8990b57cec5SDimitry Andric   unsigned SkipStart = CodeSynthesisContexts.size(), SkipEnd = SkipStart;
9000b57cec5SDimitry Andric   unsigned Limit = Diags.getTemplateBacktraceLimit();
9010b57cec5SDimitry Andric   if (Limit && Limit < CodeSynthesisContexts.size()) {
9020b57cec5SDimitry Andric     SkipStart = Limit / 2 + Limit % 2;
9030b57cec5SDimitry Andric     SkipEnd = CodeSynthesisContexts.size() - Limit / 2;
9040b57cec5SDimitry Andric   }
9050b57cec5SDimitry Andric 
9060b57cec5SDimitry Andric   // FIXME: In all of these cases, we need to show the template arguments
9070b57cec5SDimitry Andric   unsigned InstantiationIdx = 0;
9080b57cec5SDimitry Andric   for (SmallVectorImpl<CodeSynthesisContext>::reverse_iterator
9090b57cec5SDimitry Andric          Active = CodeSynthesisContexts.rbegin(),
9100b57cec5SDimitry Andric          ActiveEnd = CodeSynthesisContexts.rend();
9110b57cec5SDimitry Andric        Active != ActiveEnd;
9120b57cec5SDimitry Andric        ++Active, ++InstantiationIdx) {
9130b57cec5SDimitry Andric     // Skip this instantiation?
9140b57cec5SDimitry Andric     if (InstantiationIdx >= SkipStart && InstantiationIdx < SkipEnd) {
9150b57cec5SDimitry Andric       if (InstantiationIdx == SkipStart) {
9160b57cec5SDimitry Andric         // Note that we're skipping instantiations.
9170b57cec5SDimitry Andric         Diags.Report(Active->PointOfInstantiation,
9180b57cec5SDimitry Andric                      diag::note_instantiation_contexts_suppressed)
9190b57cec5SDimitry Andric           << unsigned(CodeSynthesisContexts.size() - Limit);
9200b57cec5SDimitry Andric       }
9210b57cec5SDimitry Andric       continue;
9220b57cec5SDimitry Andric     }
9230b57cec5SDimitry Andric 
9240b57cec5SDimitry Andric     switch (Active->Kind) {
9250b57cec5SDimitry Andric     case CodeSynthesisContext::TemplateInstantiation: {
9260b57cec5SDimitry Andric       Decl *D = Active->Entity;
9270b57cec5SDimitry Andric       if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) {
9280b57cec5SDimitry Andric         unsigned DiagID = diag::note_template_member_class_here;
9290b57cec5SDimitry Andric         if (isa<ClassTemplateSpecializationDecl>(Record))
9300b57cec5SDimitry Andric           DiagID = diag::note_template_class_instantiation_here;
9310b57cec5SDimitry Andric         Diags.Report(Active->PointOfInstantiation, DiagID)
9320b57cec5SDimitry Andric           << Record << Active->InstantiationRange;
9330b57cec5SDimitry Andric       } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
9340b57cec5SDimitry Andric         unsigned DiagID;
9350b57cec5SDimitry Andric         if (Function->getPrimaryTemplate())
9360b57cec5SDimitry Andric           DiagID = diag::note_function_template_spec_here;
9370b57cec5SDimitry Andric         else
9380b57cec5SDimitry Andric           DiagID = diag::note_template_member_function_here;
9390b57cec5SDimitry Andric         Diags.Report(Active->PointOfInstantiation, DiagID)
9400b57cec5SDimitry Andric           << Function
9410b57cec5SDimitry Andric           << Active->InstantiationRange;
9420b57cec5SDimitry Andric       } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
9430b57cec5SDimitry Andric         Diags.Report(Active->PointOfInstantiation,
9440b57cec5SDimitry Andric                      VD->isStaticDataMember()?
9450b57cec5SDimitry Andric                        diag::note_template_static_data_member_def_here
9460b57cec5SDimitry Andric                      : diag::note_template_variable_def_here)
9470b57cec5SDimitry Andric           << VD
9480b57cec5SDimitry Andric           << Active->InstantiationRange;
9490b57cec5SDimitry Andric       } else if (EnumDecl *ED = dyn_cast<EnumDecl>(D)) {
9500b57cec5SDimitry Andric         Diags.Report(Active->PointOfInstantiation,
9510b57cec5SDimitry Andric                      diag::note_template_enum_def_here)
9520b57cec5SDimitry Andric           << ED
9530b57cec5SDimitry Andric           << Active->InstantiationRange;
9540b57cec5SDimitry Andric       } else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
9550b57cec5SDimitry Andric         Diags.Report(Active->PointOfInstantiation,
9560b57cec5SDimitry Andric                      diag::note_template_nsdmi_here)
9570b57cec5SDimitry Andric             << FD << Active->InstantiationRange;
958bcd401b5SDimitry Andric       } else if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(D)) {
959bcd401b5SDimitry Andric         Diags.Report(Active->PointOfInstantiation,
960bcd401b5SDimitry Andric                      diag::note_template_class_instantiation_here)
961bcd401b5SDimitry Andric             << CTD << Active->InstantiationRange;
9620b57cec5SDimitry Andric       }
9630b57cec5SDimitry Andric       break;
9640b57cec5SDimitry Andric     }
9650b57cec5SDimitry Andric 
9660b57cec5SDimitry Andric     case CodeSynthesisContext::DefaultTemplateArgumentInstantiation: {
9670b57cec5SDimitry Andric       TemplateDecl *Template = cast<TemplateDecl>(Active->Template);
968e8d8bef9SDimitry Andric       SmallString<128> TemplateArgsStr;
9690b57cec5SDimitry Andric       llvm::raw_svector_ostream OS(TemplateArgsStr);
970bdd1243dSDimitry Andric       Template->printName(OS, getPrintingPolicy());
9710b57cec5SDimitry Andric       printTemplateArgumentList(OS, Active->template_arguments(),
9720b57cec5SDimitry Andric                                 getPrintingPolicy());
9730b57cec5SDimitry Andric       Diags.Report(Active->PointOfInstantiation,
9740b57cec5SDimitry Andric                    diag::note_default_arg_instantiation_here)
9750b57cec5SDimitry Andric         << OS.str()
9760b57cec5SDimitry Andric         << Active->InstantiationRange;
9770b57cec5SDimitry Andric       break;
9780b57cec5SDimitry Andric     }
9790b57cec5SDimitry Andric 
9800b57cec5SDimitry Andric     case CodeSynthesisContext::ExplicitTemplateArgumentSubstitution: {
9810b57cec5SDimitry Andric       FunctionTemplateDecl *FnTmpl = cast<FunctionTemplateDecl>(Active->Entity);
9820b57cec5SDimitry Andric       Diags.Report(Active->PointOfInstantiation,
9830b57cec5SDimitry Andric                    diag::note_explicit_template_arg_substitution_here)
9840b57cec5SDimitry Andric         << FnTmpl
9850b57cec5SDimitry Andric         << getTemplateArgumentBindingsText(FnTmpl->getTemplateParameters(),
9860b57cec5SDimitry Andric                                            Active->TemplateArgs,
9870b57cec5SDimitry Andric                                            Active->NumTemplateArgs)
9880b57cec5SDimitry Andric         << Active->InstantiationRange;
9890b57cec5SDimitry Andric       break;
9900b57cec5SDimitry Andric     }
9910b57cec5SDimitry Andric 
9920b57cec5SDimitry Andric     case CodeSynthesisContext::DeducedTemplateArgumentSubstitution: {
9930b57cec5SDimitry Andric       if (FunctionTemplateDecl *FnTmpl =
9940b57cec5SDimitry Andric               dyn_cast<FunctionTemplateDecl>(Active->Entity)) {
9950b57cec5SDimitry Andric         Diags.Report(Active->PointOfInstantiation,
9960b57cec5SDimitry Andric                      diag::note_function_template_deduction_instantiation_here)
9970b57cec5SDimitry Andric           << FnTmpl
9980b57cec5SDimitry Andric           << getTemplateArgumentBindingsText(FnTmpl->getTemplateParameters(),
9990b57cec5SDimitry Andric                                              Active->TemplateArgs,
10000b57cec5SDimitry Andric                                              Active->NumTemplateArgs)
10010b57cec5SDimitry Andric           << Active->InstantiationRange;
10020b57cec5SDimitry Andric       } else {
10030b57cec5SDimitry Andric         bool IsVar = isa<VarTemplateDecl>(Active->Entity) ||
10040b57cec5SDimitry Andric                      isa<VarTemplateSpecializationDecl>(Active->Entity);
10050b57cec5SDimitry Andric         bool IsTemplate = false;
10060b57cec5SDimitry Andric         TemplateParameterList *Params;
10070b57cec5SDimitry Andric         if (auto *D = dyn_cast<TemplateDecl>(Active->Entity)) {
10080b57cec5SDimitry Andric           IsTemplate = true;
10090b57cec5SDimitry Andric           Params = D->getTemplateParameters();
10100b57cec5SDimitry Andric         } else if (auto *D = dyn_cast<ClassTemplatePartialSpecializationDecl>(
10110b57cec5SDimitry Andric                        Active->Entity)) {
10120b57cec5SDimitry Andric           Params = D->getTemplateParameters();
10130b57cec5SDimitry Andric         } else if (auto *D = dyn_cast<VarTemplatePartialSpecializationDecl>(
10140b57cec5SDimitry Andric                        Active->Entity)) {
10150b57cec5SDimitry Andric           Params = D->getTemplateParameters();
10160b57cec5SDimitry Andric         } else {
10170b57cec5SDimitry Andric           llvm_unreachable("unexpected template kind");
10180b57cec5SDimitry Andric         }
10190b57cec5SDimitry Andric 
10200b57cec5SDimitry Andric         Diags.Report(Active->PointOfInstantiation,
10210b57cec5SDimitry Andric                      diag::note_deduced_template_arg_substitution_here)
10220b57cec5SDimitry Andric           << IsVar << IsTemplate << cast<NamedDecl>(Active->Entity)
10230b57cec5SDimitry Andric           << getTemplateArgumentBindingsText(Params, Active->TemplateArgs,
10240b57cec5SDimitry Andric                                              Active->NumTemplateArgs)
10250b57cec5SDimitry Andric           << Active->InstantiationRange;
10260b57cec5SDimitry Andric       }
10270b57cec5SDimitry Andric       break;
10280b57cec5SDimitry Andric     }
10290b57cec5SDimitry Andric 
10300b57cec5SDimitry Andric     case CodeSynthesisContext::DefaultFunctionArgumentInstantiation: {
10310b57cec5SDimitry Andric       ParmVarDecl *Param = cast<ParmVarDecl>(Active->Entity);
10320b57cec5SDimitry Andric       FunctionDecl *FD = cast<FunctionDecl>(Param->getDeclContext());
10330b57cec5SDimitry Andric 
1034e8d8bef9SDimitry Andric       SmallString<128> TemplateArgsStr;
10350b57cec5SDimitry Andric       llvm::raw_svector_ostream OS(TemplateArgsStr);
1036bdd1243dSDimitry Andric       FD->printName(OS, getPrintingPolicy());
10370b57cec5SDimitry Andric       printTemplateArgumentList(OS, Active->template_arguments(),
10380b57cec5SDimitry Andric                                 getPrintingPolicy());
10390b57cec5SDimitry Andric       Diags.Report(Active->PointOfInstantiation,
10400b57cec5SDimitry Andric                    diag::note_default_function_arg_instantiation_here)
10410b57cec5SDimitry Andric         << OS.str()
10420b57cec5SDimitry Andric         << Active->InstantiationRange;
10430b57cec5SDimitry Andric       break;
10440b57cec5SDimitry Andric     }
10450b57cec5SDimitry Andric 
10460b57cec5SDimitry Andric     case CodeSynthesisContext::PriorTemplateArgumentSubstitution: {
10470b57cec5SDimitry Andric       NamedDecl *Parm = cast<NamedDecl>(Active->Entity);
10480b57cec5SDimitry Andric       std::string Name;
10490b57cec5SDimitry Andric       if (!Parm->getName().empty())
10500b57cec5SDimitry Andric         Name = std::string(" '") + Parm->getName().str() + "'";
10510b57cec5SDimitry Andric 
10520b57cec5SDimitry Andric       TemplateParameterList *TemplateParams = nullptr;
10530b57cec5SDimitry Andric       if (TemplateDecl *Template = dyn_cast<TemplateDecl>(Active->Template))
10540b57cec5SDimitry Andric         TemplateParams = Template->getTemplateParameters();
10550b57cec5SDimitry Andric       else
10560b57cec5SDimitry Andric         TemplateParams =
10570b57cec5SDimitry Andric           cast<ClassTemplatePartialSpecializationDecl>(Active->Template)
10580b57cec5SDimitry Andric                                                       ->getTemplateParameters();
10590b57cec5SDimitry Andric       Diags.Report(Active->PointOfInstantiation,
10600b57cec5SDimitry Andric                    diag::note_prior_template_arg_substitution)
10610b57cec5SDimitry Andric         << isa<TemplateTemplateParmDecl>(Parm)
10620b57cec5SDimitry Andric         << Name
10630b57cec5SDimitry Andric         << getTemplateArgumentBindingsText(TemplateParams,
10640b57cec5SDimitry Andric                                            Active->TemplateArgs,
10650b57cec5SDimitry Andric                                            Active->NumTemplateArgs)
10660b57cec5SDimitry Andric         << Active->InstantiationRange;
10670b57cec5SDimitry Andric       break;
10680b57cec5SDimitry Andric     }
10690b57cec5SDimitry Andric 
10700b57cec5SDimitry Andric     case CodeSynthesisContext::DefaultTemplateArgumentChecking: {
10710b57cec5SDimitry Andric       TemplateParameterList *TemplateParams = nullptr;
10720b57cec5SDimitry Andric       if (TemplateDecl *Template = dyn_cast<TemplateDecl>(Active->Template))
10730b57cec5SDimitry Andric         TemplateParams = Template->getTemplateParameters();
10740b57cec5SDimitry Andric       else
10750b57cec5SDimitry Andric         TemplateParams =
10760b57cec5SDimitry Andric           cast<ClassTemplatePartialSpecializationDecl>(Active->Template)
10770b57cec5SDimitry Andric                                                       ->getTemplateParameters();
10780b57cec5SDimitry Andric 
10790b57cec5SDimitry Andric       Diags.Report(Active->PointOfInstantiation,
10800b57cec5SDimitry Andric                    diag::note_template_default_arg_checking)
10810b57cec5SDimitry Andric         << getTemplateArgumentBindingsText(TemplateParams,
10820b57cec5SDimitry Andric                                            Active->TemplateArgs,
10830b57cec5SDimitry Andric                                            Active->NumTemplateArgs)
10840b57cec5SDimitry Andric         << Active->InstantiationRange;
10850b57cec5SDimitry Andric       break;
10860b57cec5SDimitry Andric     }
10870b57cec5SDimitry Andric 
10880b57cec5SDimitry Andric     case CodeSynthesisContext::ExceptionSpecEvaluation:
10890b57cec5SDimitry Andric       Diags.Report(Active->PointOfInstantiation,
10900b57cec5SDimitry Andric                    diag::note_evaluating_exception_spec_here)
10910b57cec5SDimitry Andric           << cast<FunctionDecl>(Active->Entity);
10920b57cec5SDimitry Andric       break;
10930b57cec5SDimitry Andric 
10940b57cec5SDimitry Andric     case CodeSynthesisContext::ExceptionSpecInstantiation:
10950b57cec5SDimitry Andric       Diags.Report(Active->PointOfInstantiation,
10960b57cec5SDimitry Andric                    diag::note_template_exception_spec_instantiation_here)
10970b57cec5SDimitry Andric         << cast<FunctionDecl>(Active->Entity)
10980b57cec5SDimitry Andric         << Active->InstantiationRange;
10990b57cec5SDimitry Andric       break;
11000b57cec5SDimitry Andric 
110155e4f9d5SDimitry Andric     case CodeSynthesisContext::RequirementInstantiation:
110255e4f9d5SDimitry Andric       Diags.Report(Active->PointOfInstantiation,
110355e4f9d5SDimitry Andric                    diag::note_template_requirement_instantiation_here)
110455e4f9d5SDimitry Andric         << Active->InstantiationRange;
110555e4f9d5SDimitry Andric       break;
1106bdd1243dSDimitry Andric     case CodeSynthesisContext::RequirementParameterInstantiation:
1107bdd1243dSDimitry Andric       Diags.Report(Active->PointOfInstantiation,
1108bdd1243dSDimitry Andric                    diag::note_template_requirement_params_instantiation_here)
1109bdd1243dSDimitry Andric           << Active->InstantiationRange;
1110bdd1243dSDimitry Andric       break;
111155e4f9d5SDimitry Andric 
111255e4f9d5SDimitry Andric     case CodeSynthesisContext::NestedRequirementConstraintsCheck:
111355e4f9d5SDimitry Andric       Diags.Report(Active->PointOfInstantiation,
111455e4f9d5SDimitry Andric                    diag::note_nested_requirement_here)
111555e4f9d5SDimitry Andric         << Active->InstantiationRange;
111655e4f9d5SDimitry Andric       break;
111755e4f9d5SDimitry Andric 
11180b57cec5SDimitry Andric     case CodeSynthesisContext::DeclaringSpecialMember:
11190b57cec5SDimitry Andric       Diags.Report(Active->PointOfInstantiation,
11200b57cec5SDimitry Andric                    diag::note_in_declaration_of_implicit_special_member)
11210fca6ea1SDimitry Andric           << cast<CXXRecordDecl>(Active->Entity)
11220fca6ea1SDimitry Andric           << llvm::to_underlying(Active->SpecialMember);
11230b57cec5SDimitry Andric       break;
11240b57cec5SDimitry Andric 
1125480093f4SDimitry Andric     case CodeSynthesisContext::DeclaringImplicitEqualityComparison:
1126480093f4SDimitry Andric       Diags.Report(Active->Entity->getLocation(),
1127480093f4SDimitry Andric                    diag::note_in_declaration_of_implicit_equality_comparison);
1128480093f4SDimitry Andric       break;
1129480093f4SDimitry Andric 
11300b57cec5SDimitry Andric     case CodeSynthesisContext::DefiningSynthesizedFunction: {
1131480093f4SDimitry Andric       // FIXME: For synthesized functions that are not defaulted,
1132480093f4SDimitry Andric       // produce a note.
1133480093f4SDimitry Andric       auto *FD = dyn_cast<FunctionDecl>(Active->Entity);
1134480093f4SDimitry Andric       DefaultedFunctionKind DFK =
1135480093f4SDimitry Andric           FD ? getDefaultedFunctionKind(FD) : DefaultedFunctionKind();
1136480093f4SDimitry Andric       if (DFK.isSpecialMember()) {
1137480093f4SDimitry Andric         auto *MD = cast<CXXMethodDecl>(FD);
11380b57cec5SDimitry Andric         Diags.Report(Active->PointOfInstantiation,
11390b57cec5SDimitry Andric                      diag::note_member_synthesized_at)
11400fca6ea1SDimitry Andric             << MD->isExplicitlyDefaulted()
11410fca6ea1SDimitry Andric             << llvm::to_underlying(DFK.asSpecialMember())
1142480093f4SDimitry Andric             << Context.getTagDeclType(MD->getParent());
1143480093f4SDimitry Andric       } else if (DFK.isComparison()) {
114406c3fb27SDimitry Andric         QualType RecordType = FD->getParamDecl(0)
114506c3fb27SDimitry Andric                                   ->getType()
114606c3fb27SDimitry Andric                                   .getNonReferenceType()
114706c3fb27SDimitry Andric                                   .getUnqualifiedType();
1148480093f4SDimitry Andric         Diags.Report(Active->PointOfInstantiation,
1149480093f4SDimitry Andric                      diag::note_comparison_synthesized_at)
115006c3fb27SDimitry Andric             << (int)DFK.asComparison() << RecordType;
11510b57cec5SDimitry Andric       }
11520b57cec5SDimitry Andric       break;
11530b57cec5SDimitry Andric     }
11540b57cec5SDimitry Andric 
1155a7dea167SDimitry Andric     case CodeSynthesisContext::RewritingOperatorAsSpaceship:
1156a7dea167SDimitry Andric       Diags.Report(Active->Entity->getLocation(),
1157a7dea167SDimitry Andric                    diag::note_rewriting_operator_as_spaceship);
1158a7dea167SDimitry Andric       break;
1159a7dea167SDimitry Andric 
11605ffd83dbSDimitry Andric     case CodeSynthesisContext::InitializingStructuredBinding:
11615ffd83dbSDimitry Andric       Diags.Report(Active->PointOfInstantiation,
11625ffd83dbSDimitry Andric                    diag::note_in_binding_decl_init)
11635ffd83dbSDimitry Andric           << cast<BindingDecl>(Active->Entity);
11645ffd83dbSDimitry Andric       break;
11655ffd83dbSDimitry Andric 
11665ffd83dbSDimitry Andric     case CodeSynthesisContext::MarkingClassDllexported:
11675ffd83dbSDimitry Andric       Diags.Report(Active->PointOfInstantiation,
11685ffd83dbSDimitry Andric                    diag::note_due_to_dllexported_class)
11695ffd83dbSDimitry Andric           << cast<CXXRecordDecl>(Active->Entity) << !getLangOpts().CPlusPlus11;
11705ffd83dbSDimitry Andric       break;
11715ffd83dbSDimitry Andric 
117281ad6265SDimitry Andric     case CodeSynthesisContext::BuildingBuiltinDumpStructCall:
117381ad6265SDimitry Andric       Diags.Report(Active->PointOfInstantiation,
117481ad6265SDimitry Andric                    diag::note_building_builtin_dump_struct_call)
117581ad6265SDimitry Andric           << convertCallArgsToString(
1176bdd1243dSDimitry Andric                  *this, llvm::ArrayRef(Active->CallArgs, Active->NumCallArgs));
117781ad6265SDimitry Andric       break;
117881ad6265SDimitry Andric 
11790b57cec5SDimitry Andric     case CodeSynthesisContext::Memoization:
11800b57cec5SDimitry Andric       break;
1181a7dea167SDimitry Andric 
118206c3fb27SDimitry Andric     case CodeSynthesisContext::LambdaExpressionSubstitution:
118306c3fb27SDimitry Andric       Diags.Report(Active->PointOfInstantiation,
118406c3fb27SDimitry Andric                    diag::note_lambda_substitution_here);
118506c3fb27SDimitry Andric       break;
1186480093f4SDimitry Andric     case CodeSynthesisContext::ConstraintsCheck: {
1187480093f4SDimitry Andric       unsigned DiagID = 0;
118813138422SDimitry Andric       if (!Active->Entity) {
118913138422SDimitry Andric         Diags.Report(Active->PointOfInstantiation,
119013138422SDimitry Andric                      diag::note_nested_requirement_here)
119113138422SDimitry Andric           << Active->InstantiationRange;
119213138422SDimitry Andric         break;
119313138422SDimitry Andric       }
1194480093f4SDimitry Andric       if (isa<ConceptDecl>(Active->Entity))
1195480093f4SDimitry Andric         DiagID = diag::note_concept_specialization_here;
1196480093f4SDimitry Andric       else if (isa<TemplateDecl>(Active->Entity))
1197480093f4SDimitry Andric         DiagID = diag::note_checking_constraints_for_template_id_here;
1198480093f4SDimitry Andric       else if (isa<VarTemplatePartialSpecializationDecl>(Active->Entity))
1199480093f4SDimitry Andric         DiagID = diag::note_checking_constraints_for_var_spec_id_here;
120013138422SDimitry Andric       else if (isa<ClassTemplatePartialSpecializationDecl>(Active->Entity))
1201480093f4SDimitry Andric         DiagID = diag::note_checking_constraints_for_class_spec_id_here;
120213138422SDimitry Andric       else {
120313138422SDimitry Andric         assert(isa<FunctionDecl>(Active->Entity));
120413138422SDimitry Andric         DiagID = diag::note_checking_constraints_for_function_here;
1205480093f4SDimitry Andric       }
1206e8d8bef9SDimitry Andric       SmallString<128> TemplateArgsStr;
1207a7dea167SDimitry Andric       llvm::raw_svector_ostream OS(TemplateArgsStr);
1208bdd1243dSDimitry Andric       cast<NamedDecl>(Active->Entity)->printName(OS, getPrintingPolicy());
1209fe6060f1SDimitry Andric       if (!isa<FunctionDecl>(Active->Entity)) {
1210a7dea167SDimitry Andric         printTemplateArgumentList(OS, Active->template_arguments(),
1211a7dea167SDimitry Andric                                   getPrintingPolicy());
1212fe6060f1SDimitry Andric       }
1213480093f4SDimitry Andric       Diags.Report(Active->PointOfInstantiation, DiagID) << OS.str()
1214a7dea167SDimitry Andric         << Active->InstantiationRange;
1215a7dea167SDimitry Andric       break;
1216a7dea167SDimitry Andric     }
1217a7dea167SDimitry Andric     case CodeSynthesisContext::ConstraintSubstitution:
1218a7dea167SDimitry Andric       Diags.Report(Active->PointOfInstantiation,
1219a7dea167SDimitry Andric                    diag::note_constraint_substitution_here)
1220a7dea167SDimitry Andric           << Active->InstantiationRange;
1221a7dea167SDimitry Andric       break;
1222480093f4SDimitry Andric     case CodeSynthesisContext::ConstraintNormalization:
1223480093f4SDimitry Andric       Diags.Report(Active->PointOfInstantiation,
1224480093f4SDimitry Andric                    diag::note_constraint_normalization_here)
1225480093f4SDimitry Andric           << cast<NamedDecl>(Active->Entity)->getName()
1226480093f4SDimitry Andric           << Active->InstantiationRange;
1227480093f4SDimitry Andric       break;
1228480093f4SDimitry Andric     case CodeSynthesisContext::ParameterMappingSubstitution:
1229480093f4SDimitry Andric       Diags.Report(Active->PointOfInstantiation,
1230480093f4SDimitry Andric                    diag::note_parameter_mapping_substitution_here)
1231480093f4SDimitry Andric           << Active->InstantiationRange;
1232480093f4SDimitry Andric       break;
123306c3fb27SDimitry Andric     case CodeSynthesisContext::BuildingDeductionGuides:
12345f757f3fSDimitry Andric       Diags.Report(Active->PointOfInstantiation,
12355f757f3fSDimitry Andric                    diag::note_building_deduction_guide_here);
12365f757f3fSDimitry Andric       break;
12370fca6ea1SDimitry Andric     case CodeSynthesisContext::TypeAliasTemplateInstantiation:
12380fca6ea1SDimitry Andric       Diags.Report(Active->PointOfInstantiation,
12390fca6ea1SDimitry Andric                    diag::note_template_type_alias_instantiation_here)
12400fca6ea1SDimitry Andric           << cast<TypeAliasTemplateDecl>(Active->Entity)
12410fca6ea1SDimitry Andric           << Active->InstantiationRange;
12420fca6ea1SDimitry Andric       break;
12430b57cec5SDimitry Andric     }
12440b57cec5SDimitry Andric   }
12450b57cec5SDimitry Andric }
12460b57cec5SDimitry Andric 
1247bdd1243dSDimitry Andric std::optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const {
12480b57cec5SDimitry Andric   if (InNonInstantiationSFINAEContext)
1249bdd1243dSDimitry Andric     return std::optional<TemplateDeductionInfo *>(nullptr);
12500b57cec5SDimitry Andric 
12510b57cec5SDimitry Andric   for (SmallVectorImpl<CodeSynthesisContext>::const_reverse_iterator
12520b57cec5SDimitry Andric          Active = CodeSynthesisContexts.rbegin(),
12530b57cec5SDimitry Andric          ActiveEnd = CodeSynthesisContexts.rend();
12540b57cec5SDimitry Andric        Active != ActiveEnd;
12550b57cec5SDimitry Andric        ++Active)
12560b57cec5SDimitry Andric   {
12570b57cec5SDimitry Andric     switch (Active->Kind) {
12580fca6ea1SDimitry Andric     case CodeSynthesisContext::TypeAliasTemplateInstantiation:
12590b57cec5SDimitry Andric       // An instantiation of an alias template may or may not be a SFINAE
12600b57cec5SDimitry Andric       // context, depending on what else is on the stack.
12610b57cec5SDimitry Andric       if (isa<TypeAliasTemplateDecl>(Active->Entity))
12620b57cec5SDimitry Andric         break;
1263bdd1243dSDimitry Andric       [[fallthrough]];
12640fca6ea1SDimitry Andric     case CodeSynthesisContext::TemplateInstantiation:
12650b57cec5SDimitry Andric     case CodeSynthesisContext::DefaultFunctionArgumentInstantiation:
12660b57cec5SDimitry Andric     case CodeSynthesisContext::ExceptionSpecInstantiation:
1267a7dea167SDimitry Andric     case CodeSynthesisContext::ConstraintsCheck:
1268480093f4SDimitry Andric     case CodeSynthesisContext::ParameterMappingSubstitution:
1269480093f4SDimitry Andric     case CodeSynthesisContext::ConstraintNormalization:
127055e4f9d5SDimitry Andric     case CodeSynthesisContext::NestedRequirementConstraintsCheck:
12710b57cec5SDimitry Andric       // This is a template instantiation, so there is no SFINAE.
1272bdd1243dSDimitry Andric       return std::nullopt;
127306c3fb27SDimitry Andric     case CodeSynthesisContext::LambdaExpressionSubstitution:
127406c3fb27SDimitry Andric       // [temp.deduct]p9
127506c3fb27SDimitry Andric       // A lambda-expression appearing in a function type or a template
127606c3fb27SDimitry Andric       // parameter is not considered part of the immediate context for the
127706c3fb27SDimitry Andric       // purposes of template argument deduction.
12785f757f3fSDimitry Andric       // CWG2672: A lambda-expression body is never in the immediate context.
12795f757f3fSDimitry Andric       return std::nullopt;
12800b57cec5SDimitry Andric 
12810b57cec5SDimitry Andric     case CodeSynthesisContext::DefaultTemplateArgumentInstantiation:
12820b57cec5SDimitry Andric     case CodeSynthesisContext::PriorTemplateArgumentSubstitution:
12830b57cec5SDimitry Andric     case CodeSynthesisContext::DefaultTemplateArgumentChecking:
1284e8d8bef9SDimitry Andric     case CodeSynthesisContext::RewritingOperatorAsSpaceship:
12850b57cec5SDimitry Andric       // A default template argument instantiation and substitution into
12860b57cec5SDimitry Andric       // template parameters with arguments for prior parameters may or may
12870b57cec5SDimitry Andric       // not be a SFINAE context; look further up the stack.
12880b57cec5SDimitry Andric       break;
12890b57cec5SDimitry Andric 
12900b57cec5SDimitry Andric     case CodeSynthesisContext::ExplicitTemplateArgumentSubstitution:
12910b57cec5SDimitry Andric     case CodeSynthesisContext::DeducedTemplateArgumentSubstitution:
129206c3fb27SDimitry Andric       // We're either substituting explicitly-specified template arguments,
129306c3fb27SDimitry Andric       // deduced template arguments. SFINAE applies unless we are in a lambda
12941db9f3b2SDimitry Andric       // body, see [temp.deduct]p9.
1295a7dea167SDimitry Andric     case CodeSynthesisContext::ConstraintSubstitution:
129655e4f9d5SDimitry Andric     case CodeSynthesisContext::RequirementInstantiation:
1297bdd1243dSDimitry Andric     case CodeSynthesisContext::RequirementParameterInstantiation:
129806c3fb27SDimitry Andric       // SFINAE always applies in a constraint expression or a requirement
129906c3fb27SDimitry Andric       // in a requires expression.
13000b57cec5SDimitry Andric       assert(Active->DeductionInfo && "Missing deduction info pointer");
13010b57cec5SDimitry Andric       return Active->DeductionInfo;
13020b57cec5SDimitry Andric 
13030b57cec5SDimitry Andric     case CodeSynthesisContext::DeclaringSpecialMember:
1304480093f4SDimitry Andric     case CodeSynthesisContext::DeclaringImplicitEqualityComparison:
13050b57cec5SDimitry Andric     case CodeSynthesisContext::DefiningSynthesizedFunction:
13065ffd83dbSDimitry Andric     case CodeSynthesisContext::InitializingStructuredBinding:
13075ffd83dbSDimitry Andric     case CodeSynthesisContext::MarkingClassDllexported:
130881ad6265SDimitry Andric     case CodeSynthesisContext::BuildingBuiltinDumpStructCall:
130906c3fb27SDimitry Andric     case CodeSynthesisContext::BuildingDeductionGuides:
13100b57cec5SDimitry Andric       // This happens in a context unrelated to template instantiation, so
13110b57cec5SDimitry Andric       // there is no SFINAE.
1312bdd1243dSDimitry Andric       return std::nullopt;
13130b57cec5SDimitry Andric 
13140b57cec5SDimitry Andric     case CodeSynthesisContext::ExceptionSpecEvaluation:
13150b57cec5SDimitry Andric       // FIXME: This should not be treated as a SFINAE context, because
13160b57cec5SDimitry Andric       // we will cache an incorrect exception specification. However, clang
13170b57cec5SDimitry Andric       // bootstrap relies this! See PR31692.
13180b57cec5SDimitry Andric       break;
13190b57cec5SDimitry Andric 
13200b57cec5SDimitry Andric     case CodeSynthesisContext::Memoization:
13210b57cec5SDimitry Andric       break;
13220b57cec5SDimitry Andric     }
13230b57cec5SDimitry Andric 
13240b57cec5SDimitry Andric     // The inner context was transparent for SFINAE. If it occurred within a
13250b57cec5SDimitry Andric     // non-instantiation SFINAE context, then SFINAE applies.
13260b57cec5SDimitry Andric     if (Active->SavedInNonInstantiationSFINAEContext)
1327bdd1243dSDimitry Andric       return std::optional<TemplateDeductionInfo *>(nullptr);
13280b57cec5SDimitry Andric   }
13290b57cec5SDimitry Andric 
1330bdd1243dSDimitry Andric   return std::nullopt;
13310b57cec5SDimitry Andric }
13320b57cec5SDimitry Andric 
13330b57cec5SDimitry Andric //===----------------------------------------------------------------------===/
13340b57cec5SDimitry Andric // Template Instantiation for Types
13350b57cec5SDimitry Andric //===----------------------------------------------------------------------===/
13360b57cec5SDimitry Andric namespace {
13370b57cec5SDimitry Andric   class TemplateInstantiator : public TreeTransform<TemplateInstantiator> {
13380b57cec5SDimitry Andric     const MultiLevelTemplateArgumentList &TemplateArgs;
13390b57cec5SDimitry Andric     SourceLocation Loc;
13400b57cec5SDimitry Andric     DeclarationName Entity;
13411db9f3b2SDimitry Andric     // Whether to evaluate the C++20 constraints or simply substitute into them.
1342bdd1243dSDimitry Andric     bool EvaluateConstraints = true;
13430b57cec5SDimitry Andric 
13440b57cec5SDimitry Andric   public:
13450b57cec5SDimitry Andric     typedef TreeTransform<TemplateInstantiator> inherited;
13460b57cec5SDimitry Andric 
13470b57cec5SDimitry Andric     TemplateInstantiator(Sema &SemaRef,
13480b57cec5SDimitry Andric                          const MultiLevelTemplateArgumentList &TemplateArgs,
1349bdd1243dSDimitry Andric                          SourceLocation Loc, DeclarationName Entity)
13500b57cec5SDimitry Andric         : inherited(SemaRef), TemplateArgs(TemplateArgs), Loc(Loc),
13510b57cec5SDimitry Andric           Entity(Entity) {}
13520b57cec5SDimitry Andric 
1353bdd1243dSDimitry Andric     void setEvaluateConstraints(bool B) {
1354bdd1243dSDimitry Andric       EvaluateConstraints = B;
1355bdd1243dSDimitry Andric     }
1356bdd1243dSDimitry Andric     bool getEvaluateConstraints() {
1357bdd1243dSDimitry Andric       return EvaluateConstraints;
1358bdd1243dSDimitry Andric     }
1359bdd1243dSDimitry Andric 
13600b57cec5SDimitry Andric     /// Determine whether the given type \p T has already been
13610b57cec5SDimitry Andric     /// transformed.
13620b57cec5SDimitry Andric     ///
13630b57cec5SDimitry Andric     /// For the purposes of template instantiation, a type has already been
13640b57cec5SDimitry Andric     /// transformed if it is NULL or if it is not dependent.
13650b57cec5SDimitry Andric     bool AlreadyTransformed(QualType T);
13660b57cec5SDimitry Andric 
13670b57cec5SDimitry Andric     /// Returns the location of the entity being instantiated, if known.
13680b57cec5SDimitry Andric     SourceLocation getBaseLocation() { return Loc; }
13690b57cec5SDimitry Andric 
13700b57cec5SDimitry Andric     /// Returns the name of the entity being instantiated, if any.
13710b57cec5SDimitry Andric     DeclarationName getBaseEntity() { return Entity; }
13720b57cec5SDimitry Andric 
13730b57cec5SDimitry Andric     /// Sets the "base" location and entity when that
13740b57cec5SDimitry Andric     /// information is known based on another transformation.
13750b57cec5SDimitry Andric     void setBase(SourceLocation Loc, DeclarationName Entity) {
13760b57cec5SDimitry Andric       this->Loc = Loc;
13770b57cec5SDimitry Andric       this->Entity = Entity;
13780b57cec5SDimitry Andric     }
13790b57cec5SDimitry Andric 
1380cd675bb6SDimitry Andric     unsigned TransformTemplateDepth(unsigned Depth) {
1381cd675bb6SDimitry Andric       return TemplateArgs.getNewDepth(Depth);
1382cd675bb6SDimitry Andric     }
1383cd675bb6SDimitry Andric 
1384bdd1243dSDimitry Andric     std::optional<unsigned> getPackIndex(TemplateArgument Pack) {
1385bdd1243dSDimitry Andric       int Index = getSema().ArgumentPackSubstitutionIndex;
1386bdd1243dSDimitry Andric       if (Index == -1)
1387bdd1243dSDimitry Andric         return std::nullopt;
1388bdd1243dSDimitry Andric       return Pack.pack_size() - 1 - Index;
1389bdd1243dSDimitry Andric     }
1390bdd1243dSDimitry Andric 
13910b57cec5SDimitry Andric     bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
13920b57cec5SDimitry Andric                                  SourceRange PatternRange,
13930b57cec5SDimitry Andric                                  ArrayRef<UnexpandedParameterPack> Unexpanded,
13940b57cec5SDimitry Andric                                  bool &ShouldExpand, bool &RetainExpansion,
1395bdd1243dSDimitry Andric                                  std::optional<unsigned> &NumExpansions) {
13960b57cec5SDimitry Andric       return getSema().CheckParameterPacksForExpansion(EllipsisLoc,
13970b57cec5SDimitry Andric                                                        PatternRange, Unexpanded,
13980b57cec5SDimitry Andric                                                        TemplateArgs,
13990b57cec5SDimitry Andric                                                        ShouldExpand,
14000b57cec5SDimitry Andric                                                        RetainExpansion,
14010b57cec5SDimitry Andric                                                        NumExpansions);
14020b57cec5SDimitry Andric     }
14030b57cec5SDimitry Andric 
14040b57cec5SDimitry Andric     void ExpandingFunctionParameterPack(ParmVarDecl *Pack) {
14050b57cec5SDimitry Andric       SemaRef.CurrentInstantiationScope->MakeInstantiatedLocalArgPack(Pack);
14060b57cec5SDimitry Andric     }
14070b57cec5SDimitry Andric 
14080b57cec5SDimitry Andric     TemplateArgument ForgetPartiallySubstitutedPack() {
14090b57cec5SDimitry Andric       TemplateArgument Result;
14100b57cec5SDimitry Andric       if (NamedDecl *PartialPack
14110b57cec5SDimitry Andric             = SemaRef.CurrentInstantiationScope->getPartiallySubstitutedPack()){
14120b57cec5SDimitry Andric         MultiLevelTemplateArgumentList &TemplateArgs
14130b57cec5SDimitry Andric           = const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs);
14140b57cec5SDimitry Andric         unsigned Depth, Index;
14150b57cec5SDimitry Andric         std::tie(Depth, Index) = getDepthAndIndex(PartialPack);
14160b57cec5SDimitry Andric         if (TemplateArgs.hasTemplateArgument(Depth, Index)) {
14170b57cec5SDimitry Andric           Result = TemplateArgs(Depth, Index);
14180b57cec5SDimitry Andric           TemplateArgs.setArgument(Depth, Index, TemplateArgument());
14190b57cec5SDimitry Andric         }
14200b57cec5SDimitry Andric       }
14210b57cec5SDimitry Andric 
14220b57cec5SDimitry Andric       return Result;
14230b57cec5SDimitry Andric     }
14240b57cec5SDimitry Andric 
14250b57cec5SDimitry Andric     void RememberPartiallySubstitutedPack(TemplateArgument Arg) {
14260b57cec5SDimitry Andric       if (Arg.isNull())
14270b57cec5SDimitry Andric         return;
14280b57cec5SDimitry Andric 
14290b57cec5SDimitry Andric       if (NamedDecl *PartialPack
14300b57cec5SDimitry Andric             = SemaRef.CurrentInstantiationScope->getPartiallySubstitutedPack()){
14310b57cec5SDimitry Andric         MultiLevelTemplateArgumentList &TemplateArgs
14320b57cec5SDimitry Andric         = const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs);
14330b57cec5SDimitry Andric         unsigned Depth, Index;
14340b57cec5SDimitry Andric         std::tie(Depth, Index) = getDepthAndIndex(PartialPack);
14350b57cec5SDimitry Andric         TemplateArgs.setArgument(Depth, Index, Arg);
14360b57cec5SDimitry Andric       }
14370b57cec5SDimitry Andric     }
14380b57cec5SDimitry Andric 
14390b57cec5SDimitry Andric     /// Transform the given declaration by instantiating a reference to
14400b57cec5SDimitry Andric     /// this declaration.
14410b57cec5SDimitry Andric     Decl *TransformDecl(SourceLocation Loc, Decl *D);
14420b57cec5SDimitry Andric 
14430b57cec5SDimitry Andric     void transformAttrs(Decl *Old, Decl *New) {
14440b57cec5SDimitry Andric       SemaRef.InstantiateAttrs(TemplateArgs, Old, New);
14450b57cec5SDimitry Andric     }
14460b57cec5SDimitry Andric 
14470b57cec5SDimitry Andric     void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> NewDecls) {
14480b57cec5SDimitry Andric       if (Old->isParameterPack()) {
14490b57cec5SDimitry Andric         SemaRef.CurrentInstantiationScope->MakeInstantiatedLocalArgPack(Old);
14500b57cec5SDimitry Andric         for (auto *New : NewDecls)
14510b57cec5SDimitry Andric           SemaRef.CurrentInstantiationScope->InstantiatedLocalPackArg(
14520b57cec5SDimitry Andric               Old, cast<VarDecl>(New));
14530b57cec5SDimitry Andric         return;
14540b57cec5SDimitry Andric       }
14550b57cec5SDimitry Andric 
14560b57cec5SDimitry Andric       assert(NewDecls.size() == 1 &&
14570b57cec5SDimitry Andric              "should only have multiple expansions for a pack");
14580b57cec5SDimitry Andric       Decl *New = NewDecls.front();
14590b57cec5SDimitry Andric 
14600b57cec5SDimitry Andric       // If we've instantiated the call operator of a lambda or the call
14610b57cec5SDimitry Andric       // operator template of a generic lambda, update the "instantiation of"
14620b57cec5SDimitry Andric       // information.
14630b57cec5SDimitry Andric       auto *NewMD = dyn_cast<CXXMethodDecl>(New);
14640b57cec5SDimitry Andric       if (NewMD && isLambdaCallOperator(NewMD)) {
14650b57cec5SDimitry Andric         auto *OldMD = dyn_cast<CXXMethodDecl>(Old);
14660b57cec5SDimitry Andric         if (auto *NewTD = NewMD->getDescribedFunctionTemplate())
14670b57cec5SDimitry Andric           NewTD->setInstantiatedFromMemberTemplate(
14680b57cec5SDimitry Andric               OldMD->getDescribedFunctionTemplate());
14690b57cec5SDimitry Andric         else
14700b57cec5SDimitry Andric           NewMD->setInstantiationOfMemberFunction(OldMD,
14710b57cec5SDimitry Andric                                                   TSK_ImplicitInstantiation);
14720b57cec5SDimitry Andric       }
14730b57cec5SDimitry Andric 
14740b57cec5SDimitry Andric       SemaRef.CurrentInstantiationScope->InstantiatedLocal(Old, New);
14750b57cec5SDimitry Andric 
14760b57cec5SDimitry Andric       // We recreated a local declaration, but not by instantiating it. There
14770b57cec5SDimitry Andric       // may be pending dependent diagnostics to produce.
147806c3fb27SDimitry Andric       if (auto *DC = dyn_cast<DeclContext>(Old);
147906c3fb27SDimitry Andric           DC && DC->isDependentContext() && DC->isFunctionOrMethod())
14800b57cec5SDimitry Andric         SemaRef.PerformDependentDiagnostics(DC, TemplateArgs);
14810b57cec5SDimitry Andric     }
14820b57cec5SDimitry Andric 
14830b57cec5SDimitry Andric     /// Transform the definition of the given declaration by
14840b57cec5SDimitry Andric     /// instantiating it.
14850b57cec5SDimitry Andric     Decl *TransformDefinition(SourceLocation Loc, Decl *D);
14860b57cec5SDimitry Andric 
14870b57cec5SDimitry Andric     /// Transform the first qualifier within a scope by instantiating the
14880b57cec5SDimitry Andric     /// declaration.
14890b57cec5SDimitry Andric     NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc);
14900b57cec5SDimitry Andric 
14915f757f3fSDimitry Andric     bool TransformExceptionSpec(SourceLocation Loc,
14925f757f3fSDimitry Andric                                 FunctionProtoType::ExceptionSpecInfo &ESI,
14935f757f3fSDimitry Andric                                 SmallVectorImpl<QualType> &Exceptions,
14945f757f3fSDimitry Andric                                 bool &Changed);
14955f757f3fSDimitry Andric 
14960b57cec5SDimitry Andric     /// Rebuild the exception declaration and register the declaration
14970b57cec5SDimitry Andric     /// as an instantiated local.
14980b57cec5SDimitry Andric     VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
14990b57cec5SDimitry Andric                                   TypeSourceInfo *Declarator,
15000b57cec5SDimitry Andric                                   SourceLocation StartLoc,
15010b57cec5SDimitry Andric                                   SourceLocation NameLoc,
15020b57cec5SDimitry Andric                                   IdentifierInfo *Name);
15030b57cec5SDimitry Andric 
15040b57cec5SDimitry Andric     /// Rebuild the Objective-C exception declaration and register the
15050b57cec5SDimitry Andric     /// declaration as an instantiated local.
15060b57cec5SDimitry Andric     VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
15070b57cec5SDimitry Andric                                       TypeSourceInfo *TSInfo, QualType T);
15080b57cec5SDimitry Andric 
15090b57cec5SDimitry Andric     /// Check for tag mismatches when instantiating an
15100b57cec5SDimitry Andric     /// elaborated type.
15110b57cec5SDimitry Andric     QualType RebuildElaboratedType(SourceLocation KeywordLoc,
15120b57cec5SDimitry Andric                                    ElaboratedTypeKeyword Keyword,
15130b57cec5SDimitry Andric                                    NestedNameSpecifierLoc QualifierLoc,
15140b57cec5SDimitry Andric                                    QualType T);
15150b57cec5SDimitry Andric 
15160b57cec5SDimitry Andric     TemplateName
15170b57cec5SDimitry Andric     TransformTemplateName(CXXScopeSpec &SS, TemplateName Name,
15180b57cec5SDimitry Andric                           SourceLocation NameLoc,
15190b57cec5SDimitry Andric                           QualType ObjectType = QualType(),
15200b57cec5SDimitry Andric                           NamedDecl *FirstQualifierInScope = nullptr,
15210b57cec5SDimitry Andric                           bool AllowInjectedClassName = false);
15220b57cec5SDimitry Andric 
15230fca6ea1SDimitry Andric     const CXXAssumeAttr *TransformCXXAssumeAttr(const CXXAssumeAttr *AA);
15240b57cec5SDimitry Andric     const LoopHintAttr *TransformLoopHintAttr(const LoopHintAttr *LH);
152506c3fb27SDimitry Andric     const NoInlineAttr *TransformStmtNoInlineAttr(const Stmt *OrigS,
152606c3fb27SDimitry Andric                                                   const Stmt *InstS,
152706c3fb27SDimitry Andric                                                   const NoInlineAttr *A);
152806c3fb27SDimitry Andric     const AlwaysInlineAttr *
152906c3fb27SDimitry Andric     TransformStmtAlwaysInlineAttr(const Stmt *OrigS, const Stmt *InstS,
153006c3fb27SDimitry Andric                                   const AlwaysInlineAttr *A);
15315f757f3fSDimitry Andric     const CodeAlignAttr *TransformCodeAlignAttr(const CodeAlignAttr *CA);
15320b57cec5SDimitry Andric     ExprResult TransformPredefinedExpr(PredefinedExpr *E);
15330b57cec5SDimitry Andric     ExprResult TransformDeclRefExpr(DeclRefExpr *E);
15340b57cec5SDimitry Andric     ExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E);
15350b57cec5SDimitry Andric 
15360b57cec5SDimitry Andric     ExprResult TransformTemplateParmRefExpr(DeclRefExpr *E,
15370b57cec5SDimitry Andric                                             NonTypeTemplateParmDecl *D);
15380b57cec5SDimitry Andric     ExprResult TransformSubstNonTypeTemplateParmPackExpr(
15390b57cec5SDimitry Andric                                            SubstNonTypeTemplateParmPackExpr *E);
154013138422SDimitry Andric     ExprResult TransformSubstNonTypeTemplateParmExpr(
154113138422SDimitry Andric                                            SubstNonTypeTemplateParmExpr *E);
15420b57cec5SDimitry Andric 
15430b57cec5SDimitry Andric     /// Rebuild a DeclRefExpr for a VarDecl reference.
15440b57cec5SDimitry Andric     ExprResult RebuildVarDeclRefExpr(VarDecl *PD, SourceLocation Loc);
15450b57cec5SDimitry Andric 
15460b57cec5SDimitry Andric     /// Transform a reference to a function or init-capture parameter pack.
15470b57cec5SDimitry Andric     ExprResult TransformFunctionParmPackRefExpr(DeclRefExpr *E, VarDecl *PD);
15480b57cec5SDimitry Andric 
15490b57cec5SDimitry Andric     /// Transform a FunctionParmPackExpr which was built when we couldn't
15500b57cec5SDimitry Andric     /// expand a function parameter pack reference which refers to an expanded
15510b57cec5SDimitry Andric     /// pack.
15520b57cec5SDimitry Andric     ExprResult TransformFunctionParmPackExpr(FunctionParmPackExpr *E);
15530b57cec5SDimitry Andric 
15540b57cec5SDimitry Andric     QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
15550b57cec5SDimitry Andric                                         FunctionProtoTypeLoc TL) {
15560b57cec5SDimitry Andric       // Call the base version; it will forward to our overridden version below.
15570b57cec5SDimitry Andric       return inherited::TransformFunctionProtoType(TLB, TL);
15580b57cec5SDimitry Andric     }
15590b57cec5SDimitry Andric 
15600fca6ea1SDimitry Andric     QualType TransformInjectedClassNameType(TypeLocBuilder &TLB,
15610fca6ea1SDimitry Andric                                             InjectedClassNameTypeLoc TL) {
15620fca6ea1SDimitry Andric       auto Type = inherited::TransformInjectedClassNameType(TLB, TL);
15630fca6ea1SDimitry Andric       // Special case for transforming a deduction guide, we return a
15640fca6ea1SDimitry Andric       // transformed TemplateSpecializationType.
15650fca6ea1SDimitry Andric       if (Type.isNull() &&
15660fca6ea1SDimitry Andric           SemaRef.CodeSynthesisContexts.back().Kind ==
15670fca6ea1SDimitry Andric               Sema::CodeSynthesisContext::BuildingDeductionGuides) {
15680fca6ea1SDimitry Andric         // Return a TemplateSpecializationType for transforming a deduction
15690fca6ea1SDimitry Andric         // guide.
15700fca6ea1SDimitry Andric         if (auto *ICT = TL.getType()->getAs<InjectedClassNameType>()) {
15710fca6ea1SDimitry Andric           auto Type =
15720fca6ea1SDimitry Andric               inherited::TransformType(ICT->getInjectedSpecializationType());
15730fca6ea1SDimitry Andric           TLB.pushTrivial(SemaRef.Context, Type, TL.getNameLoc());
15740fca6ea1SDimitry Andric           return Type;
15750fca6ea1SDimitry Andric         }
15760fca6ea1SDimitry Andric       }
15770fca6ea1SDimitry Andric       return Type;
15780fca6ea1SDimitry Andric     }
15790fca6ea1SDimitry Andric     // Override the default version to handle a rewrite-template-arg-pack case
15800fca6ea1SDimitry Andric     // for building a deduction guide.
15810fca6ea1SDimitry Andric     bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
15820fca6ea1SDimitry Andric                                    TemplateArgumentLoc &Output,
15830fca6ea1SDimitry Andric                                    bool Uneval = false) {
15840fca6ea1SDimitry Andric       const TemplateArgument &Arg = Input.getArgument();
15850fca6ea1SDimitry Andric       std::vector<TemplateArgument> TArgs;
15860fca6ea1SDimitry Andric       switch (Arg.getKind()) {
15870fca6ea1SDimitry Andric       case TemplateArgument::Pack:
15880fca6ea1SDimitry Andric         // Literally rewrite the template argument pack, instead of unpacking
15890fca6ea1SDimitry Andric         // it.
15900fca6ea1SDimitry Andric         for (auto &pack : Arg.getPackAsArray()) {
15910fca6ea1SDimitry Andric           TemplateArgumentLoc Input = SemaRef.getTrivialTemplateArgumentLoc(
15920fca6ea1SDimitry Andric               pack, QualType(), SourceLocation{});
15930fca6ea1SDimitry Andric           TemplateArgumentLoc Output;
15940fca6ea1SDimitry Andric           if (SemaRef.SubstTemplateArgument(Input, TemplateArgs, Output))
15950fca6ea1SDimitry Andric             return true; // fails
15960fca6ea1SDimitry Andric           TArgs.push_back(Output.getArgument());
15970fca6ea1SDimitry Andric         }
15980fca6ea1SDimitry Andric         Output = SemaRef.getTrivialTemplateArgumentLoc(
15990fca6ea1SDimitry Andric             TemplateArgument(llvm::ArrayRef(TArgs).copy(SemaRef.Context)),
16000fca6ea1SDimitry Andric             QualType(), SourceLocation{});
16010fca6ea1SDimitry Andric         return false;
16020fca6ea1SDimitry Andric       default:
16030fca6ea1SDimitry Andric         break;
16040fca6ea1SDimitry Andric       }
16050fca6ea1SDimitry Andric       return inherited::TransformTemplateArgument(Input, Output, Uneval);
16060fca6ea1SDimitry Andric     }
16070fca6ea1SDimitry Andric 
16080b57cec5SDimitry Andric     template<typename Fn>
16090b57cec5SDimitry Andric     QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
16100b57cec5SDimitry Andric                                         FunctionProtoTypeLoc TL,
16110b57cec5SDimitry Andric                                         CXXRecordDecl *ThisContext,
16120b57cec5SDimitry Andric                                         Qualifiers ThisTypeQuals,
16130b57cec5SDimitry Andric                                         Fn TransformExceptionSpec);
16140b57cec5SDimitry Andric 
1615bdd1243dSDimitry Andric     ParmVarDecl *
1616bdd1243dSDimitry Andric     TransformFunctionTypeParam(ParmVarDecl *OldParm, int indexAdjustment,
1617bdd1243dSDimitry Andric                                std::optional<unsigned> NumExpansions,
16180b57cec5SDimitry Andric                                bool ExpectParameterPack);
16190b57cec5SDimitry Andric 
1620bdd1243dSDimitry Andric     using inherited::TransformTemplateTypeParmType;
16210b57cec5SDimitry Andric     /// Transforms a template type parameter type by performing
16220b57cec5SDimitry Andric     /// substitution of the corresponding template type argument.
16230b57cec5SDimitry Andric     QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
1624bdd1243dSDimitry Andric                                            TemplateTypeParmTypeLoc TL,
1625bdd1243dSDimitry Andric                                            bool SuppressObjCLifetime);
1626bdd1243dSDimitry Andric 
1627bdd1243dSDimitry Andric     QualType BuildSubstTemplateTypeParmType(
1628bdd1243dSDimitry Andric         TypeLocBuilder &TLB, bool SuppressObjCLifetime, bool Final,
1629bdd1243dSDimitry Andric         Decl *AssociatedDecl, unsigned Index, std::optional<unsigned> PackIndex,
1630bdd1243dSDimitry Andric         TemplateArgument Arg, SourceLocation NameLoc);
16310b57cec5SDimitry Andric 
16320b57cec5SDimitry Andric     /// Transforms an already-substituted template type parameter pack
16330b57cec5SDimitry Andric     /// into either itself (if we aren't substituting into its pack expansion)
16340b57cec5SDimitry Andric     /// or the appropriate substituted argument.
1635bdd1243dSDimitry Andric     using inherited::TransformSubstTemplateTypeParmPackType;
1636bdd1243dSDimitry Andric     QualType
1637bdd1243dSDimitry Andric     TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB,
1638bdd1243dSDimitry Andric                                            SubstTemplateTypeParmPackTypeLoc TL,
1639bdd1243dSDimitry Andric                                            bool SuppressObjCLifetime);
16400b57cec5SDimitry Andric 
16410fca6ea1SDimitry Andric     CXXRecordDecl::LambdaDependencyKind
16420fca6ea1SDimitry Andric     ComputeLambdaDependency(LambdaScopeInfo *LSI) {
1643*6c4b055cSDimitry Andric       if (auto TypeAlias =
1644*6c4b055cSDimitry Andric               TemplateInstArgsHelpers::getEnclosingTypeAliasTemplateDecl(
1645*6c4b055cSDimitry Andric                   getSema());
1646*6c4b055cSDimitry Andric           TypeAlias && TemplateInstArgsHelpers::isLambdaEnclosedByTypeAliasDecl(
1647*6c4b055cSDimitry Andric                            LSI->CallOperator, TypeAlias.PrimaryTypeAliasDecl)) {
1648*6c4b055cSDimitry Andric         unsigned TypeAliasDeclDepth = TypeAlias.Template->getTemplateDepth();
16490fca6ea1SDimitry Andric         if (TypeAliasDeclDepth >= TemplateArgs.getNumSubstitutedLevels())
16500fca6ea1SDimitry Andric           return CXXRecordDecl::LambdaDependencyKind::LDK_AlwaysDependent;
1651*6c4b055cSDimitry Andric         for (const TemplateArgument &TA : TypeAlias.AssociatedTemplateArguments)
1652*6c4b055cSDimitry Andric           if (TA.isDependent())
1653*6c4b055cSDimitry Andric             return CXXRecordDecl::LambdaDependencyKind::LDK_AlwaysDependent;
16540fca6ea1SDimitry Andric       }
16550fca6ea1SDimitry Andric       return inherited::ComputeLambdaDependency(LSI);
16560fca6ea1SDimitry Andric     }
16570fca6ea1SDimitry Andric 
16580b57cec5SDimitry Andric     ExprResult TransformLambdaExpr(LambdaExpr *E) {
16590b57cec5SDimitry Andric       LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
1660bdd1243dSDimitry Andric       Sema::ConstraintEvalRAII<TemplateInstantiator> RAII(*this);
166106c3fb27SDimitry Andric 
1662bdd1243dSDimitry Andric       ExprResult Result = inherited::TransformLambdaExpr(E);
1663bdd1243dSDimitry Andric       if (Result.isInvalid())
1664bdd1243dSDimitry Andric         return Result;
1665bdd1243dSDimitry Andric 
1666bdd1243dSDimitry Andric       CXXMethodDecl *MD = Result.getAs<LambdaExpr>()->getCallOperator();
1667bdd1243dSDimitry Andric       for (ParmVarDecl *PVD : MD->parameters()) {
166806c3fb27SDimitry Andric         assert(PVD && "null in a parameter list");
1669bdd1243dSDimitry Andric         if (!PVD->hasDefaultArg())
1670bdd1243dSDimitry Andric           continue;
1671bdd1243dSDimitry Andric         Expr *UninstExpr = PVD->getUninstantiatedDefaultArg();
1672bdd1243dSDimitry Andric         // FIXME: Obtain the source location for the '=' token.
1673bdd1243dSDimitry Andric         SourceLocation EqualLoc = UninstExpr->getBeginLoc();
1674bdd1243dSDimitry Andric         if (SemaRef.SubstDefaultArgument(EqualLoc, PVD, TemplateArgs)) {
1675bdd1243dSDimitry Andric           // If substitution fails, the default argument is set to a
1676bdd1243dSDimitry Andric           // RecoveryExpr that wraps the uninstantiated default argument so
1677bdd1243dSDimitry Andric           // that downstream diagnostics are omitted.
1678bdd1243dSDimitry Andric           ExprResult ErrorResult = SemaRef.CreateRecoveryExpr(
1679bdd1243dSDimitry Andric               UninstExpr->getBeginLoc(), UninstExpr->getEndLoc(),
1680bdd1243dSDimitry Andric               { UninstExpr }, UninstExpr->getType());
1681bdd1243dSDimitry Andric           if (ErrorResult.isUsable())
1682bdd1243dSDimitry Andric             PVD->setDefaultArg(ErrorResult.get());
1683bdd1243dSDimitry Andric         }
1684bdd1243dSDimitry Andric       }
1685bdd1243dSDimitry Andric 
1686bdd1243dSDimitry Andric       return Result;
16870b57cec5SDimitry Andric     }
16880b57cec5SDimitry Andric 
16891db9f3b2SDimitry Andric     StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body) {
16901db9f3b2SDimitry Andric       // Currently, we instantiate the body when instantiating the lambda
16911db9f3b2SDimitry Andric       // expression. However, `EvaluateConstraints` is disabled during the
16921db9f3b2SDimitry Andric       // instantiation of the lambda expression, causing the instantiation
16931db9f3b2SDimitry Andric       // failure of the return type requirement in the body. If p0588r1 is fully
16941db9f3b2SDimitry Andric       // implemented, the body will be lazily instantiated, and this problem
16951db9f3b2SDimitry Andric       // will not occur. Here, `EvaluateConstraints` is temporarily set to
16961db9f3b2SDimitry Andric       // `true` to temporarily fix this issue.
16971db9f3b2SDimitry Andric       // FIXME: This temporary fix can be removed after fully implementing
16981db9f3b2SDimitry Andric       // p0588r1.
16991db9f3b2SDimitry Andric       bool Prev = EvaluateConstraints;
17001db9f3b2SDimitry Andric       EvaluateConstraints = true;
17011db9f3b2SDimitry Andric       StmtResult Stmt = inherited::TransformLambdaBody(E, Body);
17021db9f3b2SDimitry Andric       EvaluateConstraints = Prev;
17031db9f3b2SDimitry Andric       return Stmt;
17041db9f3b2SDimitry Andric     }
17051db9f3b2SDimitry Andric 
170655e4f9d5SDimitry Andric     ExprResult TransformRequiresExpr(RequiresExpr *E) {
170755e4f9d5SDimitry Andric       LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
1708bdd1243dSDimitry Andric       ExprResult TransReq = inherited::TransformRequiresExpr(E);
1709bdd1243dSDimitry Andric       if (TransReq.isInvalid())
1710bdd1243dSDimitry Andric         return TransReq;
1711bdd1243dSDimitry Andric       assert(TransReq.get() != E &&
1712bdd1243dSDimitry Andric              "Do not change value of isSatisfied for the existing expression. "
1713bdd1243dSDimitry Andric              "Create a new expression instead.");
1714bdd1243dSDimitry Andric       if (E->getBody()->isDependentContext()) {
1715bdd1243dSDimitry Andric         Sema::SFINAETrap Trap(SemaRef);
1716bdd1243dSDimitry Andric         // We recreate the RequiresExpr body, but not by instantiating it.
1717bdd1243dSDimitry Andric         // Produce pending diagnostics for dependent access check.
1718bdd1243dSDimitry Andric         SemaRef.PerformDependentDiagnostics(E->getBody(), TemplateArgs);
1719bdd1243dSDimitry Andric         // FIXME: Store SFINAE diagnostics in RequiresExpr for diagnosis.
1720bdd1243dSDimitry Andric         if (Trap.hasErrorOccurred())
1721bdd1243dSDimitry Andric           TransReq.getAs<RequiresExpr>()->setSatisfied(false);
1722bdd1243dSDimitry Andric       }
1723bdd1243dSDimitry Andric       return TransReq;
172455e4f9d5SDimitry Andric     }
172555e4f9d5SDimitry Andric 
172655e4f9d5SDimitry Andric     bool TransformRequiresExprRequirements(
172755e4f9d5SDimitry Andric         ArrayRef<concepts::Requirement *> Reqs,
172855e4f9d5SDimitry Andric         SmallVectorImpl<concepts::Requirement *> &Transformed) {
172955e4f9d5SDimitry Andric       bool SatisfactionDetermined = false;
173055e4f9d5SDimitry Andric       for (concepts::Requirement *Req : Reqs) {
173155e4f9d5SDimitry Andric         concepts::Requirement *TransReq = nullptr;
173255e4f9d5SDimitry Andric         if (!SatisfactionDetermined) {
173355e4f9d5SDimitry Andric           if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req))
173455e4f9d5SDimitry Andric             TransReq = TransformTypeRequirement(TypeReq);
173555e4f9d5SDimitry Andric           else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req))
173655e4f9d5SDimitry Andric             TransReq = TransformExprRequirement(ExprReq);
173755e4f9d5SDimitry Andric           else
173855e4f9d5SDimitry Andric             TransReq = TransformNestedRequirement(
173955e4f9d5SDimitry Andric                 cast<concepts::NestedRequirement>(Req));
174055e4f9d5SDimitry Andric           if (!TransReq)
174155e4f9d5SDimitry Andric             return true;
174255e4f9d5SDimitry Andric           if (!TransReq->isDependent() && !TransReq->isSatisfied())
174355e4f9d5SDimitry Andric             // [expr.prim.req]p6
174455e4f9d5SDimitry Andric             //   [...]  The substitution and semantic constraint checking
174555e4f9d5SDimitry Andric             //   proceeds in lexical order and stops when a condition that
174655e4f9d5SDimitry Andric             //   determines the result of the requires-expression is
174755e4f9d5SDimitry Andric             //   encountered. [..]
174855e4f9d5SDimitry Andric             SatisfactionDetermined = true;
174955e4f9d5SDimitry Andric         } else
175055e4f9d5SDimitry Andric           TransReq = Req;
175155e4f9d5SDimitry Andric         Transformed.push_back(TransReq);
175255e4f9d5SDimitry Andric       }
175355e4f9d5SDimitry Andric       return false;
175455e4f9d5SDimitry Andric     }
175555e4f9d5SDimitry Andric 
17560b57cec5SDimitry Andric     TemplateParameterList *TransformTemplateParameterList(
17570b57cec5SDimitry Andric                               TemplateParameterList *OrigTPL)  {
17580b57cec5SDimitry Andric       if (!OrigTPL || !OrigTPL->size()) return OrigTPL;
17590b57cec5SDimitry Andric 
17600b57cec5SDimitry Andric       DeclContext *Owner = OrigTPL->getParam(0)->getDeclContext();
17610b57cec5SDimitry Andric       TemplateDeclInstantiator  DeclInstantiator(getSema(),
17620b57cec5SDimitry Andric                         /* DeclContext *Owner */ Owner, TemplateArgs);
1763bdd1243dSDimitry Andric       DeclInstantiator.setEvaluateConstraints(EvaluateConstraints);
17640b57cec5SDimitry Andric       return DeclInstantiator.SubstTemplateParams(OrigTPL);
17650b57cec5SDimitry Andric     }
176655e4f9d5SDimitry Andric 
176755e4f9d5SDimitry Andric     concepts::TypeRequirement *
176855e4f9d5SDimitry Andric     TransformTypeRequirement(concepts::TypeRequirement *Req);
176955e4f9d5SDimitry Andric     concepts::ExprRequirement *
177055e4f9d5SDimitry Andric     TransformExprRequirement(concepts::ExprRequirement *Req);
177155e4f9d5SDimitry Andric     concepts::NestedRequirement *
177255e4f9d5SDimitry Andric     TransformNestedRequirement(concepts::NestedRequirement *Req);
1773bdd1243dSDimitry Andric     ExprResult TransformRequiresTypeParams(
1774bdd1243dSDimitry Andric         SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
1775bdd1243dSDimitry Andric         RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,
1776bdd1243dSDimitry Andric         SmallVectorImpl<QualType> &PTypes,
1777bdd1243dSDimitry Andric         SmallVectorImpl<ParmVarDecl *> &TransParams,
1778bdd1243dSDimitry Andric         Sema::ExtParameterInfoBuilder &PInfos);
177955e4f9d5SDimitry Andric 
17800b57cec5SDimitry Andric   private:
1781bdd1243dSDimitry Andric     ExprResult
1782bdd1243dSDimitry Andric     transformNonTypeTemplateParmRef(Decl *AssociatedDecl,
1783bdd1243dSDimitry Andric                                     const NonTypeTemplateParmDecl *parm,
1784bdd1243dSDimitry Andric                                     SourceLocation loc, TemplateArgument arg,
1785bdd1243dSDimitry Andric                                     std::optional<unsigned> PackIndex);
17860b57cec5SDimitry Andric   };
17870b57cec5SDimitry Andric }
17880b57cec5SDimitry Andric 
17890b57cec5SDimitry Andric bool TemplateInstantiator::AlreadyTransformed(QualType T) {
17900b57cec5SDimitry Andric   if (T.isNull())
17910b57cec5SDimitry Andric     return true;
17920b57cec5SDimitry Andric 
17930b57cec5SDimitry Andric   if (T->isInstantiationDependentType() || T->isVariablyModifiedType())
17940b57cec5SDimitry Andric     return false;
17950b57cec5SDimitry Andric 
17960b57cec5SDimitry Andric   getSema().MarkDeclarationsReferencedInType(Loc, T);
17970b57cec5SDimitry Andric   return true;
17980b57cec5SDimitry Andric }
17990b57cec5SDimitry Andric 
18000b57cec5SDimitry Andric static TemplateArgument
18010b57cec5SDimitry Andric getPackSubstitutedTemplateArgument(Sema &S, TemplateArgument Arg) {
18020b57cec5SDimitry Andric   assert(S.ArgumentPackSubstitutionIndex >= 0);
18030b57cec5SDimitry Andric   assert(S.ArgumentPackSubstitutionIndex < (int)Arg.pack_size());
18040b57cec5SDimitry Andric   Arg = Arg.pack_begin()[S.ArgumentPackSubstitutionIndex];
18050b57cec5SDimitry Andric   if (Arg.isPackExpansion())
18060b57cec5SDimitry Andric     Arg = Arg.getPackExpansionPattern();
18070b57cec5SDimitry Andric   return Arg;
18080b57cec5SDimitry Andric }
18090b57cec5SDimitry Andric 
18100b57cec5SDimitry Andric Decl *TemplateInstantiator::TransformDecl(SourceLocation Loc, Decl *D) {
18110b57cec5SDimitry Andric   if (!D)
18120b57cec5SDimitry Andric     return nullptr;
18130b57cec5SDimitry Andric 
18140b57cec5SDimitry Andric   if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(D)) {
18150b57cec5SDimitry Andric     if (TTP->getDepth() < TemplateArgs.getNumLevels()) {
18160b57cec5SDimitry Andric       // If the corresponding template argument is NULL or non-existent, it's
18170b57cec5SDimitry Andric       // because we are performing instantiation from explicitly-specified
18180b57cec5SDimitry Andric       // template arguments in a function template, but there were some
18190b57cec5SDimitry Andric       // arguments left unspecified.
18200b57cec5SDimitry Andric       if (!TemplateArgs.hasTemplateArgument(TTP->getDepth(),
18210b57cec5SDimitry Andric                                             TTP->getPosition()))
18220b57cec5SDimitry Andric         return D;
18230b57cec5SDimitry Andric 
18240b57cec5SDimitry Andric       TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getPosition());
18250b57cec5SDimitry Andric 
18260b57cec5SDimitry Andric       if (TTP->isParameterPack()) {
18270b57cec5SDimitry Andric         assert(Arg.getKind() == TemplateArgument::Pack &&
18280b57cec5SDimitry Andric                "Missing argument pack");
18290b57cec5SDimitry Andric         Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
18300b57cec5SDimitry Andric       }
18310b57cec5SDimitry Andric 
18320fca6ea1SDimitry Andric       TemplateName Template = Arg.getAsTemplate();
18330b57cec5SDimitry Andric       assert(!Template.isNull() && Template.getAsTemplateDecl() &&
18340b57cec5SDimitry Andric              "Wrong kind of template template argument");
18350b57cec5SDimitry Andric       return Template.getAsTemplateDecl();
18360b57cec5SDimitry Andric     }
18370b57cec5SDimitry Andric 
18380b57cec5SDimitry Andric     // Fall through to find the instantiated declaration for this template
18390b57cec5SDimitry Andric     // template parameter.
18400b57cec5SDimitry Andric   }
18410b57cec5SDimitry Andric 
18420b57cec5SDimitry Andric   return SemaRef.FindInstantiatedDecl(Loc, cast<NamedDecl>(D), TemplateArgs);
18430b57cec5SDimitry Andric }
18440b57cec5SDimitry Andric 
18450b57cec5SDimitry Andric Decl *TemplateInstantiator::TransformDefinition(SourceLocation Loc, Decl *D) {
18460b57cec5SDimitry Andric   Decl *Inst = getSema().SubstDecl(D, getSema().CurContext, TemplateArgs);
18470b57cec5SDimitry Andric   if (!Inst)
18480b57cec5SDimitry Andric     return nullptr;
18490b57cec5SDimitry Andric 
18500b57cec5SDimitry Andric   getSema().CurrentInstantiationScope->InstantiatedLocal(D, Inst);
18510b57cec5SDimitry Andric   return Inst;
18520b57cec5SDimitry Andric }
18530b57cec5SDimitry Andric 
18545f757f3fSDimitry Andric bool TemplateInstantiator::TransformExceptionSpec(
18555f757f3fSDimitry Andric     SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
18565f757f3fSDimitry Andric     SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
18575f757f3fSDimitry Andric   if (ESI.Type == EST_Uninstantiated) {
18581db9f3b2SDimitry Andric     ESI.instantiate();
18595f757f3fSDimitry Andric     Changed = true;
18605f757f3fSDimitry Andric   }
18615f757f3fSDimitry Andric   return inherited::TransformExceptionSpec(Loc, ESI, Exceptions, Changed);
18625f757f3fSDimitry Andric }
18635f757f3fSDimitry Andric 
18640b57cec5SDimitry Andric NamedDecl *
18650b57cec5SDimitry Andric TemplateInstantiator::TransformFirstQualifierInScope(NamedDecl *D,
18660b57cec5SDimitry Andric                                                      SourceLocation Loc) {
18670b57cec5SDimitry Andric   // If the first part of the nested-name-specifier was a template type
18680b57cec5SDimitry Andric   // parameter, instantiate that type parameter down to a tag type.
18690b57cec5SDimitry Andric   if (TemplateTypeParmDecl *TTPD = dyn_cast_or_null<TemplateTypeParmDecl>(D)) {
18700b57cec5SDimitry Andric     const TemplateTypeParmType *TTP
18710b57cec5SDimitry Andric       = cast<TemplateTypeParmType>(getSema().Context.getTypeDeclType(TTPD));
18720b57cec5SDimitry Andric 
18730b57cec5SDimitry Andric     if (TTP->getDepth() < TemplateArgs.getNumLevels()) {
18740b57cec5SDimitry Andric       // FIXME: This needs testing w/ member access expressions.
18750b57cec5SDimitry Andric       TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getIndex());
18760b57cec5SDimitry Andric 
18770b57cec5SDimitry Andric       if (TTP->isParameterPack()) {
18780b57cec5SDimitry Andric         assert(Arg.getKind() == TemplateArgument::Pack &&
18790b57cec5SDimitry Andric                "Missing argument pack");
18800b57cec5SDimitry Andric 
18810b57cec5SDimitry Andric         if (getSema().ArgumentPackSubstitutionIndex == -1)
18820b57cec5SDimitry Andric           return nullptr;
18830b57cec5SDimitry Andric 
18840b57cec5SDimitry Andric         Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
18850b57cec5SDimitry Andric       }
18860b57cec5SDimitry Andric 
18870b57cec5SDimitry Andric       QualType T = Arg.getAsType();
18880b57cec5SDimitry Andric       if (T.isNull())
18890b57cec5SDimitry Andric         return cast_or_null<NamedDecl>(TransformDecl(Loc, D));
18900b57cec5SDimitry Andric 
18910b57cec5SDimitry Andric       if (const TagType *Tag = T->getAs<TagType>())
18920b57cec5SDimitry Andric         return Tag->getDecl();
18930b57cec5SDimitry Andric 
18940b57cec5SDimitry Andric       // The resulting type is not a tag; complain.
18950b57cec5SDimitry Andric       getSema().Diag(Loc, diag::err_nested_name_spec_non_tag) << T;
18960b57cec5SDimitry Andric       return nullptr;
18970b57cec5SDimitry Andric     }
18980b57cec5SDimitry Andric   }
18990b57cec5SDimitry Andric 
19000b57cec5SDimitry Andric   return cast_or_null<NamedDecl>(TransformDecl(Loc, D));
19010b57cec5SDimitry Andric }
19020b57cec5SDimitry Andric 
19030b57cec5SDimitry Andric VarDecl *
19040b57cec5SDimitry Andric TemplateInstantiator::RebuildExceptionDecl(VarDecl *ExceptionDecl,
19050b57cec5SDimitry Andric                                            TypeSourceInfo *Declarator,
19060b57cec5SDimitry Andric                                            SourceLocation StartLoc,
19070b57cec5SDimitry Andric                                            SourceLocation NameLoc,
19080b57cec5SDimitry Andric                                            IdentifierInfo *Name) {
19090b57cec5SDimitry Andric   VarDecl *Var = inherited::RebuildExceptionDecl(ExceptionDecl, Declarator,
19100b57cec5SDimitry Andric                                                  StartLoc, NameLoc, Name);
19110b57cec5SDimitry Andric   if (Var)
19120b57cec5SDimitry Andric     getSema().CurrentInstantiationScope->InstantiatedLocal(ExceptionDecl, Var);
19130b57cec5SDimitry Andric   return Var;
19140b57cec5SDimitry Andric }
19150b57cec5SDimitry Andric 
19160b57cec5SDimitry Andric VarDecl *TemplateInstantiator::RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
19170b57cec5SDimitry Andric                                                         TypeSourceInfo *TSInfo,
19180b57cec5SDimitry Andric                                                         QualType T) {
19190b57cec5SDimitry Andric   VarDecl *Var = inherited::RebuildObjCExceptionDecl(ExceptionDecl, TSInfo, T);
19200b57cec5SDimitry Andric   if (Var)
19210b57cec5SDimitry Andric     getSema().CurrentInstantiationScope->InstantiatedLocal(ExceptionDecl, Var);
19220b57cec5SDimitry Andric   return Var;
19230b57cec5SDimitry Andric }
19240b57cec5SDimitry Andric 
19250b57cec5SDimitry Andric QualType
19260b57cec5SDimitry Andric TemplateInstantiator::RebuildElaboratedType(SourceLocation KeywordLoc,
19270b57cec5SDimitry Andric                                             ElaboratedTypeKeyword Keyword,
19280b57cec5SDimitry Andric                                             NestedNameSpecifierLoc QualifierLoc,
19290b57cec5SDimitry Andric                                             QualType T) {
19300b57cec5SDimitry Andric   if (const TagType *TT = T->getAs<TagType>()) {
19310b57cec5SDimitry Andric     TagDecl* TD = TT->getDecl();
19320b57cec5SDimitry Andric 
19330b57cec5SDimitry Andric     SourceLocation TagLocation = KeywordLoc;
19340b57cec5SDimitry Andric 
19350b57cec5SDimitry Andric     IdentifierInfo *Id = TD->getIdentifier();
19360b57cec5SDimitry Andric 
19370b57cec5SDimitry Andric     // TODO: should we even warn on struct/class mismatches for this?  Seems
19380b57cec5SDimitry Andric     // like it's likely to produce a lot of spurious errors.
19395f757f3fSDimitry Andric     if (Id && Keyword != ElaboratedTypeKeyword::None &&
19405f757f3fSDimitry Andric         Keyword != ElaboratedTypeKeyword::Typename) {
19410b57cec5SDimitry Andric       TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
19420b57cec5SDimitry Andric       if (!SemaRef.isAcceptableTagRedeclaration(TD, Kind, /*isDefinition*/false,
19430b57cec5SDimitry Andric                                                 TagLocation, Id)) {
19440b57cec5SDimitry Andric         SemaRef.Diag(TagLocation, diag::err_use_with_wrong_tag)
19450b57cec5SDimitry Andric           << Id
19460b57cec5SDimitry Andric           << FixItHint::CreateReplacement(SourceRange(TagLocation),
19470b57cec5SDimitry Andric                                           TD->getKindName());
19480b57cec5SDimitry Andric         SemaRef.Diag(TD->getLocation(), diag::note_previous_use);
19490b57cec5SDimitry Andric       }
19500b57cec5SDimitry Andric     }
19510b57cec5SDimitry Andric   }
19520b57cec5SDimitry Andric 
195381ad6265SDimitry Andric   return inherited::RebuildElaboratedType(KeywordLoc, Keyword, QualifierLoc, T);
19540b57cec5SDimitry Andric }
19550b57cec5SDimitry Andric 
19560b57cec5SDimitry Andric TemplateName TemplateInstantiator::TransformTemplateName(
19570b57cec5SDimitry Andric     CXXScopeSpec &SS, TemplateName Name, SourceLocation NameLoc,
19580b57cec5SDimitry Andric     QualType ObjectType, NamedDecl *FirstQualifierInScope,
19590b57cec5SDimitry Andric     bool AllowInjectedClassName) {
19600b57cec5SDimitry Andric   if (TemplateTemplateParmDecl *TTP
19610b57cec5SDimitry Andric        = dyn_cast_or_null<TemplateTemplateParmDecl>(Name.getAsTemplateDecl())) {
19620b57cec5SDimitry Andric     if (TTP->getDepth() < TemplateArgs.getNumLevels()) {
19630b57cec5SDimitry Andric       // If the corresponding template argument is NULL or non-existent, it's
19640b57cec5SDimitry Andric       // because we are performing instantiation from explicitly-specified
19650b57cec5SDimitry Andric       // template arguments in a function template, but there were some
19660b57cec5SDimitry Andric       // arguments left unspecified.
19670b57cec5SDimitry Andric       if (!TemplateArgs.hasTemplateArgument(TTP->getDepth(),
19680b57cec5SDimitry Andric                                             TTP->getPosition()))
19690b57cec5SDimitry Andric         return Name;
19700b57cec5SDimitry Andric 
19710b57cec5SDimitry Andric       TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getPosition());
19720b57cec5SDimitry Andric 
19735ffd83dbSDimitry Andric       if (TemplateArgs.isRewrite()) {
19745ffd83dbSDimitry Andric         // We're rewriting the template parameter as a reference to another
19755ffd83dbSDimitry Andric         // template parameter.
19765ffd83dbSDimitry Andric         if (Arg.getKind() == TemplateArgument::Pack) {
19775ffd83dbSDimitry Andric           assert(Arg.pack_size() == 1 && Arg.pack_begin()->isPackExpansion() &&
19785ffd83dbSDimitry Andric                  "unexpected pack arguments in template rewrite");
19795ffd83dbSDimitry Andric           Arg = Arg.pack_begin()->getPackExpansionPattern();
19805ffd83dbSDimitry Andric         }
19815ffd83dbSDimitry Andric         assert(Arg.getKind() == TemplateArgument::Template &&
19825ffd83dbSDimitry Andric                "unexpected nontype template argument kind in template rewrite");
19835ffd83dbSDimitry Andric         return Arg.getAsTemplate();
19845ffd83dbSDimitry Andric       }
19855ffd83dbSDimitry Andric 
1986bdd1243dSDimitry Andric       auto [AssociatedDecl, Final] =
1987bdd1243dSDimitry Andric           TemplateArgs.getAssociatedDecl(TTP->getDepth());
1988bdd1243dSDimitry Andric       std::optional<unsigned> PackIndex;
19890b57cec5SDimitry Andric       if (TTP->isParameterPack()) {
19900b57cec5SDimitry Andric         assert(Arg.getKind() == TemplateArgument::Pack &&
19910b57cec5SDimitry Andric                "Missing argument pack");
19920b57cec5SDimitry Andric 
19930b57cec5SDimitry Andric         if (getSema().ArgumentPackSubstitutionIndex == -1) {
19940b57cec5SDimitry Andric           // We have the template argument pack to substitute, but we're not
19950b57cec5SDimitry Andric           // actually expanding the enclosing pack expansion yet. So, just
19960b57cec5SDimitry Andric           // keep the entire argument pack.
1997bdd1243dSDimitry Andric           return getSema().Context.getSubstTemplateTemplateParmPack(
1998bdd1243dSDimitry Andric               Arg, AssociatedDecl, TTP->getIndex(), Final);
19990b57cec5SDimitry Andric         }
20000b57cec5SDimitry Andric 
2001bdd1243dSDimitry Andric         PackIndex = getPackIndex(Arg);
20020b57cec5SDimitry Andric         Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
20030b57cec5SDimitry Andric       }
20040b57cec5SDimitry Andric 
20050fca6ea1SDimitry Andric       TemplateName Template = Arg.getAsTemplate();
20060b57cec5SDimitry Andric       assert(!Template.isNull() && "Null template template argument");
20070b57cec5SDimitry Andric 
2008bdd1243dSDimitry Andric       if (Final)
20090b57cec5SDimitry Andric         return Template;
2010bdd1243dSDimitry Andric       return getSema().Context.getSubstTemplateTemplateParm(
2011bdd1243dSDimitry Andric           Template, AssociatedDecl, TTP->getIndex(), PackIndex);
20120b57cec5SDimitry Andric     }
20130b57cec5SDimitry Andric   }
20140b57cec5SDimitry Andric 
20150b57cec5SDimitry Andric   if (SubstTemplateTemplateParmPackStorage *SubstPack
20160b57cec5SDimitry Andric       = Name.getAsSubstTemplateTemplateParmPack()) {
20170b57cec5SDimitry Andric     if (getSema().ArgumentPackSubstitutionIndex == -1)
20180b57cec5SDimitry Andric       return Name;
20190b57cec5SDimitry Andric 
2020bdd1243dSDimitry Andric     TemplateArgument Pack = SubstPack->getArgumentPack();
2021bdd1243dSDimitry Andric     TemplateName Template =
2022bdd1243dSDimitry Andric         getPackSubstitutedTemplateArgument(getSema(), Pack).getAsTemplate();
2023bdd1243dSDimitry Andric     if (SubstPack->getFinal())
2024bdd1243dSDimitry Andric       return Template;
2025bdd1243dSDimitry Andric     return getSema().Context.getSubstTemplateTemplateParm(
20260fca6ea1SDimitry Andric         Template, SubstPack->getAssociatedDecl(), SubstPack->getIndex(),
20270fca6ea1SDimitry Andric         getPackIndex(Pack));
20280b57cec5SDimitry Andric   }
20290b57cec5SDimitry Andric 
20300b57cec5SDimitry Andric   return inherited::TransformTemplateName(SS, Name, NameLoc, ObjectType,
20310b57cec5SDimitry Andric                                           FirstQualifierInScope,
20320b57cec5SDimitry Andric                                           AllowInjectedClassName);
20330b57cec5SDimitry Andric }
20340b57cec5SDimitry Andric 
20350b57cec5SDimitry Andric ExprResult
20360b57cec5SDimitry Andric TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) {
20370b57cec5SDimitry Andric   if (!E->isTypeDependent())
20380b57cec5SDimitry Andric     return E;
20390b57cec5SDimitry Andric 
20400b57cec5SDimitry Andric   return getSema().BuildPredefinedExpr(E->getLocation(), E->getIdentKind());
20410b57cec5SDimitry Andric }
20420b57cec5SDimitry Andric 
20430b57cec5SDimitry Andric ExprResult
20440b57cec5SDimitry Andric TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,
20450b57cec5SDimitry Andric                                                NonTypeTemplateParmDecl *NTTP) {
20460b57cec5SDimitry Andric   // If the corresponding template argument is NULL or non-existent, it's
20470b57cec5SDimitry Andric   // because we are performing instantiation from explicitly-specified
20480b57cec5SDimitry Andric   // template arguments in a function template, but there were some
20490b57cec5SDimitry Andric   // arguments left unspecified.
20500b57cec5SDimitry Andric   if (!TemplateArgs.hasTemplateArgument(NTTP->getDepth(),
20510b57cec5SDimitry Andric                                         NTTP->getPosition()))
20520b57cec5SDimitry Andric     return E;
20530b57cec5SDimitry Andric 
20540b57cec5SDimitry Andric   TemplateArgument Arg = TemplateArgs(NTTP->getDepth(), NTTP->getPosition());
20550b57cec5SDimitry Andric 
20565ffd83dbSDimitry Andric   if (TemplateArgs.isRewrite()) {
20575ffd83dbSDimitry Andric     // We're rewriting the template parameter as a reference to another
20585ffd83dbSDimitry Andric     // template parameter.
20590b57cec5SDimitry Andric     if (Arg.getKind() == TemplateArgument::Pack) {
20600b57cec5SDimitry Andric       assert(Arg.pack_size() == 1 && Arg.pack_begin()->isPackExpansion() &&
20615ffd83dbSDimitry Andric              "unexpected pack arguments in template rewrite");
20620b57cec5SDimitry Andric       Arg = Arg.pack_begin()->getPackExpansionPattern();
20630b57cec5SDimitry Andric     }
20640b57cec5SDimitry Andric     assert(Arg.getKind() == TemplateArgument::Expression &&
20655ffd83dbSDimitry Andric            "unexpected nontype template argument kind in template rewrite");
20665ffd83dbSDimitry Andric     // FIXME: This can lead to the same subexpression appearing multiple times
20675ffd83dbSDimitry Andric     // in a complete expression.
20680b57cec5SDimitry Andric     return Arg.getAsExpr();
20690b57cec5SDimitry Andric   }
20700b57cec5SDimitry Andric 
2071bdd1243dSDimitry Andric   auto [AssociatedDecl, _] = TemplateArgs.getAssociatedDecl(NTTP->getDepth());
2072bdd1243dSDimitry Andric   std::optional<unsigned> PackIndex;
20730b57cec5SDimitry Andric   if (NTTP->isParameterPack()) {
20740b57cec5SDimitry Andric     assert(Arg.getKind() == TemplateArgument::Pack &&
20750b57cec5SDimitry Andric            "Missing argument pack");
20760b57cec5SDimitry Andric 
20770b57cec5SDimitry Andric     if (getSema().ArgumentPackSubstitutionIndex == -1) {
20780b57cec5SDimitry Andric       // We have an argument pack, but we can't select a particular argument
20790b57cec5SDimitry Andric       // out of it yet. Therefore, we'll build an expression to hold on to that
20800b57cec5SDimitry Andric       // argument pack.
20810b57cec5SDimitry Andric       QualType TargetType = SemaRef.SubstType(NTTP->getType(), TemplateArgs,
20820b57cec5SDimitry Andric                                               E->getLocation(),
20830b57cec5SDimitry Andric                                               NTTP->getDeclName());
20840b57cec5SDimitry Andric       if (TargetType.isNull())
20850b57cec5SDimitry Andric         return ExprError();
20860b57cec5SDimitry Andric 
2087e8d8bef9SDimitry Andric       QualType ExprType = TargetType.getNonLValueExprType(SemaRef.Context);
2088e8d8bef9SDimitry Andric       if (TargetType->isRecordType())
2089e8d8bef9SDimitry Andric         ExprType.addConst();
2090bdd1243dSDimitry Andric       // FIXME: Pass in Final.
20910b57cec5SDimitry Andric       return new (SemaRef.Context) SubstNonTypeTemplateParmPackExpr(
2092fe6060f1SDimitry Andric           ExprType, TargetType->isReferenceType() ? VK_LValue : VK_PRValue,
2093bdd1243dSDimitry Andric           E->getLocation(), Arg, AssociatedDecl, NTTP->getPosition());
20940b57cec5SDimitry Andric     }
2095bdd1243dSDimitry Andric     PackIndex = getPackIndex(Arg);
20960b57cec5SDimitry Andric     Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
20970b57cec5SDimitry Andric   }
2098bdd1243dSDimitry Andric   // FIXME: Don't put subst node on Final replacement.
2099bdd1243dSDimitry Andric   return transformNonTypeTemplateParmRef(AssociatedDecl, NTTP, E->getLocation(),
2100bdd1243dSDimitry Andric                                          Arg, PackIndex);
21010b57cec5SDimitry Andric }
21020b57cec5SDimitry Andric 
21030fca6ea1SDimitry Andric const CXXAssumeAttr *
21040fca6ea1SDimitry Andric TemplateInstantiator::TransformCXXAssumeAttr(const CXXAssumeAttr *AA) {
21050fca6ea1SDimitry Andric   ExprResult Res = getDerived().TransformExpr(AA->getAssumption());
21060fca6ea1SDimitry Andric   if (!Res.isUsable())
21070fca6ea1SDimitry Andric     return AA;
21080fca6ea1SDimitry Andric 
21090fca6ea1SDimitry Andric   Res = getSema().BuildCXXAssumeExpr(Res.get(), AA->getAttrName(),
21100fca6ea1SDimitry Andric                                      AA->getRange());
21110fca6ea1SDimitry Andric   if (!Res.isUsable())
21120fca6ea1SDimitry Andric     return AA;
21130fca6ea1SDimitry Andric 
21140fca6ea1SDimitry Andric   return CXXAssumeAttr::CreateImplicit(getSema().Context, Res.get(),
21150fca6ea1SDimitry Andric                                        AA->getRange());
21160fca6ea1SDimitry Andric }
21170fca6ea1SDimitry Andric 
21180b57cec5SDimitry Andric const LoopHintAttr *
21190b57cec5SDimitry Andric TemplateInstantiator::TransformLoopHintAttr(const LoopHintAttr *LH) {
21200b57cec5SDimitry Andric   Expr *TransformedExpr = getDerived().TransformExpr(LH->getValue()).get();
21210b57cec5SDimitry Andric 
21220b57cec5SDimitry Andric   if (TransformedExpr == LH->getValue())
21230b57cec5SDimitry Andric     return LH;
21240b57cec5SDimitry Andric 
21250b57cec5SDimitry Andric   // Generate error if there is a problem with the value.
21260fca6ea1SDimitry Andric   if (getSema().CheckLoopHintExpr(TransformedExpr, LH->getLocation(),
21270fca6ea1SDimitry Andric                                   LH->getSemanticSpelling() ==
21280fca6ea1SDimitry Andric                                       LoopHintAttr::Pragma_unroll))
21290b57cec5SDimitry Andric     return LH;
21300b57cec5SDimitry Andric 
21310fca6ea1SDimitry Andric   LoopHintAttr::OptionType Option = LH->getOption();
21320fca6ea1SDimitry Andric   LoopHintAttr::LoopHintState State = LH->getState();
21330fca6ea1SDimitry Andric 
21340fca6ea1SDimitry Andric   llvm::APSInt ValueAPS =
21350fca6ea1SDimitry Andric       TransformedExpr->EvaluateKnownConstInt(getSema().getASTContext());
21360fca6ea1SDimitry Andric   // The values of 0 and 1 block any unrolling of the loop.
21370fca6ea1SDimitry Andric   if (ValueAPS.isZero() || ValueAPS.isOne()) {
21380fca6ea1SDimitry Andric     Option = LoopHintAttr::Unroll;
21390fca6ea1SDimitry Andric     State = LoopHintAttr::Disable;
21400fca6ea1SDimitry Andric   }
21410fca6ea1SDimitry Andric 
21420b57cec5SDimitry Andric   // Create new LoopHintValueAttr with integral expression in place of the
21430b57cec5SDimitry Andric   // non-type template parameter.
21440fca6ea1SDimitry Andric   return LoopHintAttr::CreateImplicit(getSema().Context, Option, State,
21450fca6ea1SDimitry Andric                                       TransformedExpr, *LH);
21460b57cec5SDimitry Andric }
214706c3fb27SDimitry Andric const NoInlineAttr *TemplateInstantiator::TransformStmtNoInlineAttr(
214806c3fb27SDimitry Andric     const Stmt *OrigS, const Stmt *InstS, const NoInlineAttr *A) {
214906c3fb27SDimitry Andric   if (!A || getSema().CheckNoInlineAttr(OrigS, InstS, *A))
215006c3fb27SDimitry Andric     return nullptr;
215106c3fb27SDimitry Andric 
215206c3fb27SDimitry Andric   return A;
215306c3fb27SDimitry Andric }
215406c3fb27SDimitry Andric const AlwaysInlineAttr *TemplateInstantiator::TransformStmtAlwaysInlineAttr(
215506c3fb27SDimitry Andric     const Stmt *OrigS, const Stmt *InstS, const AlwaysInlineAttr *A) {
215606c3fb27SDimitry Andric   if (!A || getSema().CheckAlwaysInlineAttr(OrigS, InstS, *A))
215706c3fb27SDimitry Andric     return nullptr;
215806c3fb27SDimitry Andric 
215906c3fb27SDimitry Andric   return A;
216006c3fb27SDimitry Andric }
21610b57cec5SDimitry Andric 
21625f757f3fSDimitry Andric const CodeAlignAttr *
21635f757f3fSDimitry Andric TemplateInstantiator::TransformCodeAlignAttr(const CodeAlignAttr *CA) {
21645f757f3fSDimitry Andric   Expr *TransformedExpr = getDerived().TransformExpr(CA->getAlignment()).get();
21655f757f3fSDimitry Andric   return getSema().BuildCodeAlignAttr(*CA, TransformedExpr);
21665f757f3fSDimitry Andric }
21675f757f3fSDimitry Andric 
21680b57cec5SDimitry Andric ExprResult TemplateInstantiator::transformNonTypeTemplateParmRef(
2169bdd1243dSDimitry Andric     Decl *AssociatedDecl, const NonTypeTemplateParmDecl *parm,
2170bdd1243dSDimitry Andric     SourceLocation loc, TemplateArgument arg,
2171bdd1243dSDimitry Andric     std::optional<unsigned> PackIndex) {
21720b57cec5SDimitry Andric   ExprResult result;
21730b57cec5SDimitry Andric 
2174e8d8bef9SDimitry Andric   // Determine the substituted parameter type. We can usually infer this from
2175e8d8bef9SDimitry Andric   // the template argument, but not always.
2176e8d8bef9SDimitry Andric   auto SubstParamType = [&] {
2177e8d8bef9SDimitry Andric     QualType T;
2178e8d8bef9SDimitry Andric     if (parm->isExpandedParameterPack())
2179e8d8bef9SDimitry Andric       T = parm->getExpansionType(SemaRef.ArgumentPackSubstitutionIndex);
2180e8d8bef9SDimitry Andric     else
2181e8d8bef9SDimitry Andric       T = parm->getType();
2182e8d8bef9SDimitry Andric     if (parm->isParameterPack() && isa<PackExpansionType>(T))
2183e8d8bef9SDimitry Andric       T = cast<PackExpansionType>(T)->getPattern();
2184e8d8bef9SDimitry Andric     return SemaRef.SubstType(T, TemplateArgs, loc, parm->getDeclName());
2185e8d8bef9SDimitry Andric   };
2186e8d8bef9SDimitry Andric 
2187e8d8bef9SDimitry Andric   bool refParam = false;
2188e8d8bef9SDimitry Andric 
2189e8d8bef9SDimitry Andric   // The template argument itself might be an expression, in which case we just
2190e8d8bef9SDimitry Andric   // return that expression. This happens when substituting into an alias
2191e8d8bef9SDimitry Andric   // template.
21920b57cec5SDimitry Andric   if (arg.getKind() == TemplateArgument::Expression) {
21930b57cec5SDimitry Andric     Expr *argExpr = arg.getAsExpr();
21940b57cec5SDimitry Andric     result = argExpr;
2195e8d8bef9SDimitry Andric     if (argExpr->isLValue()) {
2196e8d8bef9SDimitry Andric       if (argExpr->getType()->isRecordType()) {
2197e8d8bef9SDimitry Andric         // Check whether the parameter was actually a reference.
2198e8d8bef9SDimitry Andric         QualType paramType = SubstParamType();
2199e8d8bef9SDimitry Andric         if (paramType.isNull())
2200e8d8bef9SDimitry Andric           return ExprError();
2201e8d8bef9SDimitry Andric         refParam = paramType->isReferenceType();
2202e8d8bef9SDimitry Andric       } else {
2203e8d8bef9SDimitry Andric         refParam = true;
2204e8d8bef9SDimitry Andric       }
2205e8d8bef9SDimitry Andric     }
22060b57cec5SDimitry Andric   } else if (arg.getKind() == TemplateArgument::Declaration ||
22070b57cec5SDimitry Andric              arg.getKind() == TemplateArgument::NullPtr) {
22080b57cec5SDimitry Andric     if (arg.getKind() == TemplateArgument::Declaration) {
22097a6dacacSDimitry Andric       ValueDecl *VD = arg.getAsDecl();
22100b57cec5SDimitry Andric 
22110b57cec5SDimitry Andric       // Find the instantiation of the template argument.  This is
22120b57cec5SDimitry Andric       // required for nested templates.
22130b57cec5SDimitry Andric       VD = cast_or_null<ValueDecl>(
22140b57cec5SDimitry Andric              getSema().FindInstantiatedDecl(loc, VD, TemplateArgs));
22150b57cec5SDimitry Andric       if (!VD)
22160b57cec5SDimitry Andric         return ExprError();
22170b57cec5SDimitry Andric     }
22180b57cec5SDimitry Andric 
22197a6dacacSDimitry Andric     QualType paramType = arg.getNonTypeTemplateArgumentType();
2220e8d8bef9SDimitry Andric     assert(!paramType.isNull() && "type substitution failed for param type");
2221e8d8bef9SDimitry Andric     assert(!paramType->isDependentType() && "param type still dependent");
2222e8d8bef9SDimitry Andric     result = SemaRef.BuildExpressionFromDeclTemplateArgument(arg, paramType, loc);
2223e8d8bef9SDimitry Andric     refParam = paramType->isReferenceType();
22240b57cec5SDimitry Andric   } else {
22257a6dacacSDimitry Andric     QualType paramType = arg.getNonTypeTemplateArgumentType();
22267a6dacacSDimitry Andric     result = SemaRef.BuildExpressionFromNonTypeTemplateArgument(arg, loc);
22277a6dacacSDimitry Andric     refParam = paramType->isReferenceType();
2228e8d8bef9SDimitry Andric     assert(result.isInvalid() ||
2229e8d8bef9SDimitry Andric            SemaRef.Context.hasSameType(result.get()->getType(),
22307a6dacacSDimitry Andric                                        paramType.getNonReferenceType()));
22310b57cec5SDimitry Andric   }
2232e8d8bef9SDimitry Andric 
2233e8d8bef9SDimitry Andric   if (result.isInvalid())
2234e8d8bef9SDimitry Andric     return ExprError();
22350b57cec5SDimitry Andric 
22360b57cec5SDimitry Andric   Expr *resultExpr = result.get();
2237bdd1243dSDimitry Andric   // FIXME: Don't put subst node on final replacement.
22380b57cec5SDimitry Andric   return new (SemaRef.Context) SubstNonTypeTemplateParmExpr(
2239bdd1243dSDimitry Andric       resultExpr->getType(), resultExpr->getValueKind(), loc, resultExpr,
2240bdd1243dSDimitry Andric       AssociatedDecl, parm->getIndex(), PackIndex, refParam);
22410b57cec5SDimitry Andric }
22420b57cec5SDimitry Andric 
22430b57cec5SDimitry Andric ExprResult
22440b57cec5SDimitry Andric TemplateInstantiator::TransformSubstNonTypeTemplateParmPackExpr(
22450b57cec5SDimitry Andric                                           SubstNonTypeTemplateParmPackExpr *E) {
22460b57cec5SDimitry Andric   if (getSema().ArgumentPackSubstitutionIndex == -1) {
22470b57cec5SDimitry Andric     // We aren't expanding the parameter pack, so just return ourselves.
22480b57cec5SDimitry Andric     return E;
22490b57cec5SDimitry Andric   }
22500b57cec5SDimitry Andric 
2251bdd1243dSDimitry Andric   TemplateArgument Pack = E->getArgumentPack();
2252bdd1243dSDimitry Andric   TemplateArgument Arg = getPackSubstitutedTemplateArgument(getSema(), Pack);
2253bdd1243dSDimitry Andric   // FIXME: Don't put subst node on final replacement.
2254bdd1243dSDimitry Andric   return transformNonTypeTemplateParmRef(
2255bdd1243dSDimitry Andric       E->getAssociatedDecl(), E->getParameterPack(),
2256bdd1243dSDimitry Andric       E->getParameterPackLocation(), Arg, getPackIndex(Pack));
22570b57cec5SDimitry Andric }
22580b57cec5SDimitry Andric 
225913138422SDimitry Andric ExprResult
226013138422SDimitry Andric TemplateInstantiator::TransformSubstNonTypeTemplateParmExpr(
226113138422SDimitry Andric                                           SubstNonTypeTemplateParmExpr *E) {
2262e8d8bef9SDimitry Andric   ExprResult SubstReplacement = E->getReplacement();
2263e8d8bef9SDimitry Andric   if (!isa<ConstantExpr>(SubstReplacement.get()))
2264e8d8bef9SDimitry Andric     SubstReplacement = TransformExpr(E->getReplacement());
226513138422SDimitry Andric   if (SubstReplacement.isInvalid())
226613138422SDimitry Andric     return true;
2267e8d8bef9SDimitry Andric   QualType SubstType = TransformType(E->getParameterType(getSema().Context));
226813138422SDimitry Andric   if (SubstType.isNull())
226913138422SDimitry Andric     return true;
227013138422SDimitry Andric   // The type may have been previously dependent and not now, which means we
227113138422SDimitry Andric   // might have to implicit cast the argument to the new type, for example:
227213138422SDimitry Andric   // template<auto T, decltype(T) U>
227313138422SDimitry Andric   // concept C = sizeof(U) == 4;
227413138422SDimitry Andric   // void foo() requires C<2, 'a'> { }
227513138422SDimitry Andric   // When normalizing foo(), we first form the normalized constraints of C:
227613138422SDimitry Andric   // AtomicExpr(sizeof(U) == 4,
227713138422SDimitry Andric   //            U=SubstNonTypeTemplateParmExpr(Param=U,
227813138422SDimitry Andric   //                                           Expr=DeclRef(U),
227913138422SDimitry Andric   //                                           Type=decltype(T)))
228013138422SDimitry Andric   // Then we substitute T = 2, U = 'a' into the parameter mapping, and need to
228113138422SDimitry Andric   // produce:
228213138422SDimitry Andric   // AtomicExpr(sizeof(U) == 4,
228313138422SDimitry Andric   //            U=SubstNonTypeTemplateParmExpr(Param=U,
228413138422SDimitry Andric   //                                           Expr=ImpCast(
228513138422SDimitry Andric   //                                               decltype(2),
228613138422SDimitry Andric   //                                               SubstNTTPE(Param=U, Expr='a',
228713138422SDimitry Andric   //                                                          Type=char)),
228813138422SDimitry Andric   //                                           Type=decltype(2)))
228913138422SDimitry Andric   // The call to CheckTemplateArgument here produces the ImpCast.
2290bdd1243dSDimitry Andric   TemplateArgument SugaredConverted, CanonicalConverted;
2291bdd1243dSDimitry Andric   if (SemaRef
2292bdd1243dSDimitry Andric           .CheckTemplateArgument(E->getParameter(), SubstType,
2293bdd1243dSDimitry Andric                                  SubstReplacement.get(), SugaredConverted,
2294bdd1243dSDimitry Andric                                  CanonicalConverted, Sema::CTAK_Specified)
2295bdd1243dSDimitry Andric           .isInvalid())
229613138422SDimitry Andric     return true;
2297bdd1243dSDimitry Andric   return transformNonTypeTemplateParmRef(E->getAssociatedDecl(),
2298bdd1243dSDimitry Andric                                          E->getParameter(), E->getExprLoc(),
2299bdd1243dSDimitry Andric                                          SugaredConverted, E->getPackIndex());
230013138422SDimitry Andric }
230113138422SDimitry Andric 
23020b57cec5SDimitry Andric ExprResult TemplateInstantiator::RebuildVarDeclRefExpr(VarDecl *PD,
23030b57cec5SDimitry Andric                                                        SourceLocation Loc) {
23040b57cec5SDimitry Andric   DeclarationNameInfo NameInfo(PD->getDeclName(), Loc);
23050b57cec5SDimitry Andric   return getSema().BuildDeclarationNameExpr(CXXScopeSpec(), NameInfo, PD);
23060b57cec5SDimitry Andric }
23070b57cec5SDimitry Andric 
23080b57cec5SDimitry Andric ExprResult
23090b57cec5SDimitry Andric TemplateInstantiator::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
23100b57cec5SDimitry Andric   if (getSema().ArgumentPackSubstitutionIndex != -1) {
23110b57cec5SDimitry Andric     // We can expand this parameter pack now.
23120b57cec5SDimitry Andric     VarDecl *D = E->getExpansion(getSema().ArgumentPackSubstitutionIndex);
23130b57cec5SDimitry Andric     VarDecl *VD = cast_or_null<VarDecl>(TransformDecl(E->getExprLoc(), D));
23140b57cec5SDimitry Andric     if (!VD)
23150b57cec5SDimitry Andric       return ExprError();
23160b57cec5SDimitry Andric     return RebuildVarDeclRefExpr(VD, E->getExprLoc());
23170b57cec5SDimitry Andric   }
23180b57cec5SDimitry Andric 
23190b57cec5SDimitry Andric   QualType T = TransformType(E->getType());
23200b57cec5SDimitry Andric   if (T.isNull())
23210b57cec5SDimitry Andric     return ExprError();
23220b57cec5SDimitry Andric 
23230b57cec5SDimitry Andric   // Transform each of the parameter expansions into the corresponding
23240b57cec5SDimitry Andric   // parameters in the instantiation of the function decl.
23250b57cec5SDimitry Andric   SmallVector<VarDecl *, 8> Vars;
23260b57cec5SDimitry Andric   Vars.reserve(E->getNumExpansions());
23270b57cec5SDimitry Andric   for (FunctionParmPackExpr::iterator I = E->begin(), End = E->end();
23280b57cec5SDimitry Andric        I != End; ++I) {
23290b57cec5SDimitry Andric     VarDecl *D = cast_or_null<VarDecl>(TransformDecl(E->getExprLoc(), *I));
23300b57cec5SDimitry Andric     if (!D)
23310b57cec5SDimitry Andric       return ExprError();
23320b57cec5SDimitry Andric     Vars.push_back(D);
23330b57cec5SDimitry Andric   }
23340b57cec5SDimitry Andric 
23350b57cec5SDimitry Andric   auto *PackExpr =
23360b57cec5SDimitry Andric       FunctionParmPackExpr::Create(getSema().Context, T, E->getParameterPack(),
23370b57cec5SDimitry Andric                                    E->getParameterPackLocation(), Vars);
23380b57cec5SDimitry Andric   getSema().MarkFunctionParmPackReferenced(PackExpr);
23390b57cec5SDimitry Andric   return PackExpr;
23400b57cec5SDimitry Andric }
23410b57cec5SDimitry Andric 
23420b57cec5SDimitry Andric ExprResult
23430b57cec5SDimitry Andric TemplateInstantiator::TransformFunctionParmPackRefExpr(DeclRefExpr *E,
23440b57cec5SDimitry Andric                                                        VarDecl *PD) {
23450b57cec5SDimitry Andric   typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
23460b57cec5SDimitry Andric   llvm::PointerUnion<Decl *, DeclArgumentPack *> *Found
23470b57cec5SDimitry Andric     = getSema().CurrentInstantiationScope->findInstantiationOf(PD);
23480b57cec5SDimitry Andric   assert(Found && "no instantiation for parameter pack");
23490b57cec5SDimitry Andric 
23500b57cec5SDimitry Andric   Decl *TransformedDecl;
23510b57cec5SDimitry Andric   if (DeclArgumentPack *Pack = Found->dyn_cast<DeclArgumentPack *>()) {
23520b57cec5SDimitry Andric     // If this is a reference to a function parameter pack which we can
23530b57cec5SDimitry Andric     // substitute but can't yet expand, build a FunctionParmPackExpr for it.
23540b57cec5SDimitry Andric     if (getSema().ArgumentPackSubstitutionIndex == -1) {
23550b57cec5SDimitry Andric       QualType T = TransformType(E->getType());
23560b57cec5SDimitry Andric       if (T.isNull())
23570b57cec5SDimitry Andric         return ExprError();
23580b57cec5SDimitry Andric       auto *PackExpr = FunctionParmPackExpr::Create(getSema().Context, T, PD,
23590b57cec5SDimitry Andric                                                     E->getExprLoc(), *Pack);
23600b57cec5SDimitry Andric       getSema().MarkFunctionParmPackReferenced(PackExpr);
23610b57cec5SDimitry Andric       return PackExpr;
23620b57cec5SDimitry Andric     }
23630b57cec5SDimitry Andric 
23640b57cec5SDimitry Andric     TransformedDecl = (*Pack)[getSema().ArgumentPackSubstitutionIndex];
23650b57cec5SDimitry Andric   } else {
23660b57cec5SDimitry Andric     TransformedDecl = Found->get<Decl*>();
23670b57cec5SDimitry Andric   }
23680b57cec5SDimitry Andric 
23690b57cec5SDimitry Andric   // We have either an unexpanded pack or a specific expansion.
23700b57cec5SDimitry Andric   return RebuildVarDeclRefExpr(cast<VarDecl>(TransformedDecl), E->getExprLoc());
23710b57cec5SDimitry Andric }
23720b57cec5SDimitry Andric 
23730b57cec5SDimitry Andric ExprResult
23740b57cec5SDimitry Andric TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E) {
23750b57cec5SDimitry Andric   NamedDecl *D = E->getDecl();
23760b57cec5SDimitry Andric 
23770b57cec5SDimitry Andric   // Handle references to non-type template parameters and non-type template
23780b57cec5SDimitry Andric   // parameter packs.
23790b57cec5SDimitry Andric   if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
23800b57cec5SDimitry Andric     if (NTTP->getDepth() < TemplateArgs.getNumLevels())
23810b57cec5SDimitry Andric       return TransformTemplateParmRefExpr(E, NTTP);
23820b57cec5SDimitry Andric 
23830b57cec5SDimitry Andric     // We have a non-type template parameter that isn't fully substituted;
23840b57cec5SDimitry Andric     // FindInstantiatedDecl will find it in the local instantiation scope.
23850b57cec5SDimitry Andric   }
23860b57cec5SDimitry Andric 
23870b57cec5SDimitry Andric   // Handle references to function parameter packs.
23880b57cec5SDimitry Andric   if (VarDecl *PD = dyn_cast<VarDecl>(D))
23890b57cec5SDimitry Andric     if (PD->isParameterPack())
23900b57cec5SDimitry Andric       return TransformFunctionParmPackRefExpr(E, PD);
23910b57cec5SDimitry Andric 
239281ad6265SDimitry Andric   return inherited::TransformDeclRefExpr(E);
23930b57cec5SDimitry Andric }
23940b57cec5SDimitry Andric 
23950b57cec5SDimitry Andric ExprResult TemplateInstantiator::TransformCXXDefaultArgExpr(
23960b57cec5SDimitry Andric     CXXDefaultArgExpr *E) {
23970b57cec5SDimitry Andric   assert(!cast<FunctionDecl>(E->getParam()->getDeclContext())->
23980b57cec5SDimitry Andric              getDescribedFunctionTemplate() &&
23990b57cec5SDimitry Andric          "Default arg expressions are never formed in dependent cases.");
2400bdd1243dSDimitry Andric   return SemaRef.BuildCXXDefaultArgExpr(
2401bdd1243dSDimitry Andric       E->getUsedLocation(), cast<FunctionDecl>(E->getParam()->getDeclContext()),
24020b57cec5SDimitry Andric       E->getParam());
24030b57cec5SDimitry Andric }
24040b57cec5SDimitry Andric 
24050b57cec5SDimitry Andric template<typename Fn>
24060b57cec5SDimitry Andric QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB,
24070b57cec5SDimitry Andric                                  FunctionProtoTypeLoc TL,
24080b57cec5SDimitry Andric                                  CXXRecordDecl *ThisContext,
24090b57cec5SDimitry Andric                                  Qualifiers ThisTypeQuals,
24100b57cec5SDimitry Andric                                  Fn TransformExceptionSpec) {
24110b57cec5SDimitry Andric   // We need a local instantiation scope for this function prototype.
24120b57cec5SDimitry Andric   LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
24130b57cec5SDimitry Andric   return inherited::TransformFunctionProtoType(
24140b57cec5SDimitry Andric       TLB, TL, ThisContext, ThisTypeQuals, TransformExceptionSpec);
24150b57cec5SDimitry Andric }
24160b57cec5SDimitry Andric 
2417bdd1243dSDimitry Andric ParmVarDecl *TemplateInstantiator::TransformFunctionTypeParam(
2418bdd1243dSDimitry Andric     ParmVarDecl *OldParm, int indexAdjustment,
2419bdd1243dSDimitry Andric     std::optional<unsigned> NumExpansions, bool ExpectParameterPack) {
2420bdd1243dSDimitry Andric   auto NewParm = SemaRef.SubstParmVarDecl(
2421bdd1243dSDimitry Andric       OldParm, TemplateArgs, indexAdjustment, NumExpansions,
2422bdd1243dSDimitry Andric       ExpectParameterPack, EvaluateConstraints);
2423480093f4SDimitry Andric   if (NewParm && SemaRef.getLangOpts().OpenCL)
2424480093f4SDimitry Andric     SemaRef.deduceOpenCLAddressSpace(NewParm);
2425480093f4SDimitry Andric   return NewParm;
24260b57cec5SDimitry Andric }
24270b57cec5SDimitry Andric 
2428bdd1243dSDimitry Andric QualType TemplateInstantiator::BuildSubstTemplateTypeParmType(
2429bdd1243dSDimitry Andric     TypeLocBuilder &TLB, bool SuppressObjCLifetime, bool Final,
2430bdd1243dSDimitry Andric     Decl *AssociatedDecl, unsigned Index, std::optional<unsigned> PackIndex,
2431bdd1243dSDimitry Andric     TemplateArgument Arg, SourceLocation NameLoc) {
2432bdd1243dSDimitry Andric   QualType Replacement = Arg.getAsType();
2433bdd1243dSDimitry Andric 
2434bdd1243dSDimitry Andric   // If the template parameter had ObjC lifetime qualifiers,
2435bdd1243dSDimitry Andric   // then any such qualifiers on the replacement type are ignored.
2436bdd1243dSDimitry Andric   if (SuppressObjCLifetime) {
2437bdd1243dSDimitry Andric     Qualifiers RQs;
2438bdd1243dSDimitry Andric     RQs = Replacement.getQualifiers();
2439bdd1243dSDimitry Andric     RQs.removeObjCLifetime();
2440bdd1243dSDimitry Andric     Replacement =
2441bdd1243dSDimitry Andric         SemaRef.Context.getQualifiedType(Replacement.getUnqualifiedType(), RQs);
2442bdd1243dSDimitry Andric   }
2443bdd1243dSDimitry Andric 
2444bdd1243dSDimitry Andric   if (Final) {
2445bdd1243dSDimitry Andric     TLB.pushTrivial(SemaRef.Context, Replacement, NameLoc);
2446bdd1243dSDimitry Andric     return Replacement;
2447bdd1243dSDimitry Andric   }
2448bdd1243dSDimitry Andric   // TODO: only do this uniquing once, at the start of instantiation.
2449bdd1243dSDimitry Andric   QualType Result = getSema().Context.getSubstTemplateTypeParmType(
2450bdd1243dSDimitry Andric       Replacement, AssociatedDecl, Index, PackIndex);
2451bdd1243dSDimitry Andric   SubstTemplateTypeParmTypeLoc NewTL =
2452bdd1243dSDimitry Andric       TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
2453bdd1243dSDimitry Andric   NewTL.setNameLoc(NameLoc);
2454bdd1243dSDimitry Andric   return Result;
2455bdd1243dSDimitry Andric }
2456bdd1243dSDimitry Andric 
24570b57cec5SDimitry Andric QualType
24580b57cec5SDimitry Andric TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB,
2459bdd1243dSDimitry Andric                                                     TemplateTypeParmTypeLoc TL,
2460bdd1243dSDimitry Andric                                                     bool SuppressObjCLifetime) {
24610b57cec5SDimitry Andric   const TemplateTypeParmType *T = TL.getTypePtr();
24620b57cec5SDimitry Andric   if (T->getDepth() < TemplateArgs.getNumLevels()) {
24630b57cec5SDimitry Andric     // Replace the template type parameter with its corresponding
24640b57cec5SDimitry Andric     // template argument.
24650b57cec5SDimitry Andric 
24660b57cec5SDimitry Andric     // If the corresponding template argument is NULL or doesn't exist, it's
24670b57cec5SDimitry Andric     // because we are performing instantiation from explicitly-specified
24680b57cec5SDimitry Andric     // template arguments in a function template class, but there were some
24690b57cec5SDimitry Andric     // arguments left unspecified.
24700b57cec5SDimitry Andric     if (!TemplateArgs.hasTemplateArgument(T->getDepth(), T->getIndex())) {
24710b57cec5SDimitry Andric       TemplateTypeParmTypeLoc NewTL
24720b57cec5SDimitry Andric         = TLB.push<TemplateTypeParmTypeLoc>(TL.getType());
24730b57cec5SDimitry Andric       NewTL.setNameLoc(TL.getNameLoc());
24740b57cec5SDimitry Andric       return TL.getType();
24750b57cec5SDimitry Andric     }
24760b57cec5SDimitry Andric 
24770b57cec5SDimitry Andric     TemplateArgument Arg = TemplateArgs(T->getDepth(), T->getIndex());
24780b57cec5SDimitry Andric 
24795ffd83dbSDimitry Andric     if (TemplateArgs.isRewrite()) {
24805ffd83dbSDimitry Andric       // We're rewriting the template parameter as a reference to another
24815ffd83dbSDimitry Andric       // template parameter.
24825ffd83dbSDimitry Andric       if (Arg.getKind() == TemplateArgument::Pack) {
24835ffd83dbSDimitry Andric         assert(Arg.pack_size() == 1 && Arg.pack_begin()->isPackExpansion() &&
24845ffd83dbSDimitry Andric                "unexpected pack arguments in template rewrite");
24855ffd83dbSDimitry Andric         Arg = Arg.pack_begin()->getPackExpansionPattern();
24865ffd83dbSDimitry Andric       }
24875ffd83dbSDimitry Andric       assert(Arg.getKind() == TemplateArgument::Type &&
24885ffd83dbSDimitry Andric              "unexpected nontype template argument kind in template rewrite");
24895ffd83dbSDimitry Andric       QualType NewT = Arg.getAsType();
24900fca6ea1SDimitry Andric       TLB.pushTrivial(SemaRef.Context, NewT, TL.getNameLoc());
24915ffd83dbSDimitry Andric       return NewT;
24925ffd83dbSDimitry Andric     }
24935ffd83dbSDimitry Andric 
2494bdd1243dSDimitry Andric     auto [AssociatedDecl, Final] =
2495bdd1243dSDimitry Andric         TemplateArgs.getAssociatedDecl(T->getDepth());
2496bdd1243dSDimitry Andric     std::optional<unsigned> PackIndex;
24970b57cec5SDimitry Andric     if (T->isParameterPack()) {
24980b57cec5SDimitry Andric       assert(Arg.getKind() == TemplateArgument::Pack &&
24990b57cec5SDimitry Andric              "Missing argument pack");
25000b57cec5SDimitry Andric 
25010b57cec5SDimitry Andric       if (getSema().ArgumentPackSubstitutionIndex == -1) {
25020b57cec5SDimitry Andric         // We have the template argument pack, but we're not expanding the
25030b57cec5SDimitry Andric         // enclosing pack expansion yet. Just save the template argument
25040b57cec5SDimitry Andric         // pack for later substitution.
2505bdd1243dSDimitry Andric         QualType Result = getSema().Context.getSubstTemplateTypeParmPackType(
2506bdd1243dSDimitry Andric             AssociatedDecl, T->getIndex(), Final, Arg);
25070b57cec5SDimitry Andric         SubstTemplateTypeParmPackTypeLoc NewTL
25080b57cec5SDimitry Andric           = TLB.push<SubstTemplateTypeParmPackTypeLoc>(Result);
25090b57cec5SDimitry Andric         NewTL.setNameLoc(TL.getNameLoc());
25100b57cec5SDimitry Andric         return Result;
25110b57cec5SDimitry Andric       }
25120b57cec5SDimitry Andric 
2513bdd1243dSDimitry Andric       // PackIndex starts from last element.
2514bdd1243dSDimitry Andric       PackIndex = getPackIndex(Arg);
25150b57cec5SDimitry Andric       Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
25160b57cec5SDimitry Andric     }
25170b57cec5SDimitry Andric 
25180b57cec5SDimitry Andric     assert(Arg.getKind() == TemplateArgument::Type &&
25190b57cec5SDimitry Andric            "Template argument kind mismatch");
25200b57cec5SDimitry Andric 
2521bdd1243dSDimitry Andric     return BuildSubstTemplateTypeParmType(TLB, SuppressObjCLifetime, Final,
2522bdd1243dSDimitry Andric                                           AssociatedDecl, T->getIndex(),
2523bdd1243dSDimitry Andric                                           PackIndex, Arg, TL.getNameLoc());
25240b57cec5SDimitry Andric   }
25250b57cec5SDimitry Andric 
25260b57cec5SDimitry Andric   // The template type parameter comes from an inner template (e.g.,
25270b57cec5SDimitry Andric   // the template parameter list of a member template inside the
25280b57cec5SDimitry Andric   // template we are instantiating). Create a new template type
25290b57cec5SDimitry Andric   // parameter with the template "level" reduced by one.
25300b57cec5SDimitry Andric   TemplateTypeParmDecl *NewTTPDecl = nullptr;
25310b57cec5SDimitry Andric   if (TemplateTypeParmDecl *OldTTPDecl = T->getDecl())
25320b57cec5SDimitry Andric     NewTTPDecl = cast_or_null<TemplateTypeParmDecl>(
25330b57cec5SDimitry Andric         TransformDecl(TL.getNameLoc(), OldTTPDecl));
25340b57cec5SDimitry Andric   QualType Result = getSema().Context.getTemplateTypeParmType(
25350b57cec5SDimitry Andric       T->getDepth() - TemplateArgs.getNumSubstitutedLevels(), T->getIndex(),
25360b57cec5SDimitry Andric       T->isParameterPack(), NewTTPDecl);
25370b57cec5SDimitry Andric   TemplateTypeParmTypeLoc NewTL = TLB.push<TemplateTypeParmTypeLoc>(Result);
25380b57cec5SDimitry Andric   NewTL.setNameLoc(TL.getNameLoc());
25390b57cec5SDimitry Andric   return Result;
25400b57cec5SDimitry Andric }
25410b57cec5SDimitry Andric 
2542bdd1243dSDimitry Andric QualType TemplateInstantiator::TransformSubstTemplateTypeParmPackType(
2543bdd1243dSDimitry Andric     TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL,
2544bdd1243dSDimitry Andric     bool SuppressObjCLifetime) {
2545bdd1243dSDimitry Andric   const SubstTemplateTypeParmPackType *T = TL.getTypePtr();
2546bdd1243dSDimitry Andric 
2547bdd1243dSDimitry Andric   Decl *NewReplaced = TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
2548bdd1243dSDimitry Andric 
25490b57cec5SDimitry Andric   if (getSema().ArgumentPackSubstitutionIndex == -1) {
25500b57cec5SDimitry Andric     // We aren't expanding the parameter pack, so just return ourselves.
2551bdd1243dSDimitry Andric     QualType Result = TL.getType();
2552bdd1243dSDimitry Andric     if (NewReplaced != T->getAssociatedDecl())
2553bdd1243dSDimitry Andric       Result = getSema().Context.getSubstTemplateTypeParmPackType(
2554bdd1243dSDimitry Andric           NewReplaced, T->getIndex(), T->getFinal(), T->getArgumentPack());
2555bdd1243dSDimitry Andric     SubstTemplateTypeParmPackTypeLoc NewTL =
2556bdd1243dSDimitry Andric         TLB.push<SubstTemplateTypeParmPackTypeLoc>(Result);
25570b57cec5SDimitry Andric     NewTL.setNameLoc(TL.getNameLoc());
25580b57cec5SDimitry Andric     return Result;
25590b57cec5SDimitry Andric   }
25600b57cec5SDimitry Andric 
2561bdd1243dSDimitry Andric   TemplateArgument Pack = T->getArgumentPack();
2562bdd1243dSDimitry Andric   TemplateArgument Arg = getPackSubstitutedTemplateArgument(getSema(), Pack);
2563bdd1243dSDimitry Andric   return BuildSubstTemplateTypeParmType(
2564bdd1243dSDimitry Andric       TLB, SuppressObjCLifetime, T->getFinal(), NewReplaced, T->getIndex(),
2565bdd1243dSDimitry Andric       getPackIndex(Pack), Arg, TL.getNameLoc());
2566bdd1243dSDimitry Andric }
2567bdd1243dSDimitry Andric 
256855e4f9d5SDimitry Andric static concepts::Requirement::SubstitutionDiagnostic *
25698a4dda33SDimitry Andric createSubstDiag(Sema &S, TemplateDeductionInfo &Info,
25708a4dda33SDimitry Andric                 concepts::EntityPrinter Printer) {
257155e4f9d5SDimitry Andric   SmallString<128> Message;
257255e4f9d5SDimitry Andric   SourceLocation ErrorLoc;
257355e4f9d5SDimitry Andric   if (Info.hasSFINAEDiagnostic()) {
257455e4f9d5SDimitry Andric     PartialDiagnosticAt PDA(SourceLocation(),
257555e4f9d5SDimitry Andric                             PartialDiagnostic::NullDiagnostic{});
257655e4f9d5SDimitry Andric     Info.takeSFINAEDiagnostic(PDA);
257755e4f9d5SDimitry Andric     PDA.second.EmitToString(S.getDiagnostics(), Message);
257855e4f9d5SDimitry Andric     ErrorLoc = PDA.first;
257955e4f9d5SDimitry Andric   } else {
258055e4f9d5SDimitry Andric     ErrorLoc = Info.getLocation();
258155e4f9d5SDimitry Andric   }
258255e4f9d5SDimitry Andric   SmallString<128> Entity;
258355e4f9d5SDimitry Andric   llvm::raw_svector_ostream OS(Entity);
258455e4f9d5SDimitry Andric   Printer(OS);
25850fca6ea1SDimitry Andric   const ASTContext &C = S.Context;
25860fca6ea1SDimitry Andric   return new (C) concepts::Requirement::SubstitutionDiagnostic{
25870fca6ea1SDimitry Andric       C.backupStr(Entity), ErrorLoc, C.backupStr(Message)};
258855e4f9d5SDimitry Andric }
258955e4f9d5SDimitry Andric 
25908a4dda33SDimitry Andric concepts::Requirement::SubstitutionDiagnostic *
25918a4dda33SDimitry Andric concepts::createSubstDiagAt(Sema &S, SourceLocation Location,
25928a4dda33SDimitry Andric                             EntityPrinter Printer) {
25938a4dda33SDimitry Andric   SmallString<128> Entity;
25948a4dda33SDimitry Andric   llvm::raw_svector_ostream OS(Entity);
25958a4dda33SDimitry Andric   Printer(OS);
25960fca6ea1SDimitry Andric   const ASTContext &C = S.Context;
25970fca6ea1SDimitry Andric   return new (C) concepts::Requirement::SubstitutionDiagnostic{
25980fca6ea1SDimitry Andric       /*SubstitutedEntity=*/C.backupStr(Entity),
25998a4dda33SDimitry Andric       /*DiagLoc=*/Location, /*DiagMessage=*/StringRef()};
26008a4dda33SDimitry Andric }
26018a4dda33SDimitry Andric 
2602bdd1243dSDimitry Andric ExprResult TemplateInstantiator::TransformRequiresTypeParams(
2603bdd1243dSDimitry Andric     SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
2604bdd1243dSDimitry Andric     RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,
2605bdd1243dSDimitry Andric     SmallVectorImpl<QualType> &PTypes,
2606bdd1243dSDimitry Andric     SmallVectorImpl<ParmVarDecl *> &TransParams,
2607bdd1243dSDimitry Andric     Sema::ExtParameterInfoBuilder &PInfos) {
2608bdd1243dSDimitry Andric 
2609bdd1243dSDimitry Andric   TemplateDeductionInfo Info(KWLoc);
2610bdd1243dSDimitry Andric   Sema::InstantiatingTemplate TypeInst(SemaRef, KWLoc,
2611bdd1243dSDimitry Andric                                        RE, Info,
2612bdd1243dSDimitry Andric                                        SourceRange{KWLoc, RBraceLoc});
2613bdd1243dSDimitry Andric   Sema::SFINAETrap Trap(SemaRef);
2614bdd1243dSDimitry Andric 
2615bdd1243dSDimitry Andric   unsigned ErrorIdx;
2616bdd1243dSDimitry Andric   if (getDerived().TransformFunctionTypeParams(
2617bdd1243dSDimitry Andric           KWLoc, Params, /*ParamTypes=*/nullptr, /*ParamInfos=*/nullptr, PTypes,
2618bdd1243dSDimitry Andric           &TransParams, PInfos, &ErrorIdx) ||
2619bdd1243dSDimitry Andric       Trap.hasErrorOccurred()) {
2620bdd1243dSDimitry Andric     SmallVector<concepts::Requirement *, 4> TransReqs;
2621bdd1243dSDimitry Andric     ParmVarDecl *FailedDecl = Params[ErrorIdx];
2622bdd1243dSDimitry Andric     // Add a 'failed' Requirement to contain the error that caused the failure
2623bdd1243dSDimitry Andric     // here.
2624bdd1243dSDimitry Andric     TransReqs.push_back(RebuildTypeRequirement(createSubstDiag(
2625bdd1243dSDimitry Andric         SemaRef, Info, [&](llvm::raw_ostream &OS) { OS << *FailedDecl; })));
26265f757f3fSDimitry Andric     return getDerived().RebuildRequiresExpr(KWLoc, Body, RE->getLParenLoc(),
26275f757f3fSDimitry Andric                                             TransParams, RE->getRParenLoc(),
26285f757f3fSDimitry Andric                                             TransReqs, RBraceLoc);
2629bdd1243dSDimitry Andric   }
2630bdd1243dSDimitry Andric 
2631bdd1243dSDimitry Andric   return ExprResult{};
2632bdd1243dSDimitry Andric }
2633bdd1243dSDimitry Andric 
263455e4f9d5SDimitry Andric concepts::TypeRequirement *
263555e4f9d5SDimitry Andric TemplateInstantiator::TransformTypeRequirement(concepts::TypeRequirement *Req) {
263655e4f9d5SDimitry Andric   if (!Req->isDependent() && !AlwaysRebuild())
263755e4f9d5SDimitry Andric     return Req;
263855e4f9d5SDimitry Andric   if (Req->isSubstitutionFailure()) {
263955e4f9d5SDimitry Andric     if (AlwaysRebuild())
264055e4f9d5SDimitry Andric       return RebuildTypeRequirement(
264155e4f9d5SDimitry Andric               Req->getSubstitutionDiagnostic());
264255e4f9d5SDimitry Andric     return Req;
264355e4f9d5SDimitry Andric   }
264455e4f9d5SDimitry Andric 
264555e4f9d5SDimitry Andric   Sema::SFINAETrap Trap(SemaRef);
264655e4f9d5SDimitry Andric   TemplateDeductionInfo Info(Req->getType()->getTypeLoc().getBeginLoc());
264755e4f9d5SDimitry Andric   Sema::InstantiatingTemplate TypeInst(SemaRef,
264855e4f9d5SDimitry Andric       Req->getType()->getTypeLoc().getBeginLoc(), Req, Info,
264955e4f9d5SDimitry Andric       Req->getType()->getTypeLoc().getSourceRange());
265055e4f9d5SDimitry Andric   if (TypeInst.isInvalid())
265155e4f9d5SDimitry Andric     return nullptr;
265255e4f9d5SDimitry Andric   TypeSourceInfo *TransType = TransformType(Req->getType());
265355e4f9d5SDimitry Andric   if (!TransType || Trap.hasErrorOccurred())
265455e4f9d5SDimitry Andric     return RebuildTypeRequirement(createSubstDiag(SemaRef, Info,
265555e4f9d5SDimitry Andric         [&] (llvm::raw_ostream& OS) {
265655e4f9d5SDimitry Andric             Req->getType()->getType().print(OS, SemaRef.getPrintingPolicy());
265755e4f9d5SDimitry Andric         }));
265855e4f9d5SDimitry Andric   return RebuildTypeRequirement(TransType);
265955e4f9d5SDimitry Andric }
266055e4f9d5SDimitry Andric 
266155e4f9d5SDimitry Andric concepts::ExprRequirement *
266255e4f9d5SDimitry Andric TemplateInstantiator::TransformExprRequirement(concepts::ExprRequirement *Req) {
266355e4f9d5SDimitry Andric   if (!Req->isDependent() && !AlwaysRebuild())
266455e4f9d5SDimitry Andric     return Req;
266555e4f9d5SDimitry Andric 
266655e4f9d5SDimitry Andric   Sema::SFINAETrap Trap(SemaRef);
266755e4f9d5SDimitry Andric 
266855e4f9d5SDimitry Andric   llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *>
266955e4f9d5SDimitry Andric       TransExpr;
267055e4f9d5SDimitry Andric   if (Req->isExprSubstitutionFailure())
267155e4f9d5SDimitry Andric     TransExpr = Req->getExprSubstitutionDiagnostic();
267255e4f9d5SDimitry Andric   else {
26736e75b2fbSDimitry Andric     Expr *E = Req->getExpr();
26746e75b2fbSDimitry Andric     TemplateDeductionInfo Info(E->getBeginLoc());
26756e75b2fbSDimitry Andric     Sema::InstantiatingTemplate ExprInst(SemaRef, E->getBeginLoc(), Req, Info,
26766e75b2fbSDimitry Andric                                          E->getSourceRange());
267755e4f9d5SDimitry Andric     if (ExprInst.isInvalid())
267855e4f9d5SDimitry Andric       return nullptr;
26796e75b2fbSDimitry Andric     ExprResult TransExprRes = TransformExpr(E);
26801fd87a68SDimitry Andric     if (!TransExprRes.isInvalid() && !Trap.hasErrorOccurred() &&
26811fd87a68SDimitry Andric         TransExprRes.get()->hasPlaceholderType())
26821fd87a68SDimitry Andric       TransExprRes = SemaRef.CheckPlaceholderExpr(TransExprRes.get());
268355e4f9d5SDimitry Andric     if (TransExprRes.isInvalid() || Trap.hasErrorOccurred())
26846e75b2fbSDimitry Andric       TransExpr = createSubstDiag(SemaRef, Info, [&](llvm::raw_ostream &OS) {
26856e75b2fbSDimitry Andric         E->printPretty(OS, nullptr, SemaRef.getPrintingPolicy());
268655e4f9d5SDimitry Andric       });
268755e4f9d5SDimitry Andric     else
268855e4f9d5SDimitry Andric       TransExpr = TransExprRes.get();
268955e4f9d5SDimitry Andric   }
269055e4f9d5SDimitry Andric 
2691bdd1243dSDimitry Andric   std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
269255e4f9d5SDimitry Andric   const auto &RetReq = Req->getReturnTypeRequirement();
269355e4f9d5SDimitry Andric   if (RetReq.isEmpty())
269455e4f9d5SDimitry Andric     TransRetReq.emplace();
269555e4f9d5SDimitry Andric   else if (RetReq.isSubstitutionFailure())
269655e4f9d5SDimitry Andric     TransRetReq.emplace(RetReq.getSubstitutionDiagnostic());
269755e4f9d5SDimitry Andric   else if (RetReq.isTypeConstraint()) {
269855e4f9d5SDimitry Andric     TemplateParameterList *OrigTPL =
269955e4f9d5SDimitry Andric         RetReq.getTypeConstraintTemplateParameterList();
27006e75b2fbSDimitry Andric     TemplateDeductionInfo Info(OrigTPL->getTemplateLoc());
270155e4f9d5SDimitry Andric     Sema::InstantiatingTemplate TPLInst(SemaRef, OrigTPL->getTemplateLoc(),
270255e4f9d5SDimitry Andric                                         Req, Info, OrigTPL->getSourceRange());
270355e4f9d5SDimitry Andric     if (TPLInst.isInvalid())
270455e4f9d5SDimitry Andric       return nullptr;
2705bdd1243dSDimitry Andric     TemplateParameterList *TPL = TransformTemplateParameterList(OrigTPL);
27060fca6ea1SDimitry Andric     if (!TPL || Trap.hasErrorOccurred())
270755e4f9d5SDimitry Andric       TransRetReq.emplace(createSubstDiag(SemaRef, Info,
270855e4f9d5SDimitry Andric           [&] (llvm::raw_ostream& OS) {
270955e4f9d5SDimitry Andric               RetReq.getTypeConstraint()->getImmediatelyDeclaredConstraint()
271055e4f9d5SDimitry Andric                   ->printPretty(OS, nullptr, SemaRef.getPrintingPolicy());
271155e4f9d5SDimitry Andric           }));
271255e4f9d5SDimitry Andric     else {
271355e4f9d5SDimitry Andric       TPLInst.Clear();
271455e4f9d5SDimitry Andric       TransRetReq.emplace(TPL);
271555e4f9d5SDimitry Andric     }
271655e4f9d5SDimitry Andric   }
271781ad6265SDimitry Andric   assert(TransRetReq && "All code paths leading here must set TransRetReq");
271855e4f9d5SDimitry Andric   if (Expr *E = TransExpr.dyn_cast<Expr *>())
271955e4f9d5SDimitry Andric     return RebuildExprRequirement(E, Req->isSimple(), Req->getNoexceptLoc(),
272055e4f9d5SDimitry Andric                                   std::move(*TransRetReq));
272155e4f9d5SDimitry Andric   return RebuildExprRequirement(
272255e4f9d5SDimitry Andric       TransExpr.get<concepts::Requirement::SubstitutionDiagnostic *>(),
272355e4f9d5SDimitry Andric       Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
272455e4f9d5SDimitry Andric }
272555e4f9d5SDimitry Andric 
272655e4f9d5SDimitry Andric concepts::NestedRequirement *
272755e4f9d5SDimitry Andric TemplateInstantiator::TransformNestedRequirement(
272855e4f9d5SDimitry Andric     concepts::NestedRequirement *Req) {
272955e4f9d5SDimitry Andric   if (!Req->isDependent() && !AlwaysRebuild())
273055e4f9d5SDimitry Andric     return Req;
2731bdd1243dSDimitry Andric   if (Req->hasInvalidConstraint()) {
273255e4f9d5SDimitry Andric     if (AlwaysRebuild())
2733bdd1243dSDimitry Andric       return RebuildNestedRequirement(Req->getInvalidConstraintEntity(),
2734bdd1243dSDimitry Andric                                       Req->getConstraintSatisfaction());
273555e4f9d5SDimitry Andric     return Req;
273655e4f9d5SDimitry Andric   }
273755e4f9d5SDimitry Andric   Sema::InstantiatingTemplate ReqInst(SemaRef,
273855e4f9d5SDimitry Andric       Req->getConstraintExpr()->getBeginLoc(), Req,
273955e4f9d5SDimitry Andric       Sema::InstantiatingTemplate::ConstraintsCheck{},
274055e4f9d5SDimitry Andric       Req->getConstraintExpr()->getSourceRange());
27411db9f3b2SDimitry Andric   if (!getEvaluateConstraints()) {
27421db9f3b2SDimitry Andric     ExprResult TransConstraint = TransformExpr(Req->getConstraintExpr());
27431db9f3b2SDimitry Andric     if (TransConstraint.isInvalid() || !TransConstraint.get())
27441db9f3b2SDimitry Andric       return nullptr;
27451db9f3b2SDimitry Andric     if (TransConstraint.get()->isInstantiationDependent())
27461db9f3b2SDimitry Andric       return new (SemaRef.Context)
27471db9f3b2SDimitry Andric           concepts::NestedRequirement(TransConstraint.get());
27481db9f3b2SDimitry Andric     ConstraintSatisfaction Satisfaction;
27491db9f3b2SDimitry Andric     return new (SemaRef.Context) concepts::NestedRequirement(
27501db9f3b2SDimitry Andric         SemaRef.Context, TransConstraint.get(), Satisfaction);
27511db9f3b2SDimitry Andric   }
275255e4f9d5SDimitry Andric 
275355e4f9d5SDimitry Andric   ExprResult TransConstraint;
275481ad6265SDimitry Andric   ConstraintSatisfaction Satisfaction;
275555e4f9d5SDimitry Andric   TemplateDeductionInfo Info(Req->getConstraintExpr()->getBeginLoc());
275655e4f9d5SDimitry Andric   {
275755e4f9d5SDimitry Andric     EnterExpressionEvaluationContext ContextRAII(
275855e4f9d5SDimitry Andric         SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
275955e4f9d5SDimitry Andric     Sema::SFINAETrap Trap(SemaRef);
276055e4f9d5SDimitry Andric     Sema::InstantiatingTemplate ConstrInst(SemaRef,
276155e4f9d5SDimitry Andric         Req->getConstraintExpr()->getBeginLoc(), Req, Info,
276255e4f9d5SDimitry Andric         Req->getConstraintExpr()->getSourceRange());
276355e4f9d5SDimitry Andric     if (ConstrInst.isInvalid())
276455e4f9d5SDimitry Andric       return nullptr;
2765bdd1243dSDimitry Andric     llvm::SmallVector<Expr *> Result;
2766bdd1243dSDimitry Andric     if (!SemaRef.CheckConstraintSatisfaction(
2767bdd1243dSDimitry Andric             nullptr, {Req->getConstraintExpr()}, Result, TemplateArgs,
2768bdd1243dSDimitry Andric             Req->getConstraintExpr()->getSourceRange(), Satisfaction) &&
2769bdd1243dSDimitry Andric         !Result.empty())
2770bdd1243dSDimitry Andric       TransConstraint = Result[0];
2771bdd1243dSDimitry Andric     assert(!Trap.hasErrorOccurred() && "Substitution failures must be handled "
2772bdd1243dSDimitry Andric                                        "by CheckConstraintSatisfaction.");
277381ad6265SDimitry Andric   }
27740fca6ea1SDimitry Andric   ASTContext &C = SemaRef.Context;
2775bdd1243dSDimitry Andric   if (TransConstraint.isUsable() &&
2776bdd1243dSDimitry Andric       TransConstraint.get()->isInstantiationDependent())
27770fca6ea1SDimitry Andric     return new (C) concepts::NestedRequirement(TransConstraint.get());
2778bdd1243dSDimitry Andric   if (TransConstraint.isInvalid() || !TransConstraint.get() ||
2779bdd1243dSDimitry Andric       Satisfaction.HasSubstitutionFailure()) {
2780bdd1243dSDimitry Andric     SmallString<128> Entity;
2781bdd1243dSDimitry Andric     llvm::raw_svector_ostream OS(Entity);
2782bdd1243dSDimitry Andric     Req->getConstraintExpr()->printPretty(OS, nullptr,
2783bdd1243dSDimitry Andric                                           SemaRef.getPrintingPolicy());
27840fca6ea1SDimitry Andric     return new (C) concepts::NestedRequirement(
27850fca6ea1SDimitry Andric         SemaRef.Context, C.backupStr(Entity), Satisfaction);
2786bdd1243dSDimitry Andric   }
27870fca6ea1SDimitry Andric   return new (C)
27880fca6ea1SDimitry Andric       concepts::NestedRequirement(C, TransConstraint.get(), Satisfaction);
278955e4f9d5SDimitry Andric }
279055e4f9d5SDimitry Andric 
27910b57cec5SDimitry Andric TypeSourceInfo *Sema::SubstType(TypeSourceInfo *T,
27920b57cec5SDimitry Andric                                 const MultiLevelTemplateArgumentList &Args,
27930b57cec5SDimitry Andric                                 SourceLocation Loc,
27940b57cec5SDimitry Andric                                 DeclarationName Entity,
27950b57cec5SDimitry Andric                                 bool AllowDeducedTST) {
27960b57cec5SDimitry Andric   assert(!CodeSynthesisContexts.empty() &&
27970b57cec5SDimitry Andric          "Cannot perform an instantiation without some context on the "
27980b57cec5SDimitry Andric          "instantiation stack");
27990b57cec5SDimitry Andric 
28000b57cec5SDimitry Andric   if (!T->getType()->isInstantiationDependentType() &&
28010b57cec5SDimitry Andric       !T->getType()->isVariablyModifiedType())
28020b57cec5SDimitry Andric     return T;
28030b57cec5SDimitry Andric 
28040b57cec5SDimitry Andric   TemplateInstantiator Instantiator(*this, Args, Loc, Entity);
28050b57cec5SDimitry Andric   return AllowDeducedTST ? Instantiator.TransformTypeWithDeducedTST(T)
28060b57cec5SDimitry Andric                          : Instantiator.TransformType(T);
28070b57cec5SDimitry Andric }
28080b57cec5SDimitry Andric 
28090b57cec5SDimitry Andric TypeSourceInfo *Sema::SubstType(TypeLoc TL,
28100b57cec5SDimitry Andric                                 const MultiLevelTemplateArgumentList &Args,
28110b57cec5SDimitry Andric                                 SourceLocation Loc,
28120b57cec5SDimitry Andric                                 DeclarationName Entity) {
28130b57cec5SDimitry Andric   assert(!CodeSynthesisContexts.empty() &&
28140b57cec5SDimitry Andric          "Cannot perform an instantiation without some context on the "
28150b57cec5SDimitry Andric          "instantiation stack");
28160b57cec5SDimitry Andric 
28170b57cec5SDimitry Andric   if (TL.getType().isNull())
28180b57cec5SDimitry Andric     return nullptr;
28190b57cec5SDimitry Andric 
28200b57cec5SDimitry Andric   if (!TL.getType()->isInstantiationDependentType() &&
28210b57cec5SDimitry Andric       !TL.getType()->isVariablyModifiedType()) {
28220b57cec5SDimitry Andric     // FIXME: Make a copy of the TypeLoc data here, so that we can
28230b57cec5SDimitry Andric     // return a new TypeSourceInfo. Inefficient!
28240b57cec5SDimitry Andric     TypeLocBuilder TLB;
28250b57cec5SDimitry Andric     TLB.pushFullCopy(TL);
28260b57cec5SDimitry Andric     return TLB.getTypeSourceInfo(Context, TL.getType());
28270b57cec5SDimitry Andric   }
28280b57cec5SDimitry Andric 
28290b57cec5SDimitry Andric   TemplateInstantiator Instantiator(*this, Args, Loc, Entity);
28300b57cec5SDimitry Andric   TypeLocBuilder TLB;
28310b57cec5SDimitry Andric   TLB.reserve(TL.getFullDataSize());
28320b57cec5SDimitry Andric   QualType Result = Instantiator.TransformType(TLB, TL);
28330b57cec5SDimitry Andric   if (Result.isNull())
28340b57cec5SDimitry Andric     return nullptr;
28350b57cec5SDimitry Andric 
28360b57cec5SDimitry Andric   return TLB.getTypeSourceInfo(Context, Result);
28370b57cec5SDimitry Andric }
28380b57cec5SDimitry Andric 
28390b57cec5SDimitry Andric /// Deprecated form of the above.
28400b57cec5SDimitry Andric QualType Sema::SubstType(QualType T,
28410b57cec5SDimitry Andric                          const MultiLevelTemplateArgumentList &TemplateArgs,
28420b57cec5SDimitry Andric                          SourceLocation Loc, DeclarationName Entity) {
28430b57cec5SDimitry Andric   assert(!CodeSynthesisContexts.empty() &&
28440b57cec5SDimitry Andric          "Cannot perform an instantiation without some context on the "
28450b57cec5SDimitry Andric          "instantiation stack");
28460b57cec5SDimitry Andric 
28470b57cec5SDimitry Andric   // If T is not a dependent type or a variably-modified type, there
28480b57cec5SDimitry Andric   // is nothing to do.
28490b57cec5SDimitry Andric   if (!T->isInstantiationDependentType() && !T->isVariablyModifiedType())
28500b57cec5SDimitry Andric     return T;
28510b57cec5SDimitry Andric 
28520b57cec5SDimitry Andric   TemplateInstantiator Instantiator(*this, TemplateArgs, Loc, Entity);
28530b57cec5SDimitry Andric   return Instantiator.TransformType(T);
28540b57cec5SDimitry Andric }
28550b57cec5SDimitry Andric 
28560b57cec5SDimitry Andric static bool NeedsInstantiationAsFunctionType(TypeSourceInfo *T) {
28570b57cec5SDimitry Andric   if (T->getType()->isInstantiationDependentType() ||
28580b57cec5SDimitry Andric       T->getType()->isVariablyModifiedType())
28590b57cec5SDimitry Andric     return true;
28600b57cec5SDimitry Andric 
28610b57cec5SDimitry Andric   TypeLoc TL = T->getTypeLoc().IgnoreParens();
28620b57cec5SDimitry Andric   if (!TL.getAs<FunctionProtoTypeLoc>())
28630b57cec5SDimitry Andric     return false;
28640b57cec5SDimitry Andric 
28650b57cec5SDimitry Andric   FunctionProtoTypeLoc FP = TL.castAs<FunctionProtoTypeLoc>();
28660b57cec5SDimitry Andric   for (ParmVarDecl *P : FP.getParams()) {
28670b57cec5SDimitry Andric     // This must be synthesized from a typedef.
28680b57cec5SDimitry Andric     if (!P) continue;
28690b57cec5SDimitry Andric 
28700b57cec5SDimitry Andric     // If there are any parameters, a new TypeSourceInfo that refers to the
28710b57cec5SDimitry Andric     // instantiated parameters must be built.
28720b57cec5SDimitry Andric     return true;
28730b57cec5SDimitry Andric   }
28740b57cec5SDimitry Andric 
28750b57cec5SDimitry Andric   return false;
28760b57cec5SDimitry Andric }
28770b57cec5SDimitry Andric 
28780b57cec5SDimitry Andric TypeSourceInfo *Sema::SubstFunctionDeclType(TypeSourceInfo *T,
28790b57cec5SDimitry Andric                                 const MultiLevelTemplateArgumentList &Args,
28800b57cec5SDimitry Andric                                 SourceLocation Loc,
28810b57cec5SDimitry Andric                                 DeclarationName Entity,
28820b57cec5SDimitry Andric                                 CXXRecordDecl *ThisContext,
2883bdd1243dSDimitry Andric                                 Qualifiers ThisTypeQuals,
2884bdd1243dSDimitry Andric                                 bool EvaluateConstraints) {
28850b57cec5SDimitry Andric   assert(!CodeSynthesisContexts.empty() &&
28860b57cec5SDimitry Andric          "Cannot perform an instantiation without some context on the "
28870b57cec5SDimitry Andric          "instantiation stack");
28880b57cec5SDimitry Andric 
28890b57cec5SDimitry Andric   if (!NeedsInstantiationAsFunctionType(T))
28900b57cec5SDimitry Andric     return T;
28910b57cec5SDimitry Andric 
28920b57cec5SDimitry Andric   TemplateInstantiator Instantiator(*this, Args, Loc, Entity);
2893bdd1243dSDimitry Andric   Instantiator.setEvaluateConstraints(EvaluateConstraints);
28940b57cec5SDimitry Andric 
28950b57cec5SDimitry Andric   TypeLocBuilder TLB;
28960b57cec5SDimitry Andric 
28970b57cec5SDimitry Andric   TypeLoc TL = T->getTypeLoc();
28980b57cec5SDimitry Andric   TLB.reserve(TL.getFullDataSize());
28990b57cec5SDimitry Andric 
29000b57cec5SDimitry Andric   QualType Result;
29010b57cec5SDimitry Andric 
29020b57cec5SDimitry Andric   if (FunctionProtoTypeLoc Proto =
29030b57cec5SDimitry Andric           TL.IgnoreParens().getAs<FunctionProtoTypeLoc>()) {
29040b57cec5SDimitry Andric     // Instantiate the type, other than its exception specification. The
29050b57cec5SDimitry Andric     // exception specification is instantiated in InitFunctionInstantiation
29060b57cec5SDimitry Andric     // once we've built the FunctionDecl.
29070b57cec5SDimitry Andric     // FIXME: Set the exception specification to EST_Uninstantiated here,
29080b57cec5SDimitry Andric     // instead of rebuilding the function type again later.
29090b57cec5SDimitry Andric     Result = Instantiator.TransformFunctionProtoType(
29100b57cec5SDimitry Andric         TLB, Proto, ThisContext, ThisTypeQuals,
29110b57cec5SDimitry Andric         [](FunctionProtoType::ExceptionSpecInfo &ESI,
29120b57cec5SDimitry Andric            bool &Changed) { return false; });
29130b57cec5SDimitry Andric   } else {
29140b57cec5SDimitry Andric     Result = Instantiator.TransformType(TLB, TL);
29150b57cec5SDimitry Andric   }
29165f757f3fSDimitry Andric   // When there are errors resolving types, clang may use IntTy as a fallback,
29175f757f3fSDimitry Andric   // breaking our assumption that function declarations have function types.
29185f757f3fSDimitry Andric   if (Result.isNull() || !Result->isFunctionType())
29190b57cec5SDimitry Andric     return nullptr;
29200b57cec5SDimitry Andric 
29210b57cec5SDimitry Andric   return TLB.getTypeSourceInfo(Context, Result);
29220b57cec5SDimitry Andric }
29230b57cec5SDimitry Andric 
29240b57cec5SDimitry Andric bool Sema::SubstExceptionSpec(SourceLocation Loc,
29250b57cec5SDimitry Andric                               FunctionProtoType::ExceptionSpecInfo &ESI,
29260b57cec5SDimitry Andric                               SmallVectorImpl<QualType> &ExceptionStorage,
29270b57cec5SDimitry Andric                               const MultiLevelTemplateArgumentList &Args) {
29280b57cec5SDimitry Andric   bool Changed = false;
29290b57cec5SDimitry Andric   TemplateInstantiator Instantiator(*this, Args, Loc, DeclarationName());
29300b57cec5SDimitry Andric   return Instantiator.TransformExceptionSpec(Loc, ESI, ExceptionStorage,
29310b57cec5SDimitry Andric                                              Changed);
29320b57cec5SDimitry Andric }
29330b57cec5SDimitry Andric 
29340b57cec5SDimitry Andric void Sema::SubstExceptionSpec(FunctionDecl *New, const FunctionProtoType *Proto,
29350b57cec5SDimitry Andric                               const MultiLevelTemplateArgumentList &Args) {
29360b57cec5SDimitry Andric   FunctionProtoType::ExceptionSpecInfo ESI =
29370b57cec5SDimitry Andric       Proto->getExtProtoInfo().ExceptionSpec;
29380b57cec5SDimitry Andric 
29390b57cec5SDimitry Andric   SmallVector<QualType, 4> ExceptionStorage;
29400b57cec5SDimitry Andric   if (SubstExceptionSpec(New->getTypeSourceInfo()->getTypeLoc().getEndLoc(),
29410b57cec5SDimitry Andric                          ESI, ExceptionStorage, Args))
29420b57cec5SDimitry Andric     // On error, recover by dropping the exception specification.
29430b57cec5SDimitry Andric     ESI.Type = EST_None;
29440b57cec5SDimitry Andric 
29450b57cec5SDimitry Andric   UpdateExceptionSpec(New, ESI);
29460b57cec5SDimitry Andric }
29470b57cec5SDimitry Andric 
294813138422SDimitry Andric namespace {
294913138422SDimitry Andric 
295013138422SDimitry Andric   struct GetContainedInventedTypeParmVisitor :
295113138422SDimitry Andric     public TypeVisitor<GetContainedInventedTypeParmVisitor,
295213138422SDimitry Andric                        TemplateTypeParmDecl *> {
295313138422SDimitry Andric     using TypeVisitor<GetContainedInventedTypeParmVisitor,
295413138422SDimitry Andric                       TemplateTypeParmDecl *>::Visit;
295513138422SDimitry Andric 
295613138422SDimitry Andric     TemplateTypeParmDecl *Visit(QualType T) {
295713138422SDimitry Andric       if (T.isNull())
295813138422SDimitry Andric         return nullptr;
295913138422SDimitry Andric       return Visit(T.getTypePtr());
296013138422SDimitry Andric     }
296113138422SDimitry Andric     // The deduced type itself.
296213138422SDimitry Andric     TemplateTypeParmDecl *VisitTemplateTypeParmType(
296313138422SDimitry Andric         const TemplateTypeParmType *T) {
2964cd675bb6SDimitry Andric       if (!T->getDecl() || !T->getDecl()->isImplicit())
296513138422SDimitry Andric         return nullptr;
296613138422SDimitry Andric       return T->getDecl();
296713138422SDimitry Andric     }
296813138422SDimitry Andric 
296913138422SDimitry Andric     // Only these types can contain 'auto' types, and subsequently be replaced
297013138422SDimitry Andric     // by references to invented parameters.
297113138422SDimitry Andric 
297213138422SDimitry Andric     TemplateTypeParmDecl *VisitElaboratedType(const ElaboratedType *T) {
297313138422SDimitry Andric       return Visit(T->getNamedType());
297413138422SDimitry Andric     }
297513138422SDimitry Andric 
297613138422SDimitry Andric     TemplateTypeParmDecl *VisitPointerType(const PointerType *T) {
297713138422SDimitry Andric       return Visit(T->getPointeeType());
297813138422SDimitry Andric     }
297913138422SDimitry Andric 
298013138422SDimitry Andric     TemplateTypeParmDecl *VisitBlockPointerType(const BlockPointerType *T) {
298113138422SDimitry Andric       return Visit(T->getPointeeType());
298213138422SDimitry Andric     }
298313138422SDimitry Andric 
298413138422SDimitry Andric     TemplateTypeParmDecl *VisitReferenceType(const ReferenceType *T) {
298513138422SDimitry Andric       return Visit(T->getPointeeTypeAsWritten());
298613138422SDimitry Andric     }
298713138422SDimitry Andric 
298813138422SDimitry Andric     TemplateTypeParmDecl *VisitMemberPointerType(const MemberPointerType *T) {
298913138422SDimitry Andric       return Visit(T->getPointeeType());
299013138422SDimitry Andric     }
299113138422SDimitry Andric 
299213138422SDimitry Andric     TemplateTypeParmDecl *VisitArrayType(const ArrayType *T) {
299313138422SDimitry Andric       return Visit(T->getElementType());
299413138422SDimitry Andric     }
299513138422SDimitry Andric 
299613138422SDimitry Andric     TemplateTypeParmDecl *VisitDependentSizedExtVectorType(
299713138422SDimitry Andric       const DependentSizedExtVectorType *T) {
299813138422SDimitry Andric       return Visit(T->getElementType());
299913138422SDimitry Andric     }
300013138422SDimitry Andric 
300113138422SDimitry Andric     TemplateTypeParmDecl *VisitVectorType(const VectorType *T) {
300213138422SDimitry Andric       return Visit(T->getElementType());
300313138422SDimitry Andric     }
300413138422SDimitry Andric 
300513138422SDimitry Andric     TemplateTypeParmDecl *VisitFunctionProtoType(const FunctionProtoType *T) {
300613138422SDimitry Andric       return VisitFunctionType(T);
300713138422SDimitry Andric     }
300813138422SDimitry Andric 
300913138422SDimitry Andric     TemplateTypeParmDecl *VisitFunctionType(const FunctionType *T) {
301013138422SDimitry Andric       return Visit(T->getReturnType());
301113138422SDimitry Andric     }
301213138422SDimitry Andric 
301313138422SDimitry Andric     TemplateTypeParmDecl *VisitParenType(const ParenType *T) {
301413138422SDimitry Andric       return Visit(T->getInnerType());
301513138422SDimitry Andric     }
301613138422SDimitry Andric 
301713138422SDimitry Andric     TemplateTypeParmDecl *VisitAttributedType(const AttributedType *T) {
301813138422SDimitry Andric       return Visit(T->getModifiedType());
301913138422SDimitry Andric     }
302013138422SDimitry Andric 
302113138422SDimitry Andric     TemplateTypeParmDecl *VisitMacroQualifiedType(const MacroQualifiedType *T) {
302213138422SDimitry Andric       return Visit(T->getUnderlyingType());
302313138422SDimitry Andric     }
302413138422SDimitry Andric 
302513138422SDimitry Andric     TemplateTypeParmDecl *VisitAdjustedType(const AdjustedType *T) {
302613138422SDimitry Andric       return Visit(T->getOriginalType());
302713138422SDimitry Andric     }
302813138422SDimitry Andric 
302913138422SDimitry Andric     TemplateTypeParmDecl *VisitPackExpansionType(const PackExpansionType *T) {
303013138422SDimitry Andric       return Visit(T->getPattern());
303113138422SDimitry Andric     }
303213138422SDimitry Andric   };
303313138422SDimitry Andric 
303413138422SDimitry Andric } // namespace
303513138422SDimitry Andric 
3036349cc55cSDimitry Andric bool Sema::SubstTypeConstraint(
3037349cc55cSDimitry Andric     TemplateTypeParmDecl *Inst, const TypeConstraint *TC,
3038bdd1243dSDimitry Andric     const MultiLevelTemplateArgumentList &TemplateArgs,
3039bdd1243dSDimitry Andric     bool EvaluateConstraints) {
3040349cc55cSDimitry Andric   const ASTTemplateArgumentListInfo *TemplArgInfo =
3041349cc55cSDimitry Andric       TC->getTemplateArgsAsWritten();
3042bdd1243dSDimitry Andric 
3043bdd1243dSDimitry Andric   if (!EvaluateConstraints) {
30445f757f3fSDimitry Andric       Inst->setTypeConstraint(TC->getConceptReference(),
3045bdd1243dSDimitry Andric                               TC->getImmediatelyDeclaredConstraint());
3046bdd1243dSDimitry Andric       return false;
3047bdd1243dSDimitry Andric   }
3048bdd1243dSDimitry Andric 
3049349cc55cSDimitry Andric   TemplateArgumentListInfo InstArgs;
3050349cc55cSDimitry Andric 
3051349cc55cSDimitry Andric   if (TemplArgInfo) {
3052349cc55cSDimitry Andric     InstArgs.setLAngleLoc(TemplArgInfo->LAngleLoc);
3053349cc55cSDimitry Andric     InstArgs.setRAngleLoc(TemplArgInfo->RAngleLoc);
3054349cc55cSDimitry Andric     if (SubstTemplateArguments(TemplArgInfo->arguments(), TemplateArgs,
3055349cc55cSDimitry Andric                                InstArgs))
3056349cc55cSDimitry Andric       return true;
3057349cc55cSDimitry Andric   }
3058349cc55cSDimitry Andric   return AttachTypeConstraint(
3059349cc55cSDimitry Andric       TC->getNestedNameSpecifierLoc(), TC->getConceptNameInfo(),
30600fca6ea1SDimitry Andric       TC->getNamedConcept(),
30610fca6ea1SDimitry Andric       /*FoundDecl=*/TC->getConceptReference()->getFoundDecl(), &InstArgs, Inst,
3062349cc55cSDimitry Andric       Inst->isParameterPack()
3063349cc55cSDimitry Andric           ? cast<CXXFoldExpr>(TC->getImmediatelyDeclaredConstraint())
3064349cc55cSDimitry Andric                 ->getEllipsisLoc()
3065349cc55cSDimitry Andric           : SourceLocation());
3066349cc55cSDimitry Andric }
3067349cc55cSDimitry Andric 
3068bdd1243dSDimitry Andric ParmVarDecl *Sema::SubstParmVarDecl(
3069bdd1243dSDimitry Andric     ParmVarDecl *OldParm, const MultiLevelTemplateArgumentList &TemplateArgs,
3070bdd1243dSDimitry Andric     int indexAdjustment, std::optional<unsigned> NumExpansions,
3071bdd1243dSDimitry Andric     bool ExpectParameterPack, bool EvaluateConstraint) {
30720b57cec5SDimitry Andric   TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
30730b57cec5SDimitry Andric   TypeSourceInfo *NewDI = nullptr;
30740b57cec5SDimitry Andric 
30750b57cec5SDimitry Andric   TypeLoc OldTL = OldDI->getTypeLoc();
30760b57cec5SDimitry Andric   if (PackExpansionTypeLoc ExpansionTL = OldTL.getAs<PackExpansionTypeLoc>()) {
30770b57cec5SDimitry Andric 
30780b57cec5SDimitry Andric     // We have a function parameter pack. Substitute into the pattern of the
30790b57cec5SDimitry Andric     // expansion.
30800b57cec5SDimitry Andric     NewDI = SubstType(ExpansionTL.getPatternLoc(), TemplateArgs,
30810b57cec5SDimitry Andric                       OldParm->getLocation(), OldParm->getDeclName());
30820b57cec5SDimitry Andric     if (!NewDI)
30830b57cec5SDimitry Andric       return nullptr;
30840b57cec5SDimitry Andric 
30850b57cec5SDimitry Andric     if (NewDI->getType()->containsUnexpandedParameterPack()) {
30860b57cec5SDimitry Andric       // We still have unexpanded parameter packs, which means that
30870b57cec5SDimitry Andric       // our function parameter is still a function parameter pack.
30880b57cec5SDimitry Andric       // Therefore, make its type a pack expansion type.
30890b57cec5SDimitry Andric       NewDI = CheckPackExpansion(NewDI, ExpansionTL.getEllipsisLoc(),
30900b57cec5SDimitry Andric                                  NumExpansions);
30910b57cec5SDimitry Andric     } else if (ExpectParameterPack) {
30920b57cec5SDimitry Andric       // We expected to get a parameter pack but didn't (because the type
30930b57cec5SDimitry Andric       // itself is not a pack expansion type), so complain. This can occur when
30940b57cec5SDimitry Andric       // the substitution goes through an alias template that "loses" the
30950b57cec5SDimitry Andric       // pack expansion.
30960b57cec5SDimitry Andric       Diag(OldParm->getLocation(),
30970b57cec5SDimitry Andric            diag::err_function_parameter_pack_without_parameter_packs)
30980b57cec5SDimitry Andric         << NewDI->getType();
30990b57cec5SDimitry Andric       return nullptr;
31000b57cec5SDimitry Andric     }
31010b57cec5SDimitry Andric   } else {
31020b57cec5SDimitry Andric     NewDI = SubstType(OldDI, TemplateArgs, OldParm->getLocation(),
31030b57cec5SDimitry Andric                       OldParm->getDeclName());
31040b57cec5SDimitry Andric   }
31050b57cec5SDimitry Andric 
31060b57cec5SDimitry Andric   if (!NewDI)
31070b57cec5SDimitry Andric     return nullptr;
31080b57cec5SDimitry Andric 
31090b57cec5SDimitry Andric   if (NewDI->getType()->isVoidType()) {
31100b57cec5SDimitry Andric     Diag(OldParm->getLocation(), diag::err_param_with_void_type);
31110b57cec5SDimitry Andric     return nullptr;
31120b57cec5SDimitry Andric   }
31130b57cec5SDimitry Andric 
311413138422SDimitry Andric   // In abbreviated templates, TemplateTypeParmDecls with possible
311513138422SDimitry Andric   // TypeConstraints are created when the parameter list is originally parsed.
311613138422SDimitry Andric   // The TypeConstraints can therefore reference other functions parameters in
311713138422SDimitry Andric   // the abbreviated function template, which is why we must instantiate them
311813138422SDimitry Andric   // here, when the instantiated versions of those referenced parameters are in
311913138422SDimitry Andric   // scope.
312013138422SDimitry Andric   if (TemplateTypeParmDecl *TTP =
312113138422SDimitry Andric           GetContainedInventedTypeParmVisitor().Visit(OldDI->getType())) {
312213138422SDimitry Andric     if (const TypeConstraint *TC = TTP->getTypeConstraint()) {
312313138422SDimitry Andric       auto *Inst = cast_or_null<TemplateTypeParmDecl>(
312413138422SDimitry Andric           FindInstantiatedDecl(TTP->getLocation(), TTP, TemplateArgs));
312513138422SDimitry Andric       // We will first get here when instantiating the abbreviated function
312613138422SDimitry Andric       // template's described function, but we might also get here later.
312713138422SDimitry Andric       // Make sure we do not instantiate the TypeConstraint more than once.
312813138422SDimitry Andric       if (Inst && !Inst->getTypeConstraint()) {
3129bdd1243dSDimitry Andric         if (SubstTypeConstraint(Inst, TC, TemplateArgs, EvaluateConstraint))
313013138422SDimitry Andric           return nullptr;
313113138422SDimitry Andric       }
313213138422SDimitry Andric     }
313313138422SDimitry Andric   }
313413138422SDimitry Andric 
31350b57cec5SDimitry Andric   ParmVarDecl *NewParm = CheckParameter(Context.getTranslationUnitDecl(),
31360b57cec5SDimitry Andric                                         OldParm->getInnerLocStart(),
31370b57cec5SDimitry Andric                                         OldParm->getLocation(),
31380b57cec5SDimitry Andric                                         OldParm->getIdentifier(),
31390b57cec5SDimitry Andric                                         NewDI->getType(), NewDI,
31400b57cec5SDimitry Andric                                         OldParm->getStorageClass());
31410b57cec5SDimitry Andric   if (!NewParm)
31420b57cec5SDimitry Andric     return nullptr;
31430b57cec5SDimitry Andric 
31440b57cec5SDimitry Andric   // Mark the (new) default argument as uninstantiated (if any).
31450b57cec5SDimitry Andric   if (OldParm->hasUninstantiatedDefaultArg()) {
31460b57cec5SDimitry Andric     Expr *Arg = OldParm->getUninstantiatedDefaultArg();
31470b57cec5SDimitry Andric     NewParm->setUninstantiatedDefaultArg(Arg);
31480b57cec5SDimitry Andric   } else if (OldParm->hasUnparsedDefaultArg()) {
31490b57cec5SDimitry Andric     NewParm->setUnparsedDefaultArg();
31500b57cec5SDimitry Andric     UnparsedDefaultArgInstantiations[OldParm].push_back(NewParm);
31510b57cec5SDimitry Andric   } else if (Expr *Arg = OldParm->getDefaultArg()) {
3152bdd1243dSDimitry Andric     // Default arguments cannot be substituted until the declaration context
3153bdd1243dSDimitry Andric     // for the associated function or lambda capture class is available.
3154bdd1243dSDimitry Andric     // This is necessary for cases like the following where construction of
3155bdd1243dSDimitry Andric     // the lambda capture class for the outer lambda is dependent on the
3156bdd1243dSDimitry Andric     // parameter types but where the default argument is dependent on the
3157bdd1243dSDimitry Andric     // outer lambda's declaration context.
3158bdd1243dSDimitry Andric     //   template <typename T>
3159bdd1243dSDimitry Andric     //   auto f() {
3160bdd1243dSDimitry Andric     //     return [](T = []{ return T{}; }()) { return 0; };
3161bdd1243dSDimitry Andric     //   }
31620b57cec5SDimitry Andric     NewParm->setUninstantiatedDefaultArg(Arg);
31630b57cec5SDimitry Andric   }
31640b57cec5SDimitry Andric 
31655f757f3fSDimitry Andric   NewParm->setExplicitObjectParameterLoc(
31665f757f3fSDimitry Andric       OldParm->getExplicitObjectParamThisLoc());
31670b57cec5SDimitry Andric   NewParm->setHasInheritedDefaultArg(OldParm->hasInheritedDefaultArg());
31680b57cec5SDimitry Andric 
31690b57cec5SDimitry Andric   if (OldParm->isParameterPack() && !NewParm->isParameterPack()) {
31700b57cec5SDimitry Andric     // Add the new parameter to the instantiated parameter pack.
31710b57cec5SDimitry Andric     CurrentInstantiationScope->InstantiatedLocalPackArg(OldParm, NewParm);
31720b57cec5SDimitry Andric   } else {
31730b57cec5SDimitry Andric     // Introduce an Old -> New mapping
31740b57cec5SDimitry Andric     CurrentInstantiationScope->InstantiatedLocal(OldParm, NewParm);
31750b57cec5SDimitry Andric   }
31760b57cec5SDimitry Andric 
31770b57cec5SDimitry Andric   // FIXME: OldParm may come from a FunctionProtoType, in which case CurContext
31780b57cec5SDimitry Andric   // can be anything, is this right ?
31790b57cec5SDimitry Andric   NewParm->setDeclContext(CurContext);
31800b57cec5SDimitry Andric 
31810b57cec5SDimitry Andric   NewParm->setScopeInfo(OldParm->getFunctionScopeDepth(),
31820b57cec5SDimitry Andric                         OldParm->getFunctionScopeIndex() + indexAdjustment);
31830b57cec5SDimitry Andric 
31840b57cec5SDimitry Andric   InstantiateAttrs(TemplateArgs, OldParm, NewParm);
31850b57cec5SDimitry Andric 
31860b57cec5SDimitry Andric   return NewParm;
31870b57cec5SDimitry Andric }
31880b57cec5SDimitry Andric 
31890b57cec5SDimitry Andric bool Sema::SubstParmTypes(
31900b57cec5SDimitry Andric     SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
31910b57cec5SDimitry Andric     const FunctionProtoType::ExtParameterInfo *ExtParamInfos,
31920b57cec5SDimitry Andric     const MultiLevelTemplateArgumentList &TemplateArgs,
31930b57cec5SDimitry Andric     SmallVectorImpl<QualType> &ParamTypes,
31940b57cec5SDimitry Andric     SmallVectorImpl<ParmVarDecl *> *OutParams,
31950b57cec5SDimitry Andric     ExtParameterInfoBuilder &ParamInfos) {
31960b57cec5SDimitry Andric   assert(!CodeSynthesisContexts.empty() &&
31970b57cec5SDimitry Andric          "Cannot perform an instantiation without some context on the "
31980b57cec5SDimitry Andric          "instantiation stack");
31990b57cec5SDimitry Andric 
32000b57cec5SDimitry Andric   TemplateInstantiator Instantiator(*this, TemplateArgs, Loc,
32010b57cec5SDimitry Andric                                     DeclarationName());
32020b57cec5SDimitry Andric   return Instantiator.TransformFunctionTypeParams(
32030b57cec5SDimitry Andric       Loc, Params, nullptr, ExtParamInfos, ParamTypes, OutParams, ParamInfos);
32040b57cec5SDimitry Andric }
32050b57cec5SDimitry Andric 
3206bdd1243dSDimitry Andric bool Sema::SubstDefaultArgument(
3207bdd1243dSDimitry Andric     SourceLocation Loc,
3208bdd1243dSDimitry Andric     ParmVarDecl *Param,
3209bdd1243dSDimitry Andric     const MultiLevelTemplateArgumentList &TemplateArgs,
3210bdd1243dSDimitry Andric     bool ForCallExpr) {
3211bdd1243dSDimitry Andric   FunctionDecl *FD = cast<FunctionDecl>(Param->getDeclContext());
3212bdd1243dSDimitry Andric   Expr *PatternExpr = Param->getUninstantiatedDefaultArg();
3213bdd1243dSDimitry Andric 
3214bdd1243dSDimitry Andric   EnterExpressionEvaluationContext EvalContext(
3215bdd1243dSDimitry Andric       *this, ExpressionEvaluationContext::PotentiallyEvaluated, Param);
3216bdd1243dSDimitry Andric 
3217bdd1243dSDimitry Andric   InstantiatingTemplate Inst(*this, Loc, Param, TemplateArgs.getInnermost());
3218bdd1243dSDimitry Andric   if (Inst.isInvalid())
3219bdd1243dSDimitry Andric     return true;
3220bdd1243dSDimitry Andric   if (Inst.isAlreadyInstantiating()) {
3221bdd1243dSDimitry Andric     Diag(Param->getBeginLoc(), diag::err_recursive_default_argument) << FD;
3222bdd1243dSDimitry Andric     Param->setInvalidDecl();
3223bdd1243dSDimitry Andric     return true;
3224bdd1243dSDimitry Andric   }
3225bdd1243dSDimitry Andric 
3226bdd1243dSDimitry Andric   ExprResult Result;
3227bdd1243dSDimitry Andric   {
3228bdd1243dSDimitry Andric     // C++ [dcl.fct.default]p5:
3229bdd1243dSDimitry Andric     //   The names in the [default argument] expression are bound, and
3230bdd1243dSDimitry Andric     //   the semantic constraints are checked, at the point where the
3231bdd1243dSDimitry Andric     //   default argument expression appears.
3232bdd1243dSDimitry Andric     ContextRAII SavedContext(*this, FD);
3233bdd1243dSDimitry Andric     std::unique_ptr<LocalInstantiationScope> LIS;
32340fca6ea1SDimitry Andric     MultiLevelTemplateArgumentList NewTemplateArgs = TemplateArgs;
3235bdd1243dSDimitry Andric 
3236bdd1243dSDimitry Andric     if (ForCallExpr) {
3237bdd1243dSDimitry Andric       // When instantiating a default argument due to use in a call expression,
3238bdd1243dSDimitry Andric       // an instantiation scope that includes the parameters of the callee is
3239bdd1243dSDimitry Andric       // required to satisfy references from the default argument. For example:
3240bdd1243dSDimitry Andric       //   template<typename T> void f(T a, int = decltype(a)());
3241bdd1243dSDimitry Andric       //   void g() { f(0); }
3242bdd1243dSDimitry Andric       LIS = std::make_unique<LocalInstantiationScope>(*this);
3243bdd1243dSDimitry Andric       FunctionDecl *PatternFD = FD->getTemplateInstantiationPattern(
3244bdd1243dSDimitry Andric           /*ForDefinition*/ false);
3245bdd1243dSDimitry Andric       if (addInstantiatedParametersToScope(FD, PatternFD, *LIS, TemplateArgs))
3246bdd1243dSDimitry Andric         return true;
32470fca6ea1SDimitry Andric       const FunctionTemplateDecl *PrimaryTemplate = FD->getPrimaryTemplate();
32480fca6ea1SDimitry Andric       if (PrimaryTemplate && PrimaryTemplate->isOutOfLine()) {
32490fca6ea1SDimitry Andric         TemplateArgumentList *CurrentTemplateArgumentList =
32500fca6ea1SDimitry Andric             TemplateArgumentList::CreateCopy(getASTContext(),
32510fca6ea1SDimitry Andric                                              TemplateArgs.getInnermost());
32520fca6ea1SDimitry Andric         NewTemplateArgs = getTemplateInstantiationArgs(
32530fca6ea1SDimitry Andric             FD, FD->getDeclContext(), /*Final=*/false,
32540fca6ea1SDimitry Andric             CurrentTemplateArgumentList->asArray(), /*RelativeToPrimary=*/true);
32550fca6ea1SDimitry Andric       }
3256bdd1243dSDimitry Andric     }
3257bdd1243dSDimitry Andric 
3258bdd1243dSDimitry Andric     runWithSufficientStackSpace(Loc, [&] {
32590fca6ea1SDimitry Andric       Result = SubstInitializer(PatternExpr, NewTemplateArgs,
3260bdd1243dSDimitry Andric                                 /*DirectInit*/ false);
3261bdd1243dSDimitry Andric     });
3262bdd1243dSDimitry Andric   }
3263bdd1243dSDimitry Andric   if (Result.isInvalid())
3264bdd1243dSDimitry Andric     return true;
3265bdd1243dSDimitry Andric 
3266bdd1243dSDimitry Andric   if (ForCallExpr) {
3267bdd1243dSDimitry Andric     // Check the expression as an initializer for the parameter.
3268bdd1243dSDimitry Andric     InitializedEntity Entity
3269bdd1243dSDimitry Andric       = InitializedEntity::InitializeParameter(Context, Param);
3270bdd1243dSDimitry Andric     InitializationKind Kind = InitializationKind::CreateCopy(
3271bdd1243dSDimitry Andric         Param->getLocation(),
3272bdd1243dSDimitry Andric         /*FIXME:EqualLoc*/ PatternExpr->getBeginLoc());
3273bdd1243dSDimitry Andric     Expr *ResultE = Result.getAs<Expr>();
3274bdd1243dSDimitry Andric 
3275bdd1243dSDimitry Andric     InitializationSequence InitSeq(*this, Entity, Kind, ResultE);
3276bdd1243dSDimitry Andric     Result = InitSeq.Perform(*this, Entity, Kind, ResultE);
3277bdd1243dSDimitry Andric     if (Result.isInvalid())
3278bdd1243dSDimitry Andric       return true;
3279bdd1243dSDimitry Andric 
3280bdd1243dSDimitry Andric     Result =
3281bdd1243dSDimitry Andric         ActOnFinishFullExpr(Result.getAs<Expr>(), Param->getOuterLocStart(),
3282bdd1243dSDimitry Andric                             /*DiscardedValue*/ false);
3283bdd1243dSDimitry Andric   } else {
3284bdd1243dSDimitry Andric     // FIXME: Obtain the source location for the '=' token.
3285bdd1243dSDimitry Andric     SourceLocation EqualLoc = PatternExpr->getBeginLoc();
3286bdd1243dSDimitry Andric     Result = ConvertParamDefaultArgument(Param, Result.getAs<Expr>(), EqualLoc);
3287bdd1243dSDimitry Andric   }
3288bdd1243dSDimitry Andric   if (Result.isInvalid())
3289bdd1243dSDimitry Andric       return true;
3290bdd1243dSDimitry Andric 
3291bdd1243dSDimitry Andric   // Remember the instantiated default argument.
3292bdd1243dSDimitry Andric   Param->setDefaultArg(Result.getAs<Expr>());
3293bdd1243dSDimitry Andric 
3294bdd1243dSDimitry Andric   return false;
3295bdd1243dSDimitry Andric }
3296bdd1243dSDimitry Andric 
32970b57cec5SDimitry Andric bool
32980b57cec5SDimitry Andric Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
32990b57cec5SDimitry Andric                           CXXRecordDecl *Pattern,
33000b57cec5SDimitry Andric                           const MultiLevelTemplateArgumentList &TemplateArgs) {
33010b57cec5SDimitry Andric   bool Invalid = false;
33020b57cec5SDimitry Andric   SmallVector<CXXBaseSpecifier*, 4> InstantiatedBases;
33030b57cec5SDimitry Andric   for (const auto &Base : Pattern->bases()) {
33040b57cec5SDimitry Andric     if (!Base.getType()->isDependentType()) {
33050b57cec5SDimitry Andric       if (const CXXRecordDecl *RD = Base.getType()->getAsCXXRecordDecl()) {
33060b57cec5SDimitry Andric         if (RD->isInvalidDecl())
33070b57cec5SDimitry Andric           Instantiation->setInvalidDecl();
33080b57cec5SDimitry Andric       }
33090b57cec5SDimitry Andric       InstantiatedBases.push_back(new (Context) CXXBaseSpecifier(Base));
33100b57cec5SDimitry Andric       continue;
33110b57cec5SDimitry Andric     }
33120b57cec5SDimitry Andric 
33130b57cec5SDimitry Andric     SourceLocation EllipsisLoc;
33140b57cec5SDimitry Andric     TypeSourceInfo *BaseTypeLoc;
33150b57cec5SDimitry Andric     if (Base.isPackExpansion()) {
33160b57cec5SDimitry Andric       // This is a pack expansion. See whether we should expand it now, or
33170b57cec5SDimitry Andric       // wait until later.
33180b57cec5SDimitry Andric       SmallVector<UnexpandedParameterPack, 2> Unexpanded;
33190b57cec5SDimitry Andric       collectUnexpandedParameterPacks(Base.getTypeSourceInfo()->getTypeLoc(),
33200b57cec5SDimitry Andric                                       Unexpanded);
33210b57cec5SDimitry Andric       bool ShouldExpand = false;
33220b57cec5SDimitry Andric       bool RetainExpansion = false;
3323bdd1243dSDimitry Andric       std::optional<unsigned> NumExpansions;
33240b57cec5SDimitry Andric       if (CheckParameterPacksForExpansion(Base.getEllipsisLoc(),
33250b57cec5SDimitry Andric                                           Base.getSourceRange(),
33260b57cec5SDimitry Andric                                           Unexpanded,
33270b57cec5SDimitry Andric                                           TemplateArgs, ShouldExpand,
33280b57cec5SDimitry Andric                                           RetainExpansion,
33290b57cec5SDimitry Andric                                           NumExpansions)) {
33300b57cec5SDimitry Andric         Invalid = true;
33310b57cec5SDimitry Andric         continue;
33320b57cec5SDimitry Andric       }
33330b57cec5SDimitry Andric 
33340b57cec5SDimitry Andric       // If we should expand this pack expansion now, do so.
33350b57cec5SDimitry Andric       if (ShouldExpand) {
33360b57cec5SDimitry Andric         for (unsigned I = 0; I != *NumExpansions; ++I) {
33370b57cec5SDimitry Andric             Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, I);
33380b57cec5SDimitry Andric 
33390b57cec5SDimitry Andric           TypeSourceInfo *BaseTypeLoc = SubstType(Base.getTypeSourceInfo(),
33400b57cec5SDimitry Andric                                                   TemplateArgs,
33410b57cec5SDimitry Andric                                               Base.getSourceRange().getBegin(),
33420b57cec5SDimitry Andric                                                   DeclarationName());
33430b57cec5SDimitry Andric           if (!BaseTypeLoc) {
33440b57cec5SDimitry Andric             Invalid = true;
33450b57cec5SDimitry Andric             continue;
33460b57cec5SDimitry Andric           }
33470b57cec5SDimitry Andric 
33480b57cec5SDimitry Andric           if (CXXBaseSpecifier *InstantiatedBase
33490b57cec5SDimitry Andric                 = CheckBaseSpecifier(Instantiation,
33500b57cec5SDimitry Andric                                      Base.getSourceRange(),
33510b57cec5SDimitry Andric                                      Base.isVirtual(),
33520b57cec5SDimitry Andric                                      Base.getAccessSpecifierAsWritten(),
33530b57cec5SDimitry Andric                                      BaseTypeLoc,
33540b57cec5SDimitry Andric                                      SourceLocation()))
33550b57cec5SDimitry Andric             InstantiatedBases.push_back(InstantiatedBase);
33560b57cec5SDimitry Andric           else
33570b57cec5SDimitry Andric             Invalid = true;
33580b57cec5SDimitry Andric         }
33590b57cec5SDimitry Andric 
33600b57cec5SDimitry Andric         continue;
33610b57cec5SDimitry Andric       }
33620b57cec5SDimitry Andric 
33630b57cec5SDimitry Andric       // The resulting base specifier will (still) be a pack expansion.
33640b57cec5SDimitry Andric       EllipsisLoc = Base.getEllipsisLoc();
33650b57cec5SDimitry Andric       Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, -1);
33660b57cec5SDimitry Andric       BaseTypeLoc = SubstType(Base.getTypeSourceInfo(),
33670b57cec5SDimitry Andric                               TemplateArgs,
33680b57cec5SDimitry Andric                               Base.getSourceRange().getBegin(),
33690b57cec5SDimitry Andric                               DeclarationName());
33700b57cec5SDimitry Andric     } else {
33710b57cec5SDimitry Andric       BaseTypeLoc = SubstType(Base.getTypeSourceInfo(),
33720b57cec5SDimitry Andric                               TemplateArgs,
33730b57cec5SDimitry Andric                               Base.getSourceRange().getBegin(),
33740b57cec5SDimitry Andric                               DeclarationName());
33750b57cec5SDimitry Andric     }
33760b57cec5SDimitry Andric 
33770b57cec5SDimitry Andric     if (!BaseTypeLoc) {
33780b57cec5SDimitry Andric       Invalid = true;
33790b57cec5SDimitry Andric       continue;
33800b57cec5SDimitry Andric     }
33810b57cec5SDimitry Andric 
33820b57cec5SDimitry Andric     if (CXXBaseSpecifier *InstantiatedBase
33830b57cec5SDimitry Andric           = CheckBaseSpecifier(Instantiation,
33840b57cec5SDimitry Andric                                Base.getSourceRange(),
33850b57cec5SDimitry Andric                                Base.isVirtual(),
33860b57cec5SDimitry Andric                                Base.getAccessSpecifierAsWritten(),
33870b57cec5SDimitry Andric                                BaseTypeLoc,
33880b57cec5SDimitry Andric                                EllipsisLoc))
33890b57cec5SDimitry Andric       InstantiatedBases.push_back(InstantiatedBase);
33900b57cec5SDimitry Andric     else
33910b57cec5SDimitry Andric       Invalid = true;
33920b57cec5SDimitry Andric   }
33930b57cec5SDimitry Andric 
33940b57cec5SDimitry Andric   if (!Invalid && AttachBaseSpecifiers(Instantiation, InstantiatedBases))
33950b57cec5SDimitry Andric     Invalid = true;
33960b57cec5SDimitry Andric 
33970b57cec5SDimitry Andric   return Invalid;
33980b57cec5SDimitry Andric }
33990b57cec5SDimitry Andric 
34000b57cec5SDimitry Andric // Defined via #include from SemaTemplateInstantiateDecl.cpp
34010b57cec5SDimitry Andric namespace clang {
34020b57cec5SDimitry Andric   namespace sema {
34030b57cec5SDimitry Andric     Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C, Sema &S,
34040b57cec5SDimitry Andric                             const MultiLevelTemplateArgumentList &TemplateArgs);
34050b57cec5SDimitry Andric     Attr *instantiateTemplateAttributeForDecl(
34060b57cec5SDimitry Andric         const Attr *At, ASTContext &C, Sema &S,
34070b57cec5SDimitry Andric         const MultiLevelTemplateArgumentList &TemplateArgs);
34080b57cec5SDimitry Andric   }
34090b57cec5SDimitry Andric }
34100b57cec5SDimitry Andric 
34110b57cec5SDimitry Andric bool
34120b57cec5SDimitry Andric Sema::InstantiateClass(SourceLocation PointOfInstantiation,
34130b57cec5SDimitry Andric                        CXXRecordDecl *Instantiation, CXXRecordDecl *Pattern,
34140b57cec5SDimitry Andric                        const MultiLevelTemplateArgumentList &TemplateArgs,
34150b57cec5SDimitry Andric                        TemplateSpecializationKind TSK,
34160b57cec5SDimitry Andric                        bool Complain) {
34170b57cec5SDimitry Andric   CXXRecordDecl *PatternDef
34180b57cec5SDimitry Andric     = cast_or_null<CXXRecordDecl>(Pattern->getDefinition());
34190b57cec5SDimitry Andric   if (DiagnoseUninstantiableTemplate(PointOfInstantiation, Instantiation,
34200b57cec5SDimitry Andric                                 Instantiation->getInstantiatedFromMemberClass(),
34210b57cec5SDimitry Andric                                      Pattern, PatternDef, TSK, Complain))
34220b57cec5SDimitry Andric     return true;
34230b57cec5SDimitry Andric 
34240b57cec5SDimitry Andric   llvm::TimeTraceScope TimeScope("InstantiateClass", [&]() {
34250fca6ea1SDimitry Andric     llvm::TimeTraceMetadata M;
34260fca6ea1SDimitry Andric     llvm::raw_string_ostream OS(M.Detail);
34270b57cec5SDimitry Andric     Instantiation->getNameForDiagnostic(OS, getPrintingPolicy(),
34280b57cec5SDimitry Andric                                         /*Qualified=*/true);
34290fca6ea1SDimitry Andric     if (llvm::isTimeTraceVerbose()) {
34300fca6ea1SDimitry Andric       auto Loc = SourceMgr.getExpansionLoc(Instantiation->getLocation());
34310fca6ea1SDimitry Andric       M.File = SourceMgr.getFilename(Loc);
34320fca6ea1SDimitry Andric       M.Line = SourceMgr.getExpansionLineNumber(Loc);
34330fca6ea1SDimitry Andric     }
34340fca6ea1SDimitry Andric     return M;
34350b57cec5SDimitry Andric   });
34360b57cec5SDimitry Andric 
34370b57cec5SDimitry Andric   Pattern = PatternDef;
34380b57cec5SDimitry Andric 
34390b57cec5SDimitry Andric   // Record the point of instantiation.
34400b57cec5SDimitry Andric   if (MemberSpecializationInfo *MSInfo
34410b57cec5SDimitry Andric         = Instantiation->getMemberSpecializationInfo()) {
34420b57cec5SDimitry Andric     MSInfo->setTemplateSpecializationKind(TSK);
34430b57cec5SDimitry Andric     MSInfo->setPointOfInstantiation(PointOfInstantiation);
34440b57cec5SDimitry Andric   } else if (ClassTemplateSpecializationDecl *Spec
34450b57cec5SDimitry Andric         = dyn_cast<ClassTemplateSpecializationDecl>(Instantiation)) {
34460b57cec5SDimitry Andric     Spec->setTemplateSpecializationKind(TSK);
34470b57cec5SDimitry Andric     Spec->setPointOfInstantiation(PointOfInstantiation);
34480b57cec5SDimitry Andric   }
34490b57cec5SDimitry Andric 
34500b57cec5SDimitry Andric   InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);
34510b57cec5SDimitry Andric   if (Inst.isInvalid())
34520b57cec5SDimitry Andric     return true;
34530b57cec5SDimitry Andric   assert(!Inst.isAlreadyInstantiating() && "should have been caught by caller");
34540b57cec5SDimitry Andric   PrettyDeclStackTraceEntry CrashInfo(Context, Instantiation, SourceLocation(),
34550b57cec5SDimitry Andric                                       "instantiating class definition");
34560b57cec5SDimitry Andric 
34570b57cec5SDimitry Andric   // Enter the scope of this instantiation. We don't use
34580b57cec5SDimitry Andric   // PushDeclContext because we don't have a scope.
34590b57cec5SDimitry Andric   ContextRAII SavedContext(*this, Instantiation);
34600b57cec5SDimitry Andric   EnterExpressionEvaluationContext EvalContext(
34610b57cec5SDimitry Andric       *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
34620b57cec5SDimitry Andric 
34630b57cec5SDimitry Andric   // If this is an instantiation of a local class, merge this local
34640b57cec5SDimitry Andric   // instantiation scope with the enclosing scope. Otherwise, every
34650b57cec5SDimitry Andric   // instantiation of a class has its own local instantiation scope.
34660b57cec5SDimitry Andric   bool MergeWithParentScope = !Instantiation->isDefinedOutsideFunctionOrMethod();
34670b57cec5SDimitry Andric   LocalInstantiationScope Scope(*this, MergeWithParentScope);
34680b57cec5SDimitry Andric 
34690b57cec5SDimitry Andric   // Some class state isn't processed immediately but delayed till class
34700b57cec5SDimitry Andric   // instantiation completes. We may not be ready to handle any delayed state
34710b57cec5SDimitry Andric   // already on the stack as it might correspond to a different class, so save
34720b57cec5SDimitry Andric   // it now and put it back later.
34730b57cec5SDimitry Andric   SavePendingParsedClassStateRAII SavedPendingParsedClassState(*this);
34740b57cec5SDimitry Andric 
34750b57cec5SDimitry Andric   // Pull attributes from the pattern onto the instantiation.
34760b57cec5SDimitry Andric   InstantiateAttrs(TemplateArgs, Pattern, Instantiation);
34770b57cec5SDimitry Andric 
34780b57cec5SDimitry Andric   // Start the definition of this instantiation.
34790b57cec5SDimitry Andric   Instantiation->startDefinition();
34800b57cec5SDimitry Andric 
34810b57cec5SDimitry Andric   // The instantiation is visible here, even if it was first declared in an
34820b57cec5SDimitry Andric   // unimported module.
34830b57cec5SDimitry Andric   Instantiation->setVisibleDespiteOwningModule();
34840b57cec5SDimitry Andric 
34850b57cec5SDimitry Andric   // FIXME: This loses the as-written tag kind for an explicit instantiation.
34860b57cec5SDimitry Andric   Instantiation->setTagKind(Pattern->getTagKind());
34870b57cec5SDimitry Andric 
34880b57cec5SDimitry Andric   // Do substitution on the base class specifiers.
34890b57cec5SDimitry Andric   if (SubstBaseSpecifiers(Instantiation, Pattern, TemplateArgs))
34900b57cec5SDimitry Andric     Instantiation->setInvalidDecl();
34910b57cec5SDimitry Andric 
34920b57cec5SDimitry Andric   TemplateDeclInstantiator Instantiator(*this, Instantiation, TemplateArgs);
3493bdd1243dSDimitry Andric   Instantiator.setEvaluateConstraints(false);
34940b57cec5SDimitry Andric   SmallVector<Decl*, 4> Fields;
34950b57cec5SDimitry Andric   // Delay instantiation of late parsed attributes.
34960b57cec5SDimitry Andric   LateInstantiatedAttrVec LateAttrs;
34970b57cec5SDimitry Andric   Instantiator.enableLateAttributeInstantiation(&LateAttrs);
34980b57cec5SDimitry Andric 
34990b57cec5SDimitry Andric   bool MightHaveConstexprVirtualFunctions = false;
35000b57cec5SDimitry Andric   for (auto *Member : Pattern->decls()) {
35010b57cec5SDimitry Andric     // Don't instantiate members not belonging in this semantic context.
35020b57cec5SDimitry Andric     // e.g. for:
35030b57cec5SDimitry Andric     // @code
35040b57cec5SDimitry Andric     //    template <int i> class A {
35050b57cec5SDimitry Andric     //      class B *g;
35060b57cec5SDimitry Andric     //    };
35070b57cec5SDimitry Andric     // @endcode
35080b57cec5SDimitry Andric     // 'class B' has the template as lexical context but semantically it is
35090b57cec5SDimitry Andric     // introduced in namespace scope.
35100b57cec5SDimitry Andric     if (Member->getDeclContext() != Pattern)
35110b57cec5SDimitry Andric       continue;
35120b57cec5SDimitry Andric 
35130b57cec5SDimitry Andric     // BlockDecls can appear in a default-member-initializer. They must be the
35140b57cec5SDimitry Andric     // child of a BlockExpr, so we only know how to instantiate them from there.
3515e8d8bef9SDimitry Andric     // Similarly, lambda closure types are recreated when instantiating the
3516e8d8bef9SDimitry Andric     // corresponding LambdaExpr.
3517e8d8bef9SDimitry Andric     if (isa<BlockDecl>(Member) ||
3518e8d8bef9SDimitry Andric         (isa<CXXRecordDecl>(Member) && cast<CXXRecordDecl>(Member)->isLambda()))
35190b57cec5SDimitry Andric       continue;
35200b57cec5SDimitry Andric 
35210b57cec5SDimitry Andric     if (Member->isInvalidDecl()) {
35220b57cec5SDimitry Andric       Instantiation->setInvalidDecl();
35230b57cec5SDimitry Andric       continue;
35240b57cec5SDimitry Andric     }
35250b57cec5SDimitry Andric 
35260b57cec5SDimitry Andric     Decl *NewMember = Instantiator.Visit(Member);
35270b57cec5SDimitry Andric     if (NewMember) {
35280b57cec5SDimitry Andric       if (FieldDecl *Field = dyn_cast<FieldDecl>(NewMember)) {
35290b57cec5SDimitry Andric         Fields.push_back(Field);
35300b57cec5SDimitry Andric       } else if (EnumDecl *Enum = dyn_cast<EnumDecl>(NewMember)) {
35310b57cec5SDimitry Andric         // C++11 [temp.inst]p1: The implicit instantiation of a class template
35320b57cec5SDimitry Andric         // specialization causes the implicit instantiation of the definitions
35330b57cec5SDimitry Andric         // of unscoped member enumerations.
35340b57cec5SDimitry Andric         // Record a point of instantiation for this implicit instantiation.
35350b57cec5SDimitry Andric         if (TSK == TSK_ImplicitInstantiation && !Enum->isScoped() &&
35360b57cec5SDimitry Andric             Enum->isCompleteDefinition()) {
35370b57cec5SDimitry Andric           MemberSpecializationInfo *MSInfo =Enum->getMemberSpecializationInfo();
35380b57cec5SDimitry Andric           assert(MSInfo && "no spec info for member enum specialization");
35390b57cec5SDimitry Andric           MSInfo->setTemplateSpecializationKind(TSK_ImplicitInstantiation);
35400b57cec5SDimitry Andric           MSInfo->setPointOfInstantiation(PointOfInstantiation);
35410b57cec5SDimitry Andric         }
35420b57cec5SDimitry Andric       } else if (StaticAssertDecl *SA = dyn_cast<StaticAssertDecl>(NewMember)) {
35430b57cec5SDimitry Andric         if (SA->isFailed()) {
35440b57cec5SDimitry Andric           // A static_assert failed. Bail out; instantiating this
35450b57cec5SDimitry Andric           // class is probably not meaningful.
35460b57cec5SDimitry Andric           Instantiation->setInvalidDecl();
35470b57cec5SDimitry Andric           break;
35480b57cec5SDimitry Andric         }
35490b57cec5SDimitry Andric       } else if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewMember)) {
35500b57cec5SDimitry Andric         if (MD->isConstexpr() && !MD->getFriendObjectKind() &&
35510b57cec5SDimitry Andric             (MD->isVirtualAsWritten() || Instantiation->getNumBases()))
35520b57cec5SDimitry Andric           MightHaveConstexprVirtualFunctions = true;
35530b57cec5SDimitry Andric       }
35540b57cec5SDimitry Andric 
35550b57cec5SDimitry Andric       if (NewMember->isInvalidDecl())
35560b57cec5SDimitry Andric         Instantiation->setInvalidDecl();
35570b57cec5SDimitry Andric     } else {
35580b57cec5SDimitry Andric       // FIXME: Eventually, a NULL return will mean that one of the
35590b57cec5SDimitry Andric       // instantiations was a semantic disaster, and we'll want to mark the
35600b57cec5SDimitry Andric       // declaration invalid.
35610b57cec5SDimitry Andric       // For now, we expect to skip some members that we can't yet handle.
35620b57cec5SDimitry Andric     }
35630b57cec5SDimitry Andric   }
35640b57cec5SDimitry Andric 
35650b57cec5SDimitry Andric   // Finish checking fields.
35660b57cec5SDimitry Andric   ActOnFields(nullptr, Instantiation->getLocation(), Instantiation, Fields,
35670b57cec5SDimitry Andric               SourceLocation(), SourceLocation(), ParsedAttributesView());
3568480093f4SDimitry Andric   CheckCompletedCXXClass(nullptr, Instantiation);
35690b57cec5SDimitry Andric 
35700b57cec5SDimitry Andric   // Default arguments are parsed, if not instantiated. We can go instantiate
3571480093f4SDimitry Andric   // default arg exprs for default constructors if necessary now. Unless we're
3572480093f4SDimitry Andric   // parsing a class, in which case wait until that's finished.
3573480093f4SDimitry Andric   if (ParsingClassDepth == 0)
3574480093f4SDimitry Andric     ActOnFinishCXXNonNestedClass();
35750b57cec5SDimitry Andric 
35760b57cec5SDimitry Andric   // Instantiate late parsed attributes, and attach them to their decls.
35770b57cec5SDimitry Andric   // See Sema::InstantiateAttrs
35780b57cec5SDimitry Andric   for (LateInstantiatedAttrVec::iterator I = LateAttrs.begin(),
35790b57cec5SDimitry Andric        E = LateAttrs.end(); I != E; ++I) {
35800b57cec5SDimitry Andric     assert(CurrentInstantiationScope == Instantiator.getStartingScope());
35810b57cec5SDimitry Andric     CurrentInstantiationScope = I->Scope;
35820b57cec5SDimitry Andric 
35830b57cec5SDimitry Andric     // Allow 'this' within late-parsed attributes.
358404eeddc0SDimitry Andric     auto *ND = cast<NamedDecl>(I->NewDecl);
358504eeddc0SDimitry Andric     auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext());
35860b57cec5SDimitry Andric     CXXThisScopeRAII ThisScope(*this, ThisContext, Qualifiers(),
358704eeddc0SDimitry Andric                                ND->isCXXInstanceMember());
35880b57cec5SDimitry Andric 
35890b57cec5SDimitry Andric     Attr *NewAttr =
35900b57cec5SDimitry Andric       instantiateTemplateAttribute(I->TmplAttr, Context, *this, TemplateArgs);
3591e8d8bef9SDimitry Andric     if (NewAttr)
35920b57cec5SDimitry Andric       I->NewDecl->addAttr(NewAttr);
35930b57cec5SDimitry Andric     LocalInstantiationScope::deleteScopes(I->Scope,
35940b57cec5SDimitry Andric                                           Instantiator.getStartingScope());
35950b57cec5SDimitry Andric   }
35960b57cec5SDimitry Andric   Instantiator.disableLateAttributeInstantiation();
35970b57cec5SDimitry Andric   LateAttrs.clear();
35980b57cec5SDimitry Andric 
35990b57cec5SDimitry Andric   ActOnFinishDelayedMemberInitializers(Instantiation);
36000b57cec5SDimitry Andric 
36010b57cec5SDimitry Andric   // FIXME: We should do something similar for explicit instantiations so they
36020b57cec5SDimitry Andric   // end up in the right module.
36030b57cec5SDimitry Andric   if (TSK == TSK_ImplicitInstantiation) {
36040b57cec5SDimitry Andric     Instantiation->setLocation(Pattern->getLocation());
36050b57cec5SDimitry Andric     Instantiation->setLocStart(Pattern->getInnerLocStart());
36060b57cec5SDimitry Andric     Instantiation->setBraceRange(Pattern->getBraceRange());
36070b57cec5SDimitry Andric   }
36080b57cec5SDimitry Andric 
36090b57cec5SDimitry Andric   if (!Instantiation->isInvalidDecl()) {
36100b57cec5SDimitry Andric     // Perform any dependent diagnostics from the pattern.
3611fe6060f1SDimitry Andric     if (Pattern->isDependentContext())
36120b57cec5SDimitry Andric       PerformDependentDiagnostics(Pattern, TemplateArgs);
36130b57cec5SDimitry Andric 
36140b57cec5SDimitry Andric     // Instantiate any out-of-line class template partial
36150b57cec5SDimitry Andric     // specializations now.
36160b57cec5SDimitry Andric     for (TemplateDeclInstantiator::delayed_partial_spec_iterator
36170b57cec5SDimitry Andric               P = Instantiator.delayed_partial_spec_begin(),
36180b57cec5SDimitry Andric            PEnd = Instantiator.delayed_partial_spec_end();
36190b57cec5SDimitry Andric          P != PEnd; ++P) {
36200b57cec5SDimitry Andric       if (!Instantiator.InstantiateClassTemplatePartialSpecialization(
36210b57cec5SDimitry Andric               P->first, P->second)) {
36220b57cec5SDimitry Andric         Instantiation->setInvalidDecl();
36230b57cec5SDimitry Andric         break;
36240b57cec5SDimitry Andric       }
36250b57cec5SDimitry Andric     }
36260b57cec5SDimitry Andric 
36270b57cec5SDimitry Andric     // Instantiate any out-of-line variable template partial
36280b57cec5SDimitry Andric     // specializations now.
36290b57cec5SDimitry Andric     for (TemplateDeclInstantiator::delayed_var_partial_spec_iterator
36300b57cec5SDimitry Andric               P = Instantiator.delayed_var_partial_spec_begin(),
36310b57cec5SDimitry Andric            PEnd = Instantiator.delayed_var_partial_spec_end();
36320b57cec5SDimitry Andric          P != PEnd; ++P) {
36330b57cec5SDimitry Andric       if (!Instantiator.InstantiateVarTemplatePartialSpecialization(
36340b57cec5SDimitry Andric               P->first, P->second)) {
36350b57cec5SDimitry Andric         Instantiation->setInvalidDecl();
36360b57cec5SDimitry Andric         break;
36370b57cec5SDimitry Andric       }
36380b57cec5SDimitry Andric     }
36390b57cec5SDimitry Andric   }
36400b57cec5SDimitry Andric 
36410b57cec5SDimitry Andric   // Exit the scope of this instantiation.
36420b57cec5SDimitry Andric   SavedContext.pop();
36430b57cec5SDimitry Andric 
36440b57cec5SDimitry Andric   if (!Instantiation->isInvalidDecl()) {
36450b57cec5SDimitry Andric     // Always emit the vtable for an explicit instantiation definition
36460b57cec5SDimitry Andric     // of a polymorphic class template specialization. Otherwise, eagerly
36470b57cec5SDimitry Andric     // instantiate only constexpr virtual functions in preparation for their use
36480b57cec5SDimitry Andric     // in constant evaluation.
36490b57cec5SDimitry Andric     if (TSK == TSK_ExplicitInstantiationDefinition)
36500b57cec5SDimitry Andric       MarkVTableUsed(PointOfInstantiation, Instantiation, true);
36510b57cec5SDimitry Andric     else if (MightHaveConstexprVirtualFunctions)
36520b57cec5SDimitry Andric       MarkVirtualMembersReferenced(PointOfInstantiation, Instantiation,
36530b57cec5SDimitry Andric                                    /*ConstexprOnly*/ true);
36540b57cec5SDimitry Andric   }
36550b57cec5SDimitry Andric 
3656e8d8bef9SDimitry Andric   Consumer.HandleTagDeclDefinition(Instantiation);
3657e8d8bef9SDimitry Andric 
36580b57cec5SDimitry Andric   return Instantiation->isInvalidDecl();
36590b57cec5SDimitry Andric }
36600b57cec5SDimitry Andric 
36610b57cec5SDimitry Andric bool Sema::InstantiateEnum(SourceLocation PointOfInstantiation,
36620b57cec5SDimitry Andric                            EnumDecl *Instantiation, EnumDecl *Pattern,
36630b57cec5SDimitry Andric                            const MultiLevelTemplateArgumentList &TemplateArgs,
36640b57cec5SDimitry Andric                            TemplateSpecializationKind TSK) {
36650b57cec5SDimitry Andric   EnumDecl *PatternDef = Pattern->getDefinition();
36660b57cec5SDimitry Andric   if (DiagnoseUninstantiableTemplate(PointOfInstantiation, Instantiation,
36670b57cec5SDimitry Andric                                  Instantiation->getInstantiatedFromMemberEnum(),
36680b57cec5SDimitry Andric                                      Pattern, PatternDef, TSK,/*Complain*/true))
36690b57cec5SDimitry Andric     return true;
36700b57cec5SDimitry Andric   Pattern = PatternDef;
36710b57cec5SDimitry Andric 
36720b57cec5SDimitry Andric   // Record the point of instantiation.
36730b57cec5SDimitry Andric   if (MemberSpecializationInfo *MSInfo
36740b57cec5SDimitry Andric         = Instantiation->getMemberSpecializationInfo()) {
36750b57cec5SDimitry Andric     MSInfo->setTemplateSpecializationKind(TSK);
36760b57cec5SDimitry Andric     MSInfo->setPointOfInstantiation(PointOfInstantiation);
36770b57cec5SDimitry Andric   }
36780b57cec5SDimitry Andric 
36790b57cec5SDimitry Andric   InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);
36800b57cec5SDimitry Andric   if (Inst.isInvalid())
36810b57cec5SDimitry Andric     return true;
36820b57cec5SDimitry Andric   if (Inst.isAlreadyInstantiating())
36830b57cec5SDimitry Andric     return false;
36840b57cec5SDimitry Andric   PrettyDeclStackTraceEntry CrashInfo(Context, Instantiation, SourceLocation(),
36850b57cec5SDimitry Andric                                       "instantiating enum definition");
36860b57cec5SDimitry Andric 
36870b57cec5SDimitry Andric   // The instantiation is visible here, even if it was first declared in an
36880b57cec5SDimitry Andric   // unimported module.
36890b57cec5SDimitry Andric   Instantiation->setVisibleDespiteOwningModule();
36900b57cec5SDimitry Andric 
36910b57cec5SDimitry Andric   // Enter the scope of this instantiation. We don't use
36920b57cec5SDimitry Andric   // PushDeclContext because we don't have a scope.
36930b57cec5SDimitry Andric   ContextRAII SavedContext(*this, Instantiation);
36940b57cec5SDimitry Andric   EnterExpressionEvaluationContext EvalContext(
36950b57cec5SDimitry Andric       *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
36960b57cec5SDimitry Andric 
36970b57cec5SDimitry Andric   LocalInstantiationScope Scope(*this, /*MergeWithParentScope*/true);
36980b57cec5SDimitry Andric 
36990b57cec5SDimitry Andric   // Pull attributes from the pattern onto the instantiation.
37000b57cec5SDimitry Andric   InstantiateAttrs(TemplateArgs, Pattern, Instantiation);
37010b57cec5SDimitry Andric 
37020b57cec5SDimitry Andric   TemplateDeclInstantiator Instantiator(*this, Instantiation, TemplateArgs);
37030b57cec5SDimitry Andric   Instantiator.InstantiateEnumDefinition(Instantiation, Pattern);
37040b57cec5SDimitry Andric 
37050b57cec5SDimitry Andric   // Exit the scope of this instantiation.
37060b57cec5SDimitry Andric   SavedContext.pop();
37070b57cec5SDimitry Andric 
37080b57cec5SDimitry Andric   return Instantiation->isInvalidDecl();
37090b57cec5SDimitry Andric }
37100b57cec5SDimitry Andric 
37110b57cec5SDimitry Andric bool Sema::InstantiateInClassInitializer(
37120b57cec5SDimitry Andric     SourceLocation PointOfInstantiation, FieldDecl *Instantiation,
37130b57cec5SDimitry Andric     FieldDecl *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs) {
37140b57cec5SDimitry Andric   // If there is no initializer, we don't need to do anything.
37150b57cec5SDimitry Andric   if (!Pattern->hasInClassInitializer())
37160b57cec5SDimitry Andric     return false;
37170b57cec5SDimitry Andric 
37180b57cec5SDimitry Andric   assert(Instantiation->getInClassInitStyle() ==
37190b57cec5SDimitry Andric              Pattern->getInClassInitStyle() &&
37200b57cec5SDimitry Andric          "pattern and instantiation disagree about init style");
37210b57cec5SDimitry Andric 
37220b57cec5SDimitry Andric   // Error out if we haven't parsed the initializer of the pattern yet because
37230b57cec5SDimitry Andric   // we are waiting for the closing brace of the outer class.
37240b57cec5SDimitry Andric   Expr *OldInit = Pattern->getInClassInitializer();
37250b57cec5SDimitry Andric   if (!OldInit) {
37260b57cec5SDimitry Andric     RecordDecl *PatternRD = Pattern->getParent();
37270b57cec5SDimitry Andric     RecordDecl *OutermostClass = PatternRD->getOuterLexicalRecordContext();
37280b57cec5SDimitry Andric     Diag(PointOfInstantiation,
3729e8d8bef9SDimitry Andric          diag::err_default_member_initializer_not_yet_parsed)
37300b57cec5SDimitry Andric         << OutermostClass << Pattern;
3731e8d8bef9SDimitry Andric     Diag(Pattern->getEndLoc(),
3732e8d8bef9SDimitry Andric          diag::note_default_member_initializer_not_yet_parsed);
37330b57cec5SDimitry Andric     Instantiation->setInvalidDecl();
37340b57cec5SDimitry Andric     return true;
37350b57cec5SDimitry Andric   }
37360b57cec5SDimitry Andric 
37370b57cec5SDimitry Andric   InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);
37380b57cec5SDimitry Andric   if (Inst.isInvalid())
37390b57cec5SDimitry Andric     return true;
37400b57cec5SDimitry Andric   if (Inst.isAlreadyInstantiating()) {
37410b57cec5SDimitry Andric     // Error out if we hit an instantiation cycle for this initializer.
3742e8d8bef9SDimitry Andric     Diag(PointOfInstantiation, diag::err_default_member_initializer_cycle)
37430b57cec5SDimitry Andric       << Instantiation;
37440b57cec5SDimitry Andric     return true;
37450b57cec5SDimitry Andric   }
37460b57cec5SDimitry Andric   PrettyDeclStackTraceEntry CrashInfo(Context, Instantiation, SourceLocation(),
37470b57cec5SDimitry Andric                                       "instantiating default member init");
37480b57cec5SDimitry Andric 
37490b57cec5SDimitry Andric   // Enter the scope of this instantiation. We don't use PushDeclContext because
37500b57cec5SDimitry Andric   // we don't have a scope.
37510b57cec5SDimitry Andric   ContextRAII SavedContext(*this, Instantiation->getParent());
37520b57cec5SDimitry Andric   EnterExpressionEvaluationContext EvalContext(
37530b57cec5SDimitry Andric       *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
3754bdd1243dSDimitry Andric   ExprEvalContexts.back().DelayedDefaultInitializationContext = {
3755bdd1243dSDimitry Andric       PointOfInstantiation, Instantiation, CurContext};
37560b57cec5SDimitry Andric 
37570b57cec5SDimitry Andric   LocalInstantiationScope Scope(*this, true);
37580b57cec5SDimitry Andric 
37590b57cec5SDimitry Andric   // Instantiate the initializer.
37600b57cec5SDimitry Andric   ActOnStartCXXInClassMemberInitializer();
37610b57cec5SDimitry Andric   CXXThisScopeRAII ThisScope(*this, Instantiation->getParent(), Qualifiers());
37620b57cec5SDimitry Andric 
37630b57cec5SDimitry Andric   ExprResult NewInit = SubstInitializer(OldInit, TemplateArgs,
37640b57cec5SDimitry Andric                                         /*CXXDirectInit=*/false);
37650b57cec5SDimitry Andric   Expr *Init = NewInit.get();
37660b57cec5SDimitry Andric   assert((!Init || !isa<ParenListExpr>(Init)) && "call-style init in class");
37670b57cec5SDimitry Andric   ActOnFinishCXXInClassMemberInitializer(
37680b57cec5SDimitry Andric       Instantiation, Init ? Init->getBeginLoc() : SourceLocation(), Init);
37690b57cec5SDimitry Andric 
37700b57cec5SDimitry Andric   if (auto *L = getASTMutationListener())
37710b57cec5SDimitry Andric     L->DefaultMemberInitializerInstantiated(Instantiation);
37720b57cec5SDimitry Andric 
37730b57cec5SDimitry Andric   // Return true if the in-class initializer is still missing.
37740b57cec5SDimitry Andric   return !Instantiation->getInClassInitializer();
37750b57cec5SDimitry Andric }
37760b57cec5SDimitry Andric 
37770b57cec5SDimitry Andric namespace {
37780b57cec5SDimitry Andric   /// A partial specialization whose template arguments have matched
37790b57cec5SDimitry Andric   /// a given template-id.
37800b57cec5SDimitry Andric   struct PartialSpecMatchResult {
37810b57cec5SDimitry Andric     ClassTemplatePartialSpecializationDecl *Partial;
37820b57cec5SDimitry Andric     TemplateArgumentList *Args;
37830b57cec5SDimitry Andric   };
37840b57cec5SDimitry Andric }
37850b57cec5SDimitry Andric 
37860b57cec5SDimitry Andric bool Sema::usesPartialOrExplicitSpecialization(
37870b57cec5SDimitry Andric     SourceLocation Loc, ClassTemplateSpecializationDecl *ClassTemplateSpec) {
37880b57cec5SDimitry Andric   if (ClassTemplateSpec->getTemplateSpecializationKind() ==
37890b57cec5SDimitry Andric       TSK_ExplicitSpecialization)
37900b57cec5SDimitry Andric     return true;
37910b57cec5SDimitry Andric 
37920b57cec5SDimitry Andric   SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs;
37930b57cec5SDimitry Andric   ClassTemplateSpec->getSpecializedTemplate()
37940b57cec5SDimitry Andric                    ->getPartialSpecializations(PartialSpecs);
37950b57cec5SDimitry Andric   for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I) {
37960b57cec5SDimitry Andric     TemplateDeductionInfo Info(Loc);
37970fca6ea1SDimitry Andric     if (DeduceTemplateArguments(PartialSpecs[I],
37980fca6ea1SDimitry Andric                                 ClassTemplateSpec->getTemplateArgs().asArray(),
37990fca6ea1SDimitry Andric                                 Info) == TemplateDeductionResult::Success)
38000b57cec5SDimitry Andric       return true;
38010b57cec5SDimitry Andric   }
38020b57cec5SDimitry Andric 
38030b57cec5SDimitry Andric   return false;
38040b57cec5SDimitry Andric }
38050b57cec5SDimitry Andric 
38060b57cec5SDimitry Andric /// Get the instantiation pattern to use to instantiate the definition of a
38070b57cec5SDimitry Andric /// given ClassTemplateSpecializationDecl (either the pattern of the primary
38080b57cec5SDimitry Andric /// template or of a partial specialization).
3809e8d8bef9SDimitry Andric static ActionResult<CXXRecordDecl *>
38100b57cec5SDimitry Andric getPatternForClassTemplateSpecialization(
38110b57cec5SDimitry Andric     Sema &S, SourceLocation PointOfInstantiation,
38120b57cec5SDimitry Andric     ClassTemplateSpecializationDecl *ClassTemplateSpec,
3813e8d8bef9SDimitry Andric     TemplateSpecializationKind TSK) {
38140b57cec5SDimitry Andric   Sema::InstantiatingTemplate Inst(S, PointOfInstantiation, ClassTemplateSpec);
3815e8d8bef9SDimitry Andric   if (Inst.isInvalid())
3816e8d8bef9SDimitry Andric     return {/*Invalid=*/true};
3817e8d8bef9SDimitry Andric   if (Inst.isAlreadyInstantiating())
3818e8d8bef9SDimitry Andric     return {/*Invalid=*/false};
38190b57cec5SDimitry Andric 
38200b57cec5SDimitry Andric   llvm::PointerUnion<ClassTemplateDecl *,
38210b57cec5SDimitry Andric                      ClassTemplatePartialSpecializationDecl *>
38220b57cec5SDimitry Andric       Specialized = ClassTemplateSpec->getSpecializedTemplateOrPartial();
38230b57cec5SDimitry Andric   if (!Specialized.is<ClassTemplatePartialSpecializationDecl *>()) {
38240b57cec5SDimitry Andric     // Find best matching specialization.
38250b57cec5SDimitry Andric     ClassTemplateDecl *Template = ClassTemplateSpec->getSpecializedTemplate();
38260b57cec5SDimitry Andric 
38270b57cec5SDimitry Andric     // C++ [temp.class.spec.match]p1:
38280b57cec5SDimitry Andric     //   When a class template is used in a context that requires an
38290b57cec5SDimitry Andric     //   instantiation of the class, it is necessary to determine
38300b57cec5SDimitry Andric     //   whether the instantiation is to be generated using the primary
38310b57cec5SDimitry Andric     //   template or one of the partial specializations. This is done by
38320b57cec5SDimitry Andric     //   matching the template arguments of the class template
38330b57cec5SDimitry Andric     //   specialization with the template argument lists of the partial
38340b57cec5SDimitry Andric     //   specializations.
38350b57cec5SDimitry Andric     typedef PartialSpecMatchResult MatchResult;
38360b57cec5SDimitry Andric     SmallVector<MatchResult, 4> Matched;
38370b57cec5SDimitry Andric     SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs;
38380b57cec5SDimitry Andric     Template->getPartialSpecializations(PartialSpecs);
38390b57cec5SDimitry Andric     TemplateSpecCandidateSet FailedCandidates(PointOfInstantiation);
38400b57cec5SDimitry Andric     for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I) {
38410b57cec5SDimitry Andric       ClassTemplatePartialSpecializationDecl *Partial = PartialSpecs[I];
38420b57cec5SDimitry Andric       TemplateDeductionInfo Info(FailedCandidates.getLocation());
38430fca6ea1SDimitry Andric       if (TemplateDeductionResult Result = S.DeduceTemplateArguments(
38440fca6ea1SDimitry Andric               Partial, ClassTemplateSpec->getTemplateArgs().asArray(), Info);
38450fca6ea1SDimitry Andric           Result != TemplateDeductionResult::Success) {
38460b57cec5SDimitry Andric         // Store the failed-deduction information for use in diagnostics, later.
38470b57cec5SDimitry Andric         // TODO: Actually use the failed-deduction info?
38480b57cec5SDimitry Andric         FailedCandidates.addCandidate().set(
38490b57cec5SDimitry Andric             DeclAccessPair::make(Template, AS_public), Partial,
38500b57cec5SDimitry Andric             MakeDeductionFailureInfo(S.Context, Result, Info));
38510b57cec5SDimitry Andric         (void)Result;
38520b57cec5SDimitry Andric       } else {
38530b57cec5SDimitry Andric         Matched.push_back(PartialSpecMatchResult());
38540b57cec5SDimitry Andric         Matched.back().Partial = Partial;
3855bdd1243dSDimitry Andric         Matched.back().Args = Info.takeCanonical();
38560b57cec5SDimitry Andric       }
38570b57cec5SDimitry Andric     }
38580b57cec5SDimitry Andric 
38590b57cec5SDimitry Andric     // If we're dealing with a member template where the template parameters
38600b57cec5SDimitry Andric     // have been instantiated, this provides the original template parameters
38610b57cec5SDimitry Andric     // from which the member template's parameters were instantiated.
38620b57cec5SDimitry Andric 
38630b57cec5SDimitry Andric     if (Matched.size() >= 1) {
38640b57cec5SDimitry Andric       SmallVectorImpl<MatchResult>::iterator Best = Matched.begin();
38650b57cec5SDimitry Andric       if (Matched.size() == 1) {
38660b57cec5SDimitry Andric         //   -- If exactly one matching specialization is found, the
38670b57cec5SDimitry Andric         //      instantiation is generated from that specialization.
38680b57cec5SDimitry Andric         // We don't need to do anything for this.
38690b57cec5SDimitry Andric       } else {
38700b57cec5SDimitry Andric         //   -- If more than one matching specialization is found, the
38710b57cec5SDimitry Andric         //      partial order rules (14.5.4.2) are used to determine
38720b57cec5SDimitry Andric         //      whether one of the specializations is more specialized
38730b57cec5SDimitry Andric         //      than the others. If none of the specializations is more
38740b57cec5SDimitry Andric         //      specialized than all of the other matching
38750b57cec5SDimitry Andric         //      specializations, then the use of the class template is
38760b57cec5SDimitry Andric         //      ambiguous and the program is ill-formed.
38770b57cec5SDimitry Andric         for (SmallVectorImpl<MatchResult>::iterator P = Best + 1,
38780b57cec5SDimitry Andric                                                  PEnd = Matched.end();
38790b57cec5SDimitry Andric              P != PEnd; ++P) {
38800b57cec5SDimitry Andric           if (S.getMoreSpecializedPartialSpecialization(
38810b57cec5SDimitry Andric                   P->Partial, Best->Partial, PointOfInstantiation) ==
38820b57cec5SDimitry Andric               P->Partial)
38830b57cec5SDimitry Andric             Best = P;
38840b57cec5SDimitry Andric         }
38850b57cec5SDimitry Andric 
38860b57cec5SDimitry Andric         // Determine if the best partial specialization is more specialized than
38870b57cec5SDimitry Andric         // the others.
38880b57cec5SDimitry Andric         bool Ambiguous = false;
38890b57cec5SDimitry Andric         for (SmallVectorImpl<MatchResult>::iterator P = Matched.begin(),
38900b57cec5SDimitry Andric                                                  PEnd = Matched.end();
38910b57cec5SDimitry Andric              P != PEnd; ++P) {
38920b57cec5SDimitry Andric           if (P != Best && S.getMoreSpecializedPartialSpecialization(
38930b57cec5SDimitry Andric                                P->Partial, Best->Partial,
38940b57cec5SDimitry Andric                                PointOfInstantiation) != Best->Partial) {
38950b57cec5SDimitry Andric             Ambiguous = true;
38960b57cec5SDimitry Andric             break;
38970b57cec5SDimitry Andric           }
38980b57cec5SDimitry Andric         }
38990b57cec5SDimitry Andric 
39000b57cec5SDimitry Andric         if (Ambiguous) {
39010b57cec5SDimitry Andric           // Partial ordering did not produce a clear winner. Complain.
39020b57cec5SDimitry Andric           Inst.Clear();
39030b57cec5SDimitry Andric           ClassTemplateSpec->setInvalidDecl();
39040b57cec5SDimitry Andric           S.Diag(PointOfInstantiation,
39050b57cec5SDimitry Andric                  diag::err_partial_spec_ordering_ambiguous)
39060b57cec5SDimitry Andric               << ClassTemplateSpec;
39070b57cec5SDimitry Andric 
39080b57cec5SDimitry Andric           // Print the matching partial specializations.
39090b57cec5SDimitry Andric           for (SmallVectorImpl<MatchResult>::iterator P = Matched.begin(),
39100b57cec5SDimitry Andric                                                    PEnd = Matched.end();
39110b57cec5SDimitry Andric                P != PEnd; ++P)
39120b57cec5SDimitry Andric             S.Diag(P->Partial->getLocation(), diag::note_partial_spec_match)
39130b57cec5SDimitry Andric                 << S.getTemplateArgumentBindingsText(
39140b57cec5SDimitry Andric                        P->Partial->getTemplateParameters(), *P->Args);
39150b57cec5SDimitry Andric 
3916e8d8bef9SDimitry Andric           return {/*Invalid=*/true};
39170b57cec5SDimitry Andric         }
39180b57cec5SDimitry Andric       }
39190b57cec5SDimitry Andric 
39200b57cec5SDimitry Andric       ClassTemplateSpec->setInstantiationOf(Best->Partial, Best->Args);
39210b57cec5SDimitry Andric     } else {
39220b57cec5SDimitry Andric       //   -- If no matches are found, the instantiation is generated
39230b57cec5SDimitry Andric       //      from the primary template.
39240b57cec5SDimitry Andric     }
39250b57cec5SDimitry Andric   }
39260b57cec5SDimitry Andric 
39270b57cec5SDimitry Andric   CXXRecordDecl *Pattern = nullptr;
39280b57cec5SDimitry Andric   Specialized = ClassTemplateSpec->getSpecializedTemplateOrPartial();
39290b57cec5SDimitry Andric   if (auto *PartialSpec =
39300b57cec5SDimitry Andric           Specialized.dyn_cast<ClassTemplatePartialSpecializationDecl *>()) {
39310b57cec5SDimitry Andric     // Instantiate using the best class template partial specialization.
39320b57cec5SDimitry Andric     while (PartialSpec->getInstantiatedFromMember()) {
39330b57cec5SDimitry Andric       // If we've found an explicit specialization of this class template,
39340b57cec5SDimitry Andric       // stop here and use that as the pattern.
39350b57cec5SDimitry Andric       if (PartialSpec->isMemberSpecialization())
39360b57cec5SDimitry Andric         break;
39370b57cec5SDimitry Andric 
39380b57cec5SDimitry Andric       PartialSpec = PartialSpec->getInstantiatedFromMember();
39390b57cec5SDimitry Andric     }
39400b57cec5SDimitry Andric     Pattern = PartialSpec;
39410b57cec5SDimitry Andric   } else {
39420b57cec5SDimitry Andric     ClassTemplateDecl *Template = ClassTemplateSpec->getSpecializedTemplate();
39430b57cec5SDimitry Andric     while (Template->getInstantiatedFromMemberTemplate()) {
39440b57cec5SDimitry Andric       // If we've found an explicit specialization of this class template,
39450b57cec5SDimitry Andric       // stop here and use that as the pattern.
39460b57cec5SDimitry Andric       if (Template->isMemberSpecialization())
39470b57cec5SDimitry Andric         break;
39480b57cec5SDimitry Andric 
39490b57cec5SDimitry Andric       Template = Template->getInstantiatedFromMemberTemplate();
39500b57cec5SDimitry Andric     }
39510b57cec5SDimitry Andric     Pattern = Template->getTemplatedDecl();
39520b57cec5SDimitry Andric   }
39530b57cec5SDimitry Andric 
39540b57cec5SDimitry Andric   return Pattern;
39550b57cec5SDimitry Andric }
39560b57cec5SDimitry Andric 
39570b57cec5SDimitry Andric bool Sema::InstantiateClassTemplateSpecialization(
39580b57cec5SDimitry Andric     SourceLocation PointOfInstantiation,
39590b57cec5SDimitry Andric     ClassTemplateSpecializationDecl *ClassTemplateSpec,
39600b57cec5SDimitry Andric     TemplateSpecializationKind TSK, bool Complain) {
39610b57cec5SDimitry Andric   // Perform the actual instantiation on the canonical declaration.
39620b57cec5SDimitry Andric   ClassTemplateSpec = cast<ClassTemplateSpecializationDecl>(
39630b57cec5SDimitry Andric       ClassTemplateSpec->getCanonicalDecl());
39640b57cec5SDimitry Andric   if (ClassTemplateSpec->isInvalidDecl())
39650b57cec5SDimitry Andric     return true;
39660b57cec5SDimitry Andric 
3967e8d8bef9SDimitry Andric   ActionResult<CXXRecordDecl *> Pattern =
3968e8d8bef9SDimitry Andric       getPatternForClassTemplateSpecialization(*this, PointOfInstantiation,
3969e8d8bef9SDimitry Andric                                                ClassTemplateSpec, TSK);
3970e8d8bef9SDimitry Andric   if (!Pattern.isUsable())
3971e8d8bef9SDimitry Andric     return Pattern.isInvalid();
39720b57cec5SDimitry Andric 
3973e8d8bef9SDimitry Andric   return InstantiateClass(
3974e8d8bef9SDimitry Andric       PointOfInstantiation, ClassTemplateSpec, Pattern.get(),
3975e8d8bef9SDimitry Andric       getTemplateInstantiationArgs(ClassTemplateSpec), TSK, Complain);
39760b57cec5SDimitry Andric }
39770b57cec5SDimitry Andric 
39780b57cec5SDimitry Andric void
39790b57cec5SDimitry Andric Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
39800b57cec5SDimitry Andric                               CXXRecordDecl *Instantiation,
39810b57cec5SDimitry Andric                         const MultiLevelTemplateArgumentList &TemplateArgs,
39820b57cec5SDimitry Andric                               TemplateSpecializationKind TSK) {
39830b57cec5SDimitry Andric   // FIXME: We need to notify the ASTMutationListener that we did all of these
39840b57cec5SDimitry Andric   // things, in case we have an explicit instantiation definition in a PCM, a
39850b57cec5SDimitry Andric   // module, or preamble, and the declaration is in an imported AST.
39860b57cec5SDimitry Andric   assert(
39870b57cec5SDimitry Andric       (TSK == TSK_ExplicitInstantiationDefinition ||
39880b57cec5SDimitry Andric        TSK == TSK_ExplicitInstantiationDeclaration ||
39890b57cec5SDimitry Andric        (TSK == TSK_ImplicitInstantiation && Instantiation->isLocalClass())) &&
39900b57cec5SDimitry Andric       "Unexpected template specialization kind!");
39910b57cec5SDimitry Andric   for (auto *D : Instantiation->decls()) {
39920b57cec5SDimitry Andric     bool SuppressNew = false;
39930b57cec5SDimitry Andric     if (auto *Function = dyn_cast<FunctionDecl>(D)) {
39940b57cec5SDimitry Andric       if (FunctionDecl *Pattern =
39950b57cec5SDimitry Andric               Function->getInstantiatedFromMemberFunction()) {
39960b57cec5SDimitry Andric 
399781ad6265SDimitry Andric         if (Function->isIneligibleOrNotSelected())
399881ad6265SDimitry Andric           continue;
399981ad6265SDimitry Andric 
400081ad6265SDimitry Andric         if (Function->getTrailingRequiresClause()) {
400181ad6265SDimitry Andric           ConstraintSatisfaction Satisfaction;
400281ad6265SDimitry Andric           if (CheckFunctionConstraints(Function, Satisfaction) ||
400381ad6265SDimitry Andric               !Satisfaction.IsSatisfied) {
400481ad6265SDimitry Andric             continue;
400581ad6265SDimitry Andric           }
400681ad6265SDimitry Andric         }
400781ad6265SDimitry Andric 
40080b57cec5SDimitry Andric         if (Function->hasAttr<ExcludeFromExplicitInstantiationAttr>())
40090b57cec5SDimitry Andric           continue;
40100b57cec5SDimitry Andric 
40110b57cec5SDimitry Andric         MemberSpecializationInfo *MSInfo =
40120b57cec5SDimitry Andric             Function->getMemberSpecializationInfo();
40130b57cec5SDimitry Andric         assert(MSInfo && "No member specialization information?");
40140b57cec5SDimitry Andric         if (MSInfo->getTemplateSpecializationKind()
40150b57cec5SDimitry Andric                                                  == TSK_ExplicitSpecialization)
40160b57cec5SDimitry Andric           continue;
40170b57cec5SDimitry Andric 
40180b57cec5SDimitry Andric         if (CheckSpecializationInstantiationRedecl(PointOfInstantiation, TSK,
40190b57cec5SDimitry Andric                                                    Function,
40200b57cec5SDimitry Andric                                         MSInfo->getTemplateSpecializationKind(),
40210b57cec5SDimitry Andric                                               MSInfo->getPointOfInstantiation(),
40220b57cec5SDimitry Andric                                                    SuppressNew) ||
40230b57cec5SDimitry Andric             SuppressNew)
40240b57cec5SDimitry Andric           continue;
40250b57cec5SDimitry Andric 
40260b57cec5SDimitry Andric         // C++11 [temp.explicit]p8:
40270b57cec5SDimitry Andric         //   An explicit instantiation definition that names a class template
40280b57cec5SDimitry Andric         //   specialization explicitly instantiates the class template
40290b57cec5SDimitry Andric         //   specialization and is only an explicit instantiation definition
40300b57cec5SDimitry Andric         //   of members whose definition is visible at the point of
40310b57cec5SDimitry Andric         //   instantiation.
40320b57cec5SDimitry Andric         if (TSK == TSK_ExplicitInstantiationDefinition && !Pattern->isDefined())
40330b57cec5SDimitry Andric           continue;
40340b57cec5SDimitry Andric 
40350b57cec5SDimitry Andric         Function->setTemplateSpecializationKind(TSK, PointOfInstantiation);
40360b57cec5SDimitry Andric 
40370b57cec5SDimitry Andric         if (Function->isDefined()) {
40380b57cec5SDimitry Andric           // Let the ASTConsumer know that this function has been explicitly
40390b57cec5SDimitry Andric           // instantiated now, and its linkage might have changed.
40400b57cec5SDimitry Andric           Consumer.HandleTopLevelDecl(DeclGroupRef(Function));
40410b57cec5SDimitry Andric         } else if (TSK == TSK_ExplicitInstantiationDefinition) {
40420b57cec5SDimitry Andric           InstantiateFunctionDefinition(PointOfInstantiation, Function);
40430b57cec5SDimitry Andric         } else if (TSK == TSK_ImplicitInstantiation) {
40440b57cec5SDimitry Andric           PendingLocalImplicitInstantiations.push_back(
40450b57cec5SDimitry Andric               std::make_pair(Function, PointOfInstantiation));
40460b57cec5SDimitry Andric         }
40470b57cec5SDimitry Andric       }
40480b57cec5SDimitry Andric     } else if (auto *Var = dyn_cast<VarDecl>(D)) {
40490b57cec5SDimitry Andric       if (isa<VarTemplateSpecializationDecl>(Var))
40500b57cec5SDimitry Andric         continue;
40510b57cec5SDimitry Andric 
40520b57cec5SDimitry Andric       if (Var->isStaticDataMember()) {
40530b57cec5SDimitry Andric         if (Var->hasAttr<ExcludeFromExplicitInstantiationAttr>())
40540b57cec5SDimitry Andric           continue;
40550b57cec5SDimitry Andric 
40560b57cec5SDimitry Andric         MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo();
40570b57cec5SDimitry Andric         assert(MSInfo && "No member specialization information?");
40580b57cec5SDimitry Andric         if (MSInfo->getTemplateSpecializationKind()
40590b57cec5SDimitry Andric                                                  == TSK_ExplicitSpecialization)
40600b57cec5SDimitry Andric           continue;
40610b57cec5SDimitry Andric 
40620b57cec5SDimitry Andric         if (CheckSpecializationInstantiationRedecl(PointOfInstantiation, TSK,
40630b57cec5SDimitry Andric                                                    Var,
40640b57cec5SDimitry Andric                                         MSInfo->getTemplateSpecializationKind(),
40650b57cec5SDimitry Andric                                               MSInfo->getPointOfInstantiation(),
40660b57cec5SDimitry Andric                                                    SuppressNew) ||
40670b57cec5SDimitry Andric             SuppressNew)
40680b57cec5SDimitry Andric           continue;
40690b57cec5SDimitry Andric 
40700b57cec5SDimitry Andric         if (TSK == TSK_ExplicitInstantiationDefinition) {
40710b57cec5SDimitry Andric           // C++0x [temp.explicit]p8:
40720b57cec5SDimitry Andric           //   An explicit instantiation definition that names a class template
40730b57cec5SDimitry Andric           //   specialization explicitly instantiates the class template
40740b57cec5SDimitry Andric           //   specialization and is only an explicit instantiation definition
40750b57cec5SDimitry Andric           //   of members whose definition is visible at the point of
40760b57cec5SDimitry Andric           //   instantiation.
40770b57cec5SDimitry Andric           if (!Var->getInstantiatedFromStaticDataMember()->getDefinition())
40780b57cec5SDimitry Andric             continue;
40790b57cec5SDimitry Andric 
40800b57cec5SDimitry Andric           Var->setTemplateSpecializationKind(TSK, PointOfInstantiation);
40810b57cec5SDimitry Andric           InstantiateVariableDefinition(PointOfInstantiation, Var);
40820b57cec5SDimitry Andric         } else {
40830b57cec5SDimitry Andric           Var->setTemplateSpecializationKind(TSK, PointOfInstantiation);
40840b57cec5SDimitry Andric         }
40850b57cec5SDimitry Andric       }
40860b57cec5SDimitry Andric     } else if (auto *Record = dyn_cast<CXXRecordDecl>(D)) {
40870b57cec5SDimitry Andric       if (Record->hasAttr<ExcludeFromExplicitInstantiationAttr>())
40880b57cec5SDimitry Andric         continue;
40890b57cec5SDimitry Andric 
40900b57cec5SDimitry Andric       // Always skip the injected-class-name, along with any
40910b57cec5SDimitry Andric       // redeclarations of nested classes, since both would cause us
40920b57cec5SDimitry Andric       // to try to instantiate the members of a class twice.
40930b57cec5SDimitry Andric       // Skip closure types; they'll get instantiated when we instantiate
40940b57cec5SDimitry Andric       // the corresponding lambda-expression.
40950b57cec5SDimitry Andric       if (Record->isInjectedClassName() || Record->getPreviousDecl() ||
40960b57cec5SDimitry Andric           Record->isLambda())
40970b57cec5SDimitry Andric         continue;
40980b57cec5SDimitry Andric 
40990b57cec5SDimitry Andric       MemberSpecializationInfo *MSInfo = Record->getMemberSpecializationInfo();
41000b57cec5SDimitry Andric       assert(MSInfo && "No member specialization information?");
41010b57cec5SDimitry Andric 
41020b57cec5SDimitry Andric       if (MSInfo->getTemplateSpecializationKind()
41030b57cec5SDimitry Andric                                                 == TSK_ExplicitSpecialization)
41040b57cec5SDimitry Andric         continue;
41050b57cec5SDimitry Andric 
41060b57cec5SDimitry Andric       if (Context.getTargetInfo().getTriple().isOSWindows() &&
41070b57cec5SDimitry Andric           TSK == TSK_ExplicitInstantiationDeclaration) {
41080b57cec5SDimitry Andric         // On Windows, explicit instantiation decl of the outer class doesn't
41090b57cec5SDimitry Andric         // affect the inner class. Typically extern template declarations are
41100b57cec5SDimitry Andric         // used in combination with dll import/export annotations, but those
41110b57cec5SDimitry Andric         // are not propagated from the outer class templates to inner classes.
41120b57cec5SDimitry Andric         // Therefore, do not instantiate inner classes on this platform, so
41130b57cec5SDimitry Andric         // that users don't end up with undefined symbols during linking.
41140b57cec5SDimitry Andric         continue;
41150b57cec5SDimitry Andric       }
41160b57cec5SDimitry Andric 
41170b57cec5SDimitry Andric       if (CheckSpecializationInstantiationRedecl(PointOfInstantiation, TSK,
41180b57cec5SDimitry Andric                                                  Record,
41190b57cec5SDimitry Andric                                         MSInfo->getTemplateSpecializationKind(),
41200b57cec5SDimitry Andric                                               MSInfo->getPointOfInstantiation(),
41210b57cec5SDimitry Andric                                                  SuppressNew) ||
41220b57cec5SDimitry Andric           SuppressNew)
41230b57cec5SDimitry Andric         continue;
41240b57cec5SDimitry Andric 
41250b57cec5SDimitry Andric       CXXRecordDecl *Pattern = Record->getInstantiatedFromMemberClass();
41260b57cec5SDimitry Andric       assert(Pattern && "Missing instantiated-from-template information");
41270b57cec5SDimitry Andric 
41280b57cec5SDimitry Andric       if (!Record->getDefinition()) {
41290b57cec5SDimitry Andric         if (!Pattern->getDefinition()) {
41300b57cec5SDimitry Andric           // C++0x [temp.explicit]p8:
41310b57cec5SDimitry Andric           //   An explicit instantiation definition that names a class template
41320b57cec5SDimitry Andric           //   specialization explicitly instantiates the class template
41330b57cec5SDimitry Andric           //   specialization and is only an explicit instantiation definition
41340b57cec5SDimitry Andric           //   of members whose definition is visible at the point of
41350b57cec5SDimitry Andric           //   instantiation.
41360b57cec5SDimitry Andric           if (TSK == TSK_ExplicitInstantiationDeclaration) {
41370b57cec5SDimitry Andric             MSInfo->setTemplateSpecializationKind(TSK);
41380b57cec5SDimitry Andric             MSInfo->setPointOfInstantiation(PointOfInstantiation);
41390b57cec5SDimitry Andric           }
41400b57cec5SDimitry Andric 
41410b57cec5SDimitry Andric           continue;
41420b57cec5SDimitry Andric         }
41430b57cec5SDimitry Andric 
41440b57cec5SDimitry Andric         InstantiateClass(PointOfInstantiation, Record, Pattern,
41450b57cec5SDimitry Andric                          TemplateArgs,
41460b57cec5SDimitry Andric                          TSK);
41470b57cec5SDimitry Andric       } else {
41480b57cec5SDimitry Andric         if (TSK == TSK_ExplicitInstantiationDefinition &&
41490b57cec5SDimitry Andric             Record->getTemplateSpecializationKind() ==
41500b57cec5SDimitry Andric                 TSK_ExplicitInstantiationDeclaration) {
41510b57cec5SDimitry Andric           Record->setTemplateSpecializationKind(TSK);
41520b57cec5SDimitry Andric           MarkVTableUsed(PointOfInstantiation, Record, true);
41530b57cec5SDimitry Andric         }
41540b57cec5SDimitry Andric       }
41550b57cec5SDimitry Andric 
41560b57cec5SDimitry Andric       Pattern = cast_or_null<CXXRecordDecl>(Record->getDefinition());
41570b57cec5SDimitry Andric       if (Pattern)
41580b57cec5SDimitry Andric         InstantiateClassMembers(PointOfInstantiation, Pattern, TemplateArgs,
41590b57cec5SDimitry Andric                                 TSK);
41600b57cec5SDimitry Andric     } else if (auto *Enum = dyn_cast<EnumDecl>(D)) {
41610b57cec5SDimitry Andric       MemberSpecializationInfo *MSInfo = Enum->getMemberSpecializationInfo();
41620b57cec5SDimitry Andric       assert(MSInfo && "No member specialization information?");
41630b57cec5SDimitry Andric 
41640b57cec5SDimitry Andric       if (MSInfo->getTemplateSpecializationKind()
41650b57cec5SDimitry Andric             == TSK_ExplicitSpecialization)
41660b57cec5SDimitry Andric         continue;
41670b57cec5SDimitry Andric 
41680b57cec5SDimitry Andric       if (CheckSpecializationInstantiationRedecl(
41690b57cec5SDimitry Andric             PointOfInstantiation, TSK, Enum,
41700b57cec5SDimitry Andric             MSInfo->getTemplateSpecializationKind(),
41710b57cec5SDimitry Andric             MSInfo->getPointOfInstantiation(), SuppressNew) ||
41720b57cec5SDimitry Andric           SuppressNew)
41730b57cec5SDimitry Andric         continue;
41740b57cec5SDimitry Andric 
41750b57cec5SDimitry Andric       if (Enum->getDefinition())
41760b57cec5SDimitry Andric         continue;
41770b57cec5SDimitry Andric 
41780b57cec5SDimitry Andric       EnumDecl *Pattern = Enum->getTemplateInstantiationPattern();
41790b57cec5SDimitry Andric       assert(Pattern && "Missing instantiated-from-template information");
41800b57cec5SDimitry Andric 
41810b57cec5SDimitry Andric       if (TSK == TSK_ExplicitInstantiationDefinition) {
41820b57cec5SDimitry Andric         if (!Pattern->getDefinition())
41830b57cec5SDimitry Andric           continue;
41840b57cec5SDimitry Andric 
41850b57cec5SDimitry Andric         InstantiateEnum(PointOfInstantiation, Enum, Pattern, TemplateArgs, TSK);
41860b57cec5SDimitry Andric       } else {
41870b57cec5SDimitry Andric         MSInfo->setTemplateSpecializationKind(TSK);
41880b57cec5SDimitry Andric         MSInfo->setPointOfInstantiation(PointOfInstantiation);
41890b57cec5SDimitry Andric       }
41900b57cec5SDimitry Andric     } else if (auto *Field = dyn_cast<FieldDecl>(D)) {
41910b57cec5SDimitry Andric       // No need to instantiate in-class initializers during explicit
41920b57cec5SDimitry Andric       // instantiation.
41930b57cec5SDimitry Andric       if (Field->hasInClassInitializer() && TSK == TSK_ImplicitInstantiation) {
41940b57cec5SDimitry Andric         CXXRecordDecl *ClassPattern =
41950b57cec5SDimitry Andric             Instantiation->getTemplateInstantiationPattern();
41960b57cec5SDimitry Andric         DeclContext::lookup_result Lookup =
41970b57cec5SDimitry Andric             ClassPattern->lookup(Field->getDeclName());
4198fe6060f1SDimitry Andric         FieldDecl *Pattern = Lookup.find_first<FieldDecl>();
4199fe6060f1SDimitry Andric         assert(Pattern);
42000b57cec5SDimitry Andric         InstantiateInClassInitializer(PointOfInstantiation, Field, Pattern,
42010b57cec5SDimitry Andric                                       TemplateArgs);
42020b57cec5SDimitry Andric       }
42030b57cec5SDimitry Andric     }
42040b57cec5SDimitry Andric   }
42050b57cec5SDimitry Andric }
42060b57cec5SDimitry Andric 
42070b57cec5SDimitry Andric void
42080b57cec5SDimitry Andric Sema::InstantiateClassTemplateSpecializationMembers(
42090b57cec5SDimitry Andric                                            SourceLocation PointOfInstantiation,
42100b57cec5SDimitry Andric                             ClassTemplateSpecializationDecl *ClassTemplateSpec,
42110b57cec5SDimitry Andric                                                TemplateSpecializationKind TSK) {
42120b57cec5SDimitry Andric   // C++0x [temp.explicit]p7:
42130b57cec5SDimitry Andric   //   An explicit instantiation that names a class template
42140b57cec5SDimitry Andric   //   specialization is an explicit instantion of the same kind
42150b57cec5SDimitry Andric   //   (declaration or definition) of each of its members (not
42160b57cec5SDimitry Andric   //   including members inherited from base classes) that has not
42170b57cec5SDimitry Andric   //   been previously explicitly specialized in the translation unit
42180b57cec5SDimitry Andric   //   containing the explicit instantiation, except as described
42190b57cec5SDimitry Andric   //   below.
42200b57cec5SDimitry Andric   InstantiateClassMembers(PointOfInstantiation, ClassTemplateSpec,
42210b57cec5SDimitry Andric                           getTemplateInstantiationArgs(ClassTemplateSpec),
42220b57cec5SDimitry Andric                           TSK);
42230b57cec5SDimitry Andric }
42240b57cec5SDimitry Andric 
42250b57cec5SDimitry Andric StmtResult
42260b57cec5SDimitry Andric Sema::SubstStmt(Stmt *S, const MultiLevelTemplateArgumentList &TemplateArgs) {
42270b57cec5SDimitry Andric   if (!S)
42280b57cec5SDimitry Andric     return S;
42290b57cec5SDimitry Andric 
42300b57cec5SDimitry Andric   TemplateInstantiator Instantiator(*this, TemplateArgs,
42310b57cec5SDimitry Andric                                     SourceLocation(),
42320b57cec5SDimitry Andric                                     DeclarationName());
42330b57cec5SDimitry Andric   return Instantiator.TransformStmt(S);
42340b57cec5SDimitry Andric }
42350b57cec5SDimitry Andric 
42360fca6ea1SDimitry Andric bool Sema::SubstTemplateArgument(
42370fca6ea1SDimitry Andric     const TemplateArgumentLoc &Input,
42380fca6ea1SDimitry Andric     const MultiLevelTemplateArgumentList &TemplateArgs,
42390fca6ea1SDimitry Andric     TemplateArgumentLoc &Output, SourceLocation Loc,
42400fca6ea1SDimitry Andric     const DeclarationName &Entity) {
42410fca6ea1SDimitry Andric   TemplateInstantiator Instantiator(*this, TemplateArgs, Loc, Entity);
42420fca6ea1SDimitry Andric   return Instantiator.TransformTemplateArgument(Input, Output);
42430fca6ea1SDimitry Andric }
42440fca6ea1SDimitry Andric 
4245480093f4SDimitry Andric bool Sema::SubstTemplateArguments(
4246480093f4SDimitry Andric     ArrayRef<TemplateArgumentLoc> Args,
4247480093f4SDimitry Andric     const MultiLevelTemplateArgumentList &TemplateArgs,
4248480093f4SDimitry Andric     TemplateArgumentListInfo &Out) {
4249bdd1243dSDimitry Andric   TemplateInstantiator Instantiator(*this, TemplateArgs, SourceLocation(),
4250480093f4SDimitry Andric                                     DeclarationName());
4251bdd1243dSDimitry Andric   return Instantiator.TransformTemplateArguments(Args.begin(), Args.end(), Out);
4252480093f4SDimitry Andric }
4253480093f4SDimitry Andric 
42540b57cec5SDimitry Andric ExprResult
42550b57cec5SDimitry Andric Sema::SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs) {
42560b57cec5SDimitry Andric   if (!E)
42570b57cec5SDimitry Andric     return E;
42580b57cec5SDimitry Andric 
42590b57cec5SDimitry Andric   TemplateInstantiator Instantiator(*this, TemplateArgs,
42600b57cec5SDimitry Andric                                     SourceLocation(),
42610b57cec5SDimitry Andric                                     DeclarationName());
42620b57cec5SDimitry Andric   return Instantiator.TransformExpr(E);
42630b57cec5SDimitry Andric }
42640b57cec5SDimitry Andric 
4265bdd1243dSDimitry Andric ExprResult
4266bdd1243dSDimitry Andric Sema::SubstConstraintExpr(Expr *E,
4267bdd1243dSDimitry Andric                           const MultiLevelTemplateArgumentList &TemplateArgs) {
42681db9f3b2SDimitry Andric   // FIXME: should call SubstExpr directly if this function is equivalent or
42691db9f3b2SDimitry Andric   //        should it be different?
42701db9f3b2SDimitry Andric   return SubstExpr(E, TemplateArgs);
42711db9f3b2SDimitry Andric }
42721db9f3b2SDimitry Andric 
42731db9f3b2SDimitry Andric ExprResult Sema::SubstConstraintExprWithoutSatisfaction(
42741db9f3b2SDimitry Andric     Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs) {
4275bdd1243dSDimitry Andric   if (!E)
4276bdd1243dSDimitry Andric     return E;
4277bdd1243dSDimitry Andric 
4278bdd1243dSDimitry Andric   TemplateInstantiator Instantiator(*this, TemplateArgs, SourceLocation(),
4279bdd1243dSDimitry Andric                                     DeclarationName());
42801db9f3b2SDimitry Andric   Instantiator.setEvaluateConstraints(false);
4281bdd1243dSDimitry Andric   return Instantiator.TransformExpr(E);
4282bdd1243dSDimitry Andric }
4283bdd1243dSDimitry Andric 
42840b57cec5SDimitry Andric ExprResult Sema::SubstInitializer(Expr *Init,
42850b57cec5SDimitry Andric                           const MultiLevelTemplateArgumentList &TemplateArgs,
42860b57cec5SDimitry Andric                           bool CXXDirectInit) {
4287bdd1243dSDimitry Andric   TemplateInstantiator Instantiator(*this, TemplateArgs, SourceLocation(),
42880b57cec5SDimitry Andric                                     DeclarationName());
42890b57cec5SDimitry Andric   return Instantiator.TransformInitializer(Init, CXXDirectInit);
42900b57cec5SDimitry Andric }
42910b57cec5SDimitry Andric 
42920b57cec5SDimitry Andric bool Sema::SubstExprs(ArrayRef<Expr *> Exprs, bool IsCall,
42930b57cec5SDimitry Andric                       const MultiLevelTemplateArgumentList &TemplateArgs,
42940b57cec5SDimitry Andric                       SmallVectorImpl<Expr *> &Outputs) {
42950b57cec5SDimitry Andric   if (Exprs.empty())
42960b57cec5SDimitry Andric     return false;
42970b57cec5SDimitry Andric 
42980b57cec5SDimitry Andric   TemplateInstantiator Instantiator(*this, TemplateArgs,
42990b57cec5SDimitry Andric                                     SourceLocation(),
43000b57cec5SDimitry Andric                                     DeclarationName());
43010b57cec5SDimitry Andric   return Instantiator.TransformExprs(Exprs.data(), Exprs.size(),
43020b57cec5SDimitry Andric                                      IsCall, Outputs);
43030b57cec5SDimitry Andric }
43040b57cec5SDimitry Andric 
43050b57cec5SDimitry Andric NestedNameSpecifierLoc
43060b57cec5SDimitry Andric Sema::SubstNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
43070b57cec5SDimitry Andric                         const MultiLevelTemplateArgumentList &TemplateArgs) {
43080b57cec5SDimitry Andric   if (!NNS)
43090b57cec5SDimitry Andric     return NestedNameSpecifierLoc();
43100b57cec5SDimitry Andric 
43110b57cec5SDimitry Andric   TemplateInstantiator Instantiator(*this, TemplateArgs, NNS.getBeginLoc(),
43120b57cec5SDimitry Andric                                     DeclarationName());
43130b57cec5SDimitry Andric   return Instantiator.TransformNestedNameSpecifierLoc(NNS);
43140b57cec5SDimitry Andric }
43150b57cec5SDimitry Andric 
43160b57cec5SDimitry Andric DeclarationNameInfo
43170b57cec5SDimitry Andric Sema::SubstDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
43180b57cec5SDimitry Andric                          const MultiLevelTemplateArgumentList &TemplateArgs) {
43190b57cec5SDimitry Andric   TemplateInstantiator Instantiator(*this, TemplateArgs, NameInfo.getLoc(),
43200b57cec5SDimitry Andric                                     NameInfo.getName());
43210b57cec5SDimitry Andric   return Instantiator.TransformDeclarationNameInfo(NameInfo);
43220b57cec5SDimitry Andric }
43230b57cec5SDimitry Andric 
43240b57cec5SDimitry Andric TemplateName
43250b57cec5SDimitry Andric Sema::SubstTemplateName(NestedNameSpecifierLoc QualifierLoc,
43260b57cec5SDimitry Andric                         TemplateName Name, SourceLocation Loc,
43270b57cec5SDimitry Andric                         const MultiLevelTemplateArgumentList &TemplateArgs) {
43280b57cec5SDimitry Andric   TemplateInstantiator Instantiator(*this, TemplateArgs, Loc,
43290b57cec5SDimitry Andric                                     DeclarationName());
43300b57cec5SDimitry Andric   CXXScopeSpec SS;
43310b57cec5SDimitry Andric   SS.Adopt(QualifierLoc);
43320b57cec5SDimitry Andric   return Instantiator.TransformTemplateName(SS, Name, Loc);
43330b57cec5SDimitry Andric }
43340b57cec5SDimitry Andric 
43350b57cec5SDimitry Andric static const Decl *getCanonicalParmVarDecl(const Decl *D) {
43360b57cec5SDimitry Andric   // When storing ParmVarDecls in the local instantiation scope, we always
43370b57cec5SDimitry Andric   // want to use the ParmVarDecl from the canonical function declaration,
43380b57cec5SDimitry Andric   // since the map is then valid for any redeclaration or definition of that
43390b57cec5SDimitry Andric   // function.
43400b57cec5SDimitry Andric   if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(D)) {
43410b57cec5SDimitry Andric     if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
43420b57cec5SDimitry Andric       unsigned i = PV->getFunctionScopeIndex();
43430b57cec5SDimitry Andric       // This parameter might be from a freestanding function type within the
43440b57cec5SDimitry Andric       // function and isn't necessarily referring to one of FD's parameters.
43450b57cec5SDimitry Andric       if (i < FD->getNumParams() && FD->getParamDecl(i) == PV)
43460b57cec5SDimitry Andric         return FD->getCanonicalDecl()->getParamDecl(i);
43470b57cec5SDimitry Andric     }
43480b57cec5SDimitry Andric   }
43490b57cec5SDimitry Andric   return D;
43500b57cec5SDimitry Andric }
43510b57cec5SDimitry Andric 
43520b57cec5SDimitry Andric 
43530b57cec5SDimitry Andric llvm::PointerUnion<Decl *, LocalInstantiationScope::DeclArgumentPack *> *
43540b57cec5SDimitry Andric LocalInstantiationScope::findInstantiationOf(const Decl *D) {
43550b57cec5SDimitry Andric   D = getCanonicalParmVarDecl(D);
43560b57cec5SDimitry Andric   for (LocalInstantiationScope *Current = this; Current;
43570b57cec5SDimitry Andric        Current = Current->Outer) {
43580b57cec5SDimitry Andric 
43590b57cec5SDimitry Andric     // Check if we found something within this scope.
43600b57cec5SDimitry Andric     const Decl *CheckD = D;
43610b57cec5SDimitry Andric     do {
43620b57cec5SDimitry Andric       LocalDeclsMap::iterator Found = Current->LocalDecls.find(CheckD);
43630b57cec5SDimitry Andric       if (Found != Current->LocalDecls.end())
43640b57cec5SDimitry Andric         return &Found->second;
43650b57cec5SDimitry Andric 
43660b57cec5SDimitry Andric       // If this is a tag declaration, it's possible that we need to look for
43670b57cec5SDimitry Andric       // a previous declaration.
43680b57cec5SDimitry Andric       if (const TagDecl *Tag = dyn_cast<TagDecl>(CheckD))
43690b57cec5SDimitry Andric         CheckD = Tag->getPreviousDecl();
43700b57cec5SDimitry Andric       else
43710b57cec5SDimitry Andric         CheckD = nullptr;
43720b57cec5SDimitry Andric     } while (CheckD);
43730b57cec5SDimitry Andric 
43740b57cec5SDimitry Andric     // If we aren't combined with our outer scope, we're done.
43750b57cec5SDimitry Andric     if (!Current->CombineWithOuterScope)
43760b57cec5SDimitry Andric       break;
43770b57cec5SDimitry Andric   }
43780b57cec5SDimitry Andric 
43790b57cec5SDimitry Andric   // If we're performing a partial substitution during template argument
43800b57cec5SDimitry Andric   // deduction, we may not have values for template parameters yet.
43810b57cec5SDimitry Andric   if (isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D) ||
43820b57cec5SDimitry Andric       isa<TemplateTemplateParmDecl>(D))
43830b57cec5SDimitry Andric     return nullptr;
43840b57cec5SDimitry Andric 
43850b57cec5SDimitry Andric   // Local types referenced prior to definition may require instantiation.
43860b57cec5SDimitry Andric   if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
43870b57cec5SDimitry Andric     if (RD->isLocalClass())
43880b57cec5SDimitry Andric       return nullptr;
43890b57cec5SDimitry Andric 
43900b57cec5SDimitry Andric   // Enumeration types referenced prior to definition may appear as a result of
43910b57cec5SDimitry Andric   // error recovery.
43920b57cec5SDimitry Andric   if (isa<EnumDecl>(D))
43930b57cec5SDimitry Andric     return nullptr;
43940b57cec5SDimitry Andric 
43955ffd83dbSDimitry Andric   // Materialized typedefs/type alias for implicit deduction guides may require
43965ffd83dbSDimitry Andric   // instantiation.
43975ffd83dbSDimitry Andric   if (isa<TypedefNameDecl>(D) &&
43985ffd83dbSDimitry Andric       isa<CXXDeductionGuideDecl>(D->getDeclContext()))
43995ffd83dbSDimitry Andric     return nullptr;
44005ffd83dbSDimitry Andric 
44010b57cec5SDimitry Andric   // If we didn't find the decl, then we either have a sema bug, or we have a
44020b57cec5SDimitry Andric   // forward reference to a label declaration.  Return null to indicate that
44030b57cec5SDimitry Andric   // we have an uninstantiated label.
44040b57cec5SDimitry Andric   assert(isa<LabelDecl>(D) && "declaration not instantiated in this scope");
44050b57cec5SDimitry Andric   return nullptr;
44060b57cec5SDimitry Andric }
44070b57cec5SDimitry Andric 
44080b57cec5SDimitry Andric void LocalInstantiationScope::InstantiatedLocal(const Decl *D, Decl *Inst) {
44090b57cec5SDimitry Andric   D = getCanonicalParmVarDecl(D);
44100b57cec5SDimitry Andric   llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored = LocalDecls[D];
44110b57cec5SDimitry Andric   if (Stored.isNull()) {
44120b57cec5SDimitry Andric #ifndef NDEBUG
44130b57cec5SDimitry Andric     // It should not be present in any surrounding scope either.
44140b57cec5SDimitry Andric     LocalInstantiationScope *Current = this;
44150b57cec5SDimitry Andric     while (Current->CombineWithOuterScope && Current->Outer) {
44160b57cec5SDimitry Andric       Current = Current->Outer;
44175f757f3fSDimitry Andric       assert(!Current->LocalDecls.contains(D) &&
44180b57cec5SDimitry Andric              "Instantiated local in inner and outer scopes");
44190b57cec5SDimitry Andric     }
44200b57cec5SDimitry Andric #endif
44210b57cec5SDimitry Andric     Stored = Inst;
44220b57cec5SDimitry Andric   } else if (DeclArgumentPack *Pack = Stored.dyn_cast<DeclArgumentPack *>()) {
44230b57cec5SDimitry Andric     Pack->push_back(cast<VarDecl>(Inst));
44240b57cec5SDimitry Andric   } else {
44250b57cec5SDimitry Andric     assert(Stored.get<Decl *>() == Inst && "Already instantiated this local");
44260b57cec5SDimitry Andric   }
44270b57cec5SDimitry Andric }
44280b57cec5SDimitry Andric 
44290b57cec5SDimitry Andric void LocalInstantiationScope::InstantiatedLocalPackArg(const Decl *D,
44300b57cec5SDimitry Andric                                                        VarDecl *Inst) {
44310b57cec5SDimitry Andric   D = getCanonicalParmVarDecl(D);
44320b57cec5SDimitry Andric   DeclArgumentPack *Pack = LocalDecls[D].get<DeclArgumentPack *>();
44330b57cec5SDimitry Andric   Pack->push_back(Inst);
44340b57cec5SDimitry Andric }
44350b57cec5SDimitry Andric 
44360b57cec5SDimitry Andric void LocalInstantiationScope::MakeInstantiatedLocalArgPack(const Decl *D) {
44370b57cec5SDimitry Andric #ifndef NDEBUG
44380b57cec5SDimitry Andric   // This should be the first time we've been told about this decl.
44390b57cec5SDimitry Andric   for (LocalInstantiationScope *Current = this;
44400b57cec5SDimitry Andric        Current && Current->CombineWithOuterScope; Current = Current->Outer)
44415f757f3fSDimitry Andric     assert(!Current->LocalDecls.contains(D) &&
44420b57cec5SDimitry Andric            "Creating local pack after instantiation of local");
44430b57cec5SDimitry Andric #endif
44440b57cec5SDimitry Andric 
44450b57cec5SDimitry Andric   D = getCanonicalParmVarDecl(D);
44460b57cec5SDimitry Andric   llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored = LocalDecls[D];
44470b57cec5SDimitry Andric   DeclArgumentPack *Pack = new DeclArgumentPack;
44480b57cec5SDimitry Andric   Stored = Pack;
44490b57cec5SDimitry Andric   ArgumentPacks.push_back(Pack);
44500b57cec5SDimitry Andric }
44510b57cec5SDimitry Andric 
44525ffd83dbSDimitry Andric bool LocalInstantiationScope::isLocalPackExpansion(const Decl *D) {
44535ffd83dbSDimitry Andric   for (DeclArgumentPack *Pack : ArgumentPacks)
4454349cc55cSDimitry Andric     if (llvm::is_contained(*Pack, D))
44555ffd83dbSDimitry Andric       return true;
44565ffd83dbSDimitry Andric   return false;
44575ffd83dbSDimitry Andric }
44585ffd83dbSDimitry Andric 
44590b57cec5SDimitry Andric void LocalInstantiationScope::SetPartiallySubstitutedPack(NamedDecl *Pack,
44600b57cec5SDimitry Andric                                           const TemplateArgument *ExplicitArgs,
44610b57cec5SDimitry Andric                                                     unsigned NumExplicitArgs) {
44620b57cec5SDimitry Andric   assert((!PartiallySubstitutedPack || PartiallySubstitutedPack == Pack) &&
44630b57cec5SDimitry Andric          "Already have a partially-substituted pack");
44640b57cec5SDimitry Andric   assert((!PartiallySubstitutedPack
44650b57cec5SDimitry Andric           || NumArgsInPartiallySubstitutedPack == NumExplicitArgs) &&
44660b57cec5SDimitry Andric          "Wrong number of arguments in partially-substituted pack");
44670b57cec5SDimitry Andric   PartiallySubstitutedPack = Pack;
44680b57cec5SDimitry Andric   ArgsInPartiallySubstitutedPack = ExplicitArgs;
44690b57cec5SDimitry Andric   NumArgsInPartiallySubstitutedPack = NumExplicitArgs;
44700b57cec5SDimitry Andric }
44710b57cec5SDimitry Andric 
44720b57cec5SDimitry Andric NamedDecl *LocalInstantiationScope::getPartiallySubstitutedPack(
44730b57cec5SDimitry Andric                                          const TemplateArgument **ExplicitArgs,
44740b57cec5SDimitry Andric                                               unsigned *NumExplicitArgs) const {
44750b57cec5SDimitry Andric   if (ExplicitArgs)
44760b57cec5SDimitry Andric     *ExplicitArgs = nullptr;
44770b57cec5SDimitry Andric   if (NumExplicitArgs)
44780b57cec5SDimitry Andric     *NumExplicitArgs = 0;
44790b57cec5SDimitry Andric 
44800b57cec5SDimitry Andric   for (const LocalInstantiationScope *Current = this; Current;
44810b57cec5SDimitry Andric        Current = Current->Outer) {
44820b57cec5SDimitry Andric     if (Current->PartiallySubstitutedPack) {
44830b57cec5SDimitry Andric       if (ExplicitArgs)
44840b57cec5SDimitry Andric         *ExplicitArgs = Current->ArgsInPartiallySubstitutedPack;
44850b57cec5SDimitry Andric       if (NumExplicitArgs)
44860b57cec5SDimitry Andric         *NumExplicitArgs = Current->NumArgsInPartiallySubstitutedPack;
44870b57cec5SDimitry Andric 
44880b57cec5SDimitry Andric       return Current->PartiallySubstitutedPack;
44890b57cec5SDimitry Andric     }
44900b57cec5SDimitry Andric 
44910b57cec5SDimitry Andric     if (!Current->CombineWithOuterScope)
44920b57cec5SDimitry Andric       break;
44930b57cec5SDimitry Andric   }
44940b57cec5SDimitry Andric 
44950b57cec5SDimitry Andric   return nullptr;
44960b57cec5SDimitry Andric }
4497