1e5dd7070Spatrick //===------- SemaTemplateInstantiate.cpp - C++ Template Instantiation ------===/
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //===----------------------------------------------------------------------===/
7e5dd7070Spatrick //
8e5dd7070Spatrick // This file implements C++ template instantiation.
9e5dd7070Spatrick //
10e5dd7070Spatrick //===----------------------------------------------------------------------===/
11e5dd7070Spatrick
12e5dd7070Spatrick #include "TreeTransform.h"
13*12c85518Srobert #include "clang/AST/ASTConcept.h"
14e5dd7070Spatrick #include "clang/AST/ASTConsumer.h"
15e5dd7070Spatrick #include "clang/AST/ASTContext.h"
16e5dd7070Spatrick #include "clang/AST/ASTLambda.h"
17e5dd7070Spatrick #include "clang/AST/ASTMutationListener.h"
18*12c85518Srobert #include "clang/AST/DeclBase.h"
19e5dd7070Spatrick #include "clang/AST/DeclTemplate.h"
20e5dd7070Spatrick #include "clang/AST/Expr.h"
21*12c85518Srobert #include "clang/AST/ExprConcepts.h"
22e5dd7070Spatrick #include "clang/AST/PrettyDeclStackTrace.h"
23*12c85518Srobert #include "clang/AST/Type.h"
24e5dd7070Spatrick #include "clang/AST/TypeVisitor.h"
25e5dd7070Spatrick #include "clang/Basic/LangOptions.h"
26e5dd7070Spatrick #include "clang/Basic/Stack.h"
27ec727ea7Spatrick #include "clang/Basic/TargetInfo.h"
28e5dd7070Spatrick #include "clang/Sema/DeclSpec.h"
29e5dd7070Spatrick #include "clang/Sema/Initialization.h"
30e5dd7070Spatrick #include "clang/Sema/Lookup.h"
31*12c85518Srobert #include "clang/Sema/Sema.h"
32ec727ea7Spatrick #include "clang/Sema/SemaConcept.h"
33ec727ea7Spatrick #include "clang/Sema/SemaInternal.h"
34e5dd7070Spatrick #include "clang/Sema/Template.h"
35e5dd7070Spatrick #include "clang/Sema/TemplateDeduction.h"
36e5dd7070Spatrick #include "clang/Sema/TemplateInstCallback.h"
37*12c85518Srobert #include "llvm/Support/ErrorHandling.h"
38e5dd7070Spatrick #include "llvm/Support/TimeProfiler.h"
39*12c85518Srobert #include <optional>
40e5dd7070Spatrick
41e5dd7070Spatrick using namespace clang;
42e5dd7070Spatrick using namespace sema;
43e5dd7070Spatrick
44e5dd7070Spatrick //===----------------------------------------------------------------------===/
45e5dd7070Spatrick // Template Instantiation Support
46e5dd7070Spatrick //===----------------------------------------------------------------------===/
47e5dd7070Spatrick
48*12c85518Srobert namespace {
49*12c85518Srobert namespace TemplateInstArgsHelpers {
50*12c85518Srobert struct Response {
51*12c85518Srobert const Decl *NextDecl = nullptr;
52*12c85518Srobert bool IsDone = false;
53*12c85518Srobert bool ClearRelativeToPrimary = true;
Done__anon63295b2c0111::TemplateInstArgsHelpers::Response54*12c85518Srobert static Response Done() {
55*12c85518Srobert Response R;
56*12c85518Srobert R.IsDone = true;
57*12c85518Srobert return R;
58*12c85518Srobert }
ChangeDecl__anon63295b2c0111::TemplateInstArgsHelpers::Response59*12c85518Srobert static Response ChangeDecl(const Decl *ND) {
60*12c85518Srobert Response R;
61*12c85518Srobert R.NextDecl = ND;
62*12c85518Srobert return R;
63*12c85518Srobert }
ChangeDecl__anon63295b2c0111::TemplateInstArgsHelpers::Response64*12c85518Srobert static Response ChangeDecl(const DeclContext *Ctx) {
65*12c85518Srobert Response R;
66*12c85518Srobert R.NextDecl = Decl::castFromDeclContext(Ctx);
67*12c85518Srobert return R;
68*12c85518Srobert }
69e5dd7070Spatrick
UseNextDecl__anon63295b2c0111::TemplateInstArgsHelpers::Response70*12c85518Srobert static Response UseNextDecl(const Decl *CurDecl) {
71*12c85518Srobert return ChangeDecl(CurDecl->getDeclContext());
72*12c85518Srobert }
73e5dd7070Spatrick
DontClearRelativeToPrimaryNextDecl__anon63295b2c0111::TemplateInstArgsHelpers::Response74*12c85518Srobert static Response DontClearRelativeToPrimaryNextDecl(const Decl *CurDecl) {
75*12c85518Srobert Response R = Response::UseNextDecl(CurDecl);
76*12c85518Srobert R.ClearRelativeToPrimary = false;
77*12c85518Srobert return R;
78*12c85518Srobert }
79*12c85518Srobert };
80*12c85518Srobert // Add template arguments from a variable template instantiation.
81*12c85518Srobert Response
HandleVarTemplateSpec(const VarTemplateSpecializationDecl * VarTemplSpec,MultiLevelTemplateArgumentList & Result,bool SkipForSpecialization)82*12c85518Srobert HandleVarTemplateSpec(const VarTemplateSpecializationDecl *VarTemplSpec,
83*12c85518Srobert MultiLevelTemplateArgumentList &Result,
84*12c85518Srobert bool SkipForSpecialization) {
85*12c85518Srobert // For a class-scope explicit specialization, there are no template arguments
86e5dd7070Spatrick // at this level, but there may be enclosing template arguments.
87*12c85518Srobert if (VarTemplSpec->isClassScopeExplicitSpecialization())
88*12c85518Srobert return Response::DontClearRelativeToPrimaryNextDecl(VarTemplSpec);
89e5dd7070Spatrick
90*12c85518Srobert // We're done when we hit an explicit specialization.
91*12c85518Srobert if (VarTemplSpec->getSpecializationKind() == TSK_ExplicitSpecialization &&
92*12c85518Srobert !isa<VarTemplatePartialSpecializationDecl>(VarTemplSpec))
93*12c85518Srobert return Response::Done();
94e5dd7070Spatrick
95e5dd7070Spatrick // If this variable template specialization was instantiated from a
96e5dd7070Spatrick // specialized member that is a variable template, we're done.
97*12c85518Srobert assert(VarTemplSpec->getSpecializedTemplate() && "No variable template?");
98*12c85518Srobert llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
99*12c85518Srobert Specialized = VarTemplSpec->getSpecializedTemplateOrPartial();
100e5dd7070Spatrick if (VarTemplatePartialSpecializationDecl *Partial =
101e5dd7070Spatrick Specialized.dyn_cast<VarTemplatePartialSpecializationDecl *>()) {
102*12c85518Srobert if (!SkipForSpecialization)
103*12c85518Srobert Result.addOuterTemplateArguments(
104*12c85518Srobert Partial, VarTemplSpec->getTemplateInstantiationArgs().asArray(),
105*12c85518Srobert /*Final=*/false);
106e5dd7070Spatrick if (Partial->isMemberSpecialization())
107*12c85518Srobert return Response::Done();
108e5dd7070Spatrick } else {
109e5dd7070Spatrick VarTemplateDecl *Tmpl = Specialized.get<VarTemplateDecl *>();
110*12c85518Srobert if (!SkipForSpecialization)
111*12c85518Srobert Result.addOuterTemplateArguments(
112*12c85518Srobert Tmpl, VarTemplSpec->getTemplateInstantiationArgs().asArray(),
113*12c85518Srobert /*Final=*/false);
114e5dd7070Spatrick if (Tmpl->isMemberSpecialization())
115*12c85518Srobert return Response::Done();
116e5dd7070Spatrick }
117*12c85518Srobert return Response::DontClearRelativeToPrimaryNextDecl(VarTemplSpec);
118e5dd7070Spatrick }
119e5dd7070Spatrick
120e5dd7070Spatrick // If we have a template template parameter with translation unit context,
121e5dd7070Spatrick // then we're performing substitution into a default template argument of
122e5dd7070Spatrick // this template template parameter before we've constructed the template
123e5dd7070Spatrick // that will own this template template parameter. In this case, we
124e5dd7070Spatrick // use empty template parameter lists for all of the outer templates
125e5dd7070Spatrick // to avoid performing any substitutions.
126*12c85518Srobert Response
HandleDefaultTempArgIntoTempTempParam(const TemplateTemplateParmDecl * TTP,MultiLevelTemplateArgumentList & Result)127*12c85518Srobert HandleDefaultTempArgIntoTempTempParam(const TemplateTemplateParmDecl *TTP,
128*12c85518Srobert MultiLevelTemplateArgumentList &Result) {
129e5dd7070Spatrick for (unsigned I = 0, N = TTP->getDepth() + 1; I != N; ++I)
130*12c85518Srobert Result.addOuterTemplateArguments(std::nullopt);
131*12c85518Srobert return Response::Done();
132e5dd7070Spatrick }
133e5dd7070Spatrick
134e5dd7070Spatrick // Add template arguments from a class template instantiation.
135*12c85518Srobert Response
HandleClassTemplateSpec(const ClassTemplateSpecializationDecl * ClassTemplSpec,MultiLevelTemplateArgumentList & Result,bool SkipForSpecialization)136*12c85518Srobert HandleClassTemplateSpec(const ClassTemplateSpecializationDecl *ClassTemplSpec,
137*12c85518Srobert MultiLevelTemplateArgumentList &Result,
138*12c85518Srobert bool SkipForSpecialization) {
139*12c85518Srobert if (!ClassTemplSpec->isClassScopeExplicitSpecialization()) {
140e5dd7070Spatrick // We're done when we hit an explicit specialization.
141*12c85518Srobert if (ClassTemplSpec->getSpecializationKind() == TSK_ExplicitSpecialization &&
142*12c85518Srobert !isa<ClassTemplatePartialSpecializationDecl>(ClassTemplSpec))
143*12c85518Srobert return Response::Done();
144e5dd7070Spatrick
145*12c85518Srobert if (!SkipForSpecialization)
146*12c85518Srobert Result.addOuterTemplateArguments(
147*12c85518Srobert const_cast<ClassTemplateSpecializationDecl *>(ClassTemplSpec),
148*12c85518Srobert ClassTemplSpec->getTemplateInstantiationArgs().asArray(),
149*12c85518Srobert /*Final=*/false);
150e5dd7070Spatrick
151e5dd7070Spatrick // If this class template specialization was instantiated from a
152e5dd7070Spatrick // specialized member that is a class template, we're done.
153*12c85518Srobert assert(ClassTemplSpec->getSpecializedTemplate() && "No class template?");
154*12c85518Srobert if (ClassTemplSpec->getSpecializedTemplate()->isMemberSpecialization())
155*12c85518Srobert return Response::Done();
156e5dd7070Spatrick }
157*12c85518Srobert return Response::UseNextDecl(ClassTemplSpec);
158*12c85518Srobert }
159*12c85518Srobert
HandleFunction(const FunctionDecl * Function,MultiLevelTemplateArgumentList & Result,const FunctionDecl * Pattern,bool RelativeToPrimary,bool ForConstraintInstantiation)160*12c85518Srobert Response HandleFunction(const FunctionDecl *Function,
161*12c85518Srobert MultiLevelTemplateArgumentList &Result,
162*12c85518Srobert const FunctionDecl *Pattern, bool RelativeToPrimary,
163*12c85518Srobert bool ForConstraintInstantiation) {
164e5dd7070Spatrick // Add template arguments from a function template specialization.
165e5dd7070Spatrick if (!RelativeToPrimary &&
166e5dd7070Spatrick Function->getTemplateSpecializationKindForInstantiation() ==
167e5dd7070Spatrick TSK_ExplicitSpecialization)
168*12c85518Srobert return Response::Done();
169e5dd7070Spatrick
170*12c85518Srobert if (!RelativeToPrimary &&
171*12c85518Srobert Function->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) {
172a9ac8606Spatrick // This is an implicit instantiation of an explicit specialization. We
173a9ac8606Spatrick // don't get any template arguments from this function but might get
174a9ac8606Spatrick // some from an enclosing template.
175*12c85518Srobert return Response::UseNextDecl(Function);
176*12c85518Srobert } else if (const TemplateArgumentList *TemplateArgs =
177*12c85518Srobert Function->getTemplateSpecializationArgs()) {
178e5dd7070Spatrick // Add the template arguments for this specialization.
179*12c85518Srobert Result.addOuterTemplateArguments(const_cast<FunctionDecl *>(Function),
180*12c85518Srobert TemplateArgs->asArray(),
181*12c85518Srobert /*Final=*/false);
182e5dd7070Spatrick
183e5dd7070Spatrick // If this function was instantiated from a specialized member that is
184e5dd7070Spatrick // a function template, we're done.
185e5dd7070Spatrick assert(Function->getPrimaryTemplate() && "No function template?");
186e5dd7070Spatrick if (Function->getPrimaryTemplate()->isMemberSpecialization())
187*12c85518Srobert return Response::Done();
188e5dd7070Spatrick
189e5dd7070Spatrick // If this function is a generic lambda specialization, we are done.
190*12c85518Srobert if (!ForConstraintInstantiation &&
191*12c85518Srobert isGenericLambdaCallOperatorOrStaticInvokerSpecialization(Function))
192*12c85518Srobert return Response::Done();
193e5dd7070Spatrick
194*12c85518Srobert } else if (Function->getDescribedFunctionTemplate()) {
195*12c85518Srobert assert(
196*12c85518Srobert (ForConstraintInstantiation || Result.getNumSubstitutedLevels() == 0) &&
197*12c85518Srobert "Outer template not instantiated?");
198e5dd7070Spatrick }
199*12c85518Srobert // If this is a friend or local declaration and it declares an entity at
200e5dd7070Spatrick // namespace scope, take arguments from its lexical parent
201e5dd7070Spatrick // instead of its semantic parent, unless of course the pattern we're
202e5dd7070Spatrick // instantiating actually comes from the file's context!
203*12c85518Srobert if ((Function->getFriendObjectKind() || Function->isLocalExternDecl()) &&
204*12c85518Srobert Function->getNonTransparentDeclContext()->isFileContext() &&
205e5dd7070Spatrick (!Pattern || !Pattern->getLexicalDeclContext()->isFileContext())) {
206*12c85518Srobert return Response::ChangeDecl(Function->getLexicalDeclContext());
207e5dd7070Spatrick }
208*12c85518Srobert return Response::UseNextDecl(Function);
209*12c85518Srobert }
210*12c85518Srobert
HandleRecordDecl(const CXXRecordDecl * Rec,MultiLevelTemplateArgumentList & Result,ASTContext & Context,bool ForConstraintInstantiation)211*12c85518Srobert Response HandleRecordDecl(const CXXRecordDecl *Rec,
212*12c85518Srobert MultiLevelTemplateArgumentList &Result,
213*12c85518Srobert ASTContext &Context,
214*12c85518Srobert bool ForConstraintInstantiation) {
215e5dd7070Spatrick if (ClassTemplateDecl *ClassTemplate = Rec->getDescribedClassTemplate()) {
216*12c85518Srobert assert(
217*12c85518Srobert (ForConstraintInstantiation || Result.getNumSubstitutedLevels() == 0) &&
218*12c85518Srobert "Outer template not instantiated?");
219e5dd7070Spatrick if (ClassTemplate->isMemberSpecialization())
220*12c85518Srobert return Response::Done();
221*12c85518Srobert if (ForConstraintInstantiation) {
222*12c85518Srobert QualType RecordType = Context.getTypeDeclType(Rec);
223*12c85518Srobert QualType Injected = cast<InjectedClassNameType>(RecordType)
224*12c85518Srobert ->getInjectedSpecializationType();
225*12c85518Srobert const auto *InjectedType = cast<TemplateSpecializationType>(Injected);
226*12c85518Srobert Result.addOuterTemplateArguments(const_cast<CXXRecordDecl *>(Rec),
227*12c85518Srobert InjectedType->template_arguments(),
228*12c85518Srobert /*Final=*/false);
229e5dd7070Spatrick }
230e5dd7070Spatrick }
231e5dd7070Spatrick
232*12c85518Srobert bool IsFriend = Rec->getFriendObjectKind() ||
233*12c85518Srobert (Rec->getDescribedClassTemplate() &&
234*12c85518Srobert Rec->getDescribedClassTemplate()->getFriendObjectKind());
235*12c85518Srobert if (ForConstraintInstantiation && IsFriend &&
236*12c85518Srobert Rec->getNonTransparentDeclContext()->isFileContext()) {
237*12c85518Srobert return Response::ChangeDecl(Rec->getLexicalDeclContext());
238*12c85518Srobert }
239*12c85518Srobert
240*12c85518Srobert // This is to make sure we pick up the VarTemplateSpecializationDecl that this
241*12c85518Srobert // lambda is defined inside of.
242*12c85518Srobert if (Rec->isLambda())
243*12c85518Srobert if (const Decl *LCD = Rec->getLambdaContextDecl())
244*12c85518Srobert return Response::ChangeDecl(LCD);
245*12c85518Srobert
246*12c85518Srobert return Response::UseNextDecl(Rec);
247*12c85518Srobert }
248*12c85518Srobert
HandleImplicitConceptSpecializationDecl(const ImplicitConceptSpecializationDecl * CSD,MultiLevelTemplateArgumentList & Result)249*12c85518Srobert Response HandleImplicitConceptSpecializationDecl(
250*12c85518Srobert const ImplicitConceptSpecializationDecl *CSD,
251*12c85518Srobert MultiLevelTemplateArgumentList &Result) {
252*12c85518Srobert Result.addOuterTemplateArguments(
253*12c85518Srobert const_cast<ImplicitConceptSpecializationDecl *>(CSD),
254*12c85518Srobert CSD->getTemplateArguments(),
255*12c85518Srobert /*Final=*/false);
256*12c85518Srobert return Response::UseNextDecl(CSD);
257*12c85518Srobert }
258*12c85518Srobert
HandleGenericDeclContext(const Decl * CurDecl)259*12c85518Srobert Response HandleGenericDeclContext(const Decl *CurDecl) {
260*12c85518Srobert return Response::UseNextDecl(CurDecl);
261*12c85518Srobert }
262*12c85518Srobert } // namespace TemplateInstArgsHelpers
263*12c85518Srobert } // namespace
264*12c85518Srobert
265*12c85518Srobert /// Retrieve the template argument list(s) that should be used to
266*12c85518Srobert /// instantiate the definition of the given declaration.
267*12c85518Srobert ///
268*12c85518Srobert /// \param ND the declaration for which we are computing template instantiation
269*12c85518Srobert /// arguments.
270*12c85518Srobert ///
271*12c85518Srobert /// \param Innermost if non-NULL, specifies a template argument list for the
272*12c85518Srobert /// template declaration passed as ND.
273*12c85518Srobert ///
274*12c85518Srobert /// \param RelativeToPrimary true if we should get the template
275*12c85518Srobert /// arguments relative to the primary template, even when we're
276*12c85518Srobert /// dealing with a specialization. This is only relevant for function
277*12c85518Srobert /// template specializations.
278*12c85518Srobert ///
279*12c85518Srobert /// \param Pattern If non-NULL, indicates the pattern from which we will be
280*12c85518Srobert /// instantiating the definition of the given declaration, \p ND. This is
281*12c85518Srobert /// used to determine the proper set of template instantiation arguments for
282*12c85518Srobert /// friend function template specializations.
283*12c85518Srobert ///
284*12c85518Srobert /// \param ForConstraintInstantiation when collecting arguments,
285*12c85518Srobert /// ForConstraintInstantiation indicates we should continue looking when
286*12c85518Srobert /// encountering a lambda generic call operator, and continue looking for
287*12c85518Srobert /// arguments on an enclosing class template.
288*12c85518Srobert
getTemplateInstantiationArgs(const NamedDecl * ND,bool Final,const TemplateArgumentList * Innermost,bool RelativeToPrimary,const FunctionDecl * Pattern,bool ForConstraintInstantiation,bool SkipForSpecialization)289*12c85518Srobert MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs(
290*12c85518Srobert const NamedDecl *ND, bool Final, const TemplateArgumentList *Innermost,
291*12c85518Srobert bool RelativeToPrimary, const FunctionDecl *Pattern,
292*12c85518Srobert bool ForConstraintInstantiation, bool SkipForSpecialization) {
293*12c85518Srobert assert(ND && "Can't find arguments for a decl if one isn't provided");
294*12c85518Srobert // Accumulate the set of template argument lists in this structure.
295*12c85518Srobert MultiLevelTemplateArgumentList Result;
296*12c85518Srobert
297*12c85518Srobert if (Innermost)
298*12c85518Srobert Result.addOuterTemplateArguments(const_cast<NamedDecl *>(ND),
299*12c85518Srobert Innermost->asArray(), Final);
300*12c85518Srobert
301*12c85518Srobert const Decl *CurDecl = ND;
302*12c85518Srobert
303*12c85518Srobert while (!CurDecl->isFileContextDecl()) {
304*12c85518Srobert using namespace TemplateInstArgsHelpers;
305*12c85518Srobert Response R;
306*12c85518Srobert if (const auto *VarTemplSpec =
307*12c85518Srobert dyn_cast<VarTemplateSpecializationDecl>(CurDecl)) {
308*12c85518Srobert R = HandleVarTemplateSpec(VarTemplSpec, Result, SkipForSpecialization);
309*12c85518Srobert } else if (const auto *ClassTemplSpec =
310*12c85518Srobert dyn_cast<ClassTemplateSpecializationDecl>(CurDecl)) {
311*12c85518Srobert R = HandleClassTemplateSpec(ClassTemplSpec, Result,
312*12c85518Srobert SkipForSpecialization);
313*12c85518Srobert } else if (const auto *Function = dyn_cast<FunctionDecl>(CurDecl)) {
314*12c85518Srobert R = HandleFunction(Function, Result, Pattern, RelativeToPrimary,
315*12c85518Srobert ForConstraintInstantiation);
316*12c85518Srobert } else if (const auto *Rec = dyn_cast<CXXRecordDecl>(CurDecl)) {
317*12c85518Srobert R = HandleRecordDecl(Rec, Result, Context, ForConstraintInstantiation);
318*12c85518Srobert } else if (const auto *CSD =
319*12c85518Srobert dyn_cast<ImplicitConceptSpecializationDecl>(CurDecl)) {
320*12c85518Srobert R = HandleImplicitConceptSpecializationDecl(CSD, Result);
321*12c85518Srobert } else if (!isa<DeclContext>(CurDecl)) {
322*12c85518Srobert R = Response::DontClearRelativeToPrimaryNextDecl(CurDecl);
323*12c85518Srobert if (CurDecl->getDeclContext()->isTranslationUnit()) {
324*12c85518Srobert if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(CurDecl)) {
325*12c85518Srobert R = HandleDefaultTempArgIntoTempTempParam(TTP, Result);
326*12c85518Srobert }
327*12c85518Srobert }
328*12c85518Srobert } else {
329*12c85518Srobert R = HandleGenericDeclContext(CurDecl);
330*12c85518Srobert }
331*12c85518Srobert
332*12c85518Srobert if (R.IsDone)
333*12c85518Srobert return Result;
334*12c85518Srobert if (R.ClearRelativeToPrimary)
335e5dd7070Spatrick RelativeToPrimary = false;
336*12c85518Srobert assert(R.NextDecl);
337*12c85518Srobert CurDecl = R.NextDecl;
338e5dd7070Spatrick }
339e5dd7070Spatrick
340e5dd7070Spatrick return Result;
341e5dd7070Spatrick }
342e5dd7070Spatrick
isInstantiationRecord() const343e5dd7070Spatrick bool Sema::CodeSynthesisContext::isInstantiationRecord() const {
344e5dd7070Spatrick switch (Kind) {
345e5dd7070Spatrick case TemplateInstantiation:
346e5dd7070Spatrick case ExceptionSpecInstantiation:
347e5dd7070Spatrick case DefaultTemplateArgumentInstantiation:
348e5dd7070Spatrick case DefaultFunctionArgumentInstantiation:
349e5dd7070Spatrick case ExplicitTemplateArgumentSubstitution:
350e5dd7070Spatrick case DeducedTemplateArgumentSubstitution:
351e5dd7070Spatrick case PriorTemplateArgumentSubstitution:
352e5dd7070Spatrick case ConstraintsCheck:
353e5dd7070Spatrick case NestedRequirementConstraintsCheck:
354e5dd7070Spatrick return true;
355e5dd7070Spatrick
356e5dd7070Spatrick case RequirementInstantiation:
357*12c85518Srobert case RequirementParameterInstantiation:
358e5dd7070Spatrick case DefaultTemplateArgumentChecking:
359e5dd7070Spatrick case DeclaringSpecialMember:
360e5dd7070Spatrick case DeclaringImplicitEqualityComparison:
361e5dd7070Spatrick case DefiningSynthesizedFunction:
362e5dd7070Spatrick case ExceptionSpecEvaluation:
363e5dd7070Spatrick case ConstraintSubstitution:
364e5dd7070Spatrick case ParameterMappingSubstitution:
365e5dd7070Spatrick case ConstraintNormalization:
366e5dd7070Spatrick case RewritingOperatorAsSpaceship:
367ec727ea7Spatrick case InitializingStructuredBinding:
368ec727ea7Spatrick case MarkingClassDllexported:
369*12c85518Srobert case BuildingBuiltinDumpStructCall:
370e5dd7070Spatrick return false;
371e5dd7070Spatrick
372e5dd7070Spatrick // This function should never be called when Kind's value is Memoization.
373e5dd7070Spatrick case Memoization:
374e5dd7070Spatrick break;
375e5dd7070Spatrick }
376e5dd7070Spatrick
377e5dd7070Spatrick llvm_unreachable("Invalid SynthesisKind!");
378e5dd7070Spatrick }
379e5dd7070Spatrick
InstantiatingTemplate(Sema & SemaRef,CodeSynthesisContext::SynthesisKind Kind,SourceLocation PointOfInstantiation,SourceRange InstantiationRange,Decl * Entity,NamedDecl * Template,ArrayRef<TemplateArgument> TemplateArgs,sema::TemplateDeductionInfo * DeductionInfo)380e5dd7070Spatrick Sema::InstantiatingTemplate::InstantiatingTemplate(
381e5dd7070Spatrick Sema &SemaRef, CodeSynthesisContext::SynthesisKind Kind,
382e5dd7070Spatrick SourceLocation PointOfInstantiation, SourceRange InstantiationRange,
383e5dd7070Spatrick Decl *Entity, NamedDecl *Template, ArrayRef<TemplateArgument> TemplateArgs,
384e5dd7070Spatrick sema::TemplateDeductionInfo *DeductionInfo)
385e5dd7070Spatrick : SemaRef(SemaRef) {
386e5dd7070Spatrick // Don't allow further instantiation if a fatal error and an uncompilable
387e5dd7070Spatrick // error have occurred. Any diagnostics we might have raised will not be
388e5dd7070Spatrick // visible, and we do not need to construct a correct AST.
389e5dd7070Spatrick if (SemaRef.Diags.hasFatalErrorOccurred() &&
390a9ac8606Spatrick SemaRef.hasUncompilableErrorOccurred()) {
391e5dd7070Spatrick Invalid = true;
392e5dd7070Spatrick return;
393e5dd7070Spatrick }
394e5dd7070Spatrick Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
395e5dd7070Spatrick if (!Invalid) {
396e5dd7070Spatrick CodeSynthesisContext Inst;
397e5dd7070Spatrick Inst.Kind = Kind;
398e5dd7070Spatrick Inst.PointOfInstantiation = PointOfInstantiation;
399e5dd7070Spatrick Inst.Entity = Entity;
400e5dd7070Spatrick Inst.Template = Template;
401e5dd7070Spatrick Inst.TemplateArgs = TemplateArgs.data();
402e5dd7070Spatrick Inst.NumTemplateArgs = TemplateArgs.size();
403e5dd7070Spatrick Inst.DeductionInfo = DeductionInfo;
404e5dd7070Spatrick Inst.InstantiationRange = InstantiationRange;
405e5dd7070Spatrick SemaRef.pushCodeSynthesisContext(Inst);
406e5dd7070Spatrick
407e5dd7070Spatrick AlreadyInstantiating = !Inst.Entity ? false :
408e5dd7070Spatrick !SemaRef.InstantiatingSpecializations
409a9ac8606Spatrick .insert({Inst.Entity->getCanonicalDecl(), Inst.Kind})
410e5dd7070Spatrick .second;
411e5dd7070Spatrick atTemplateBegin(SemaRef.TemplateInstCallbacks, SemaRef, Inst);
412e5dd7070Spatrick }
413e5dd7070Spatrick }
414e5dd7070Spatrick
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,Decl * Entity,SourceRange InstantiationRange)415e5dd7070Spatrick Sema::InstantiatingTemplate::InstantiatingTemplate(
416e5dd7070Spatrick Sema &SemaRef, SourceLocation PointOfInstantiation, Decl *Entity,
417e5dd7070Spatrick SourceRange InstantiationRange)
418e5dd7070Spatrick : InstantiatingTemplate(SemaRef,
419e5dd7070Spatrick CodeSynthesisContext::TemplateInstantiation,
420e5dd7070Spatrick PointOfInstantiation, InstantiationRange, Entity) {}
421e5dd7070Spatrick
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,FunctionDecl * Entity,ExceptionSpecification,SourceRange InstantiationRange)422e5dd7070Spatrick Sema::InstantiatingTemplate::InstantiatingTemplate(
423e5dd7070Spatrick Sema &SemaRef, SourceLocation PointOfInstantiation, FunctionDecl *Entity,
424e5dd7070Spatrick ExceptionSpecification, SourceRange InstantiationRange)
425e5dd7070Spatrick : InstantiatingTemplate(
426e5dd7070Spatrick SemaRef, CodeSynthesisContext::ExceptionSpecInstantiation,
427e5dd7070Spatrick PointOfInstantiation, InstantiationRange, Entity) {}
428e5dd7070Spatrick
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,TemplateParameter Param,TemplateDecl * Template,ArrayRef<TemplateArgument> TemplateArgs,SourceRange InstantiationRange)429e5dd7070Spatrick Sema::InstantiatingTemplate::InstantiatingTemplate(
430e5dd7070Spatrick Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateParameter Param,
431e5dd7070Spatrick TemplateDecl *Template, ArrayRef<TemplateArgument> TemplateArgs,
432e5dd7070Spatrick SourceRange InstantiationRange)
433e5dd7070Spatrick : InstantiatingTemplate(
434e5dd7070Spatrick SemaRef,
435e5dd7070Spatrick CodeSynthesisContext::DefaultTemplateArgumentInstantiation,
436e5dd7070Spatrick PointOfInstantiation, InstantiationRange, getAsNamedDecl(Param),
437e5dd7070Spatrick Template, TemplateArgs) {}
438e5dd7070Spatrick
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,FunctionTemplateDecl * FunctionTemplate,ArrayRef<TemplateArgument> TemplateArgs,CodeSynthesisContext::SynthesisKind Kind,sema::TemplateDeductionInfo & DeductionInfo,SourceRange InstantiationRange)439e5dd7070Spatrick Sema::InstantiatingTemplate::InstantiatingTemplate(
440e5dd7070Spatrick Sema &SemaRef, SourceLocation PointOfInstantiation,
441e5dd7070Spatrick FunctionTemplateDecl *FunctionTemplate,
442e5dd7070Spatrick ArrayRef<TemplateArgument> TemplateArgs,
443e5dd7070Spatrick CodeSynthesisContext::SynthesisKind Kind,
444e5dd7070Spatrick sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
445e5dd7070Spatrick : InstantiatingTemplate(SemaRef, Kind, PointOfInstantiation,
446e5dd7070Spatrick InstantiationRange, FunctionTemplate, nullptr,
447e5dd7070Spatrick TemplateArgs, &DeductionInfo) {
448e5dd7070Spatrick assert(
449e5dd7070Spatrick Kind == CodeSynthesisContext::ExplicitTemplateArgumentSubstitution ||
450e5dd7070Spatrick Kind == CodeSynthesisContext::DeducedTemplateArgumentSubstitution);
451e5dd7070Spatrick }
452e5dd7070Spatrick
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,TemplateDecl * Template,ArrayRef<TemplateArgument> TemplateArgs,sema::TemplateDeductionInfo & DeductionInfo,SourceRange InstantiationRange)453e5dd7070Spatrick Sema::InstantiatingTemplate::InstantiatingTemplate(
454e5dd7070Spatrick Sema &SemaRef, SourceLocation PointOfInstantiation,
455e5dd7070Spatrick TemplateDecl *Template,
456e5dd7070Spatrick ArrayRef<TemplateArgument> TemplateArgs,
457e5dd7070Spatrick sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
458e5dd7070Spatrick : InstantiatingTemplate(
459e5dd7070Spatrick SemaRef,
460e5dd7070Spatrick CodeSynthesisContext::DeducedTemplateArgumentSubstitution,
461e5dd7070Spatrick PointOfInstantiation, InstantiationRange, Template, nullptr,
462e5dd7070Spatrick TemplateArgs, &DeductionInfo) {}
463e5dd7070Spatrick
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,ClassTemplatePartialSpecializationDecl * PartialSpec,ArrayRef<TemplateArgument> TemplateArgs,sema::TemplateDeductionInfo & DeductionInfo,SourceRange InstantiationRange)464e5dd7070Spatrick Sema::InstantiatingTemplate::InstantiatingTemplate(
465e5dd7070Spatrick Sema &SemaRef, SourceLocation PointOfInstantiation,
466e5dd7070Spatrick ClassTemplatePartialSpecializationDecl *PartialSpec,
467e5dd7070Spatrick ArrayRef<TemplateArgument> TemplateArgs,
468e5dd7070Spatrick sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
469e5dd7070Spatrick : InstantiatingTemplate(
470e5dd7070Spatrick SemaRef,
471e5dd7070Spatrick CodeSynthesisContext::DeducedTemplateArgumentSubstitution,
472e5dd7070Spatrick PointOfInstantiation, InstantiationRange, PartialSpec, nullptr,
473e5dd7070Spatrick TemplateArgs, &DeductionInfo) {}
474e5dd7070Spatrick
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,VarTemplatePartialSpecializationDecl * PartialSpec,ArrayRef<TemplateArgument> TemplateArgs,sema::TemplateDeductionInfo & DeductionInfo,SourceRange InstantiationRange)475e5dd7070Spatrick Sema::InstantiatingTemplate::InstantiatingTemplate(
476e5dd7070Spatrick Sema &SemaRef, SourceLocation PointOfInstantiation,
477e5dd7070Spatrick VarTemplatePartialSpecializationDecl *PartialSpec,
478e5dd7070Spatrick ArrayRef<TemplateArgument> TemplateArgs,
479e5dd7070Spatrick sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
480e5dd7070Spatrick : InstantiatingTemplate(
481e5dd7070Spatrick SemaRef,
482e5dd7070Spatrick CodeSynthesisContext::DeducedTemplateArgumentSubstitution,
483e5dd7070Spatrick PointOfInstantiation, InstantiationRange, PartialSpec, nullptr,
484e5dd7070Spatrick TemplateArgs, &DeductionInfo) {}
485e5dd7070Spatrick
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,ParmVarDecl * Param,ArrayRef<TemplateArgument> TemplateArgs,SourceRange InstantiationRange)486e5dd7070Spatrick Sema::InstantiatingTemplate::InstantiatingTemplate(
487e5dd7070Spatrick Sema &SemaRef, SourceLocation PointOfInstantiation, ParmVarDecl *Param,
488e5dd7070Spatrick ArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange)
489e5dd7070Spatrick : InstantiatingTemplate(
490e5dd7070Spatrick SemaRef,
491e5dd7070Spatrick CodeSynthesisContext::DefaultFunctionArgumentInstantiation,
492e5dd7070Spatrick PointOfInstantiation, InstantiationRange, Param, nullptr,
493e5dd7070Spatrick TemplateArgs) {}
494e5dd7070Spatrick
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,NamedDecl * Template,NonTypeTemplateParmDecl * Param,ArrayRef<TemplateArgument> TemplateArgs,SourceRange InstantiationRange)495e5dd7070Spatrick Sema::InstantiatingTemplate::InstantiatingTemplate(
496e5dd7070Spatrick Sema &SemaRef, SourceLocation PointOfInstantiation, NamedDecl *Template,
497e5dd7070Spatrick NonTypeTemplateParmDecl *Param, ArrayRef<TemplateArgument> TemplateArgs,
498e5dd7070Spatrick SourceRange InstantiationRange)
499e5dd7070Spatrick : InstantiatingTemplate(
500e5dd7070Spatrick SemaRef,
501e5dd7070Spatrick CodeSynthesisContext::PriorTemplateArgumentSubstitution,
502e5dd7070Spatrick PointOfInstantiation, InstantiationRange, Param, Template,
503e5dd7070Spatrick TemplateArgs) {}
504e5dd7070Spatrick
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,NamedDecl * Template,TemplateTemplateParmDecl * Param,ArrayRef<TemplateArgument> TemplateArgs,SourceRange InstantiationRange)505e5dd7070Spatrick Sema::InstantiatingTemplate::InstantiatingTemplate(
506e5dd7070Spatrick Sema &SemaRef, SourceLocation PointOfInstantiation, NamedDecl *Template,
507e5dd7070Spatrick TemplateTemplateParmDecl *Param, ArrayRef<TemplateArgument> TemplateArgs,
508e5dd7070Spatrick SourceRange InstantiationRange)
509e5dd7070Spatrick : InstantiatingTemplate(
510e5dd7070Spatrick SemaRef,
511e5dd7070Spatrick CodeSynthesisContext::PriorTemplateArgumentSubstitution,
512e5dd7070Spatrick PointOfInstantiation, InstantiationRange, Param, Template,
513e5dd7070Spatrick TemplateArgs) {}
514e5dd7070Spatrick
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,TemplateDecl * Template,NamedDecl * Param,ArrayRef<TemplateArgument> TemplateArgs,SourceRange InstantiationRange)515e5dd7070Spatrick Sema::InstantiatingTemplate::InstantiatingTemplate(
516e5dd7070Spatrick Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateDecl *Template,
517e5dd7070Spatrick NamedDecl *Param, ArrayRef<TemplateArgument> TemplateArgs,
518e5dd7070Spatrick SourceRange InstantiationRange)
519e5dd7070Spatrick : InstantiatingTemplate(
520e5dd7070Spatrick SemaRef, CodeSynthesisContext::DefaultTemplateArgumentChecking,
521e5dd7070Spatrick PointOfInstantiation, InstantiationRange, Param, Template,
522e5dd7070Spatrick TemplateArgs) {}
523e5dd7070Spatrick
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,concepts::Requirement * Req,sema::TemplateDeductionInfo & DeductionInfo,SourceRange InstantiationRange)524e5dd7070Spatrick Sema::InstantiatingTemplate::InstantiatingTemplate(
525e5dd7070Spatrick Sema &SemaRef, SourceLocation PointOfInstantiation,
526e5dd7070Spatrick concepts::Requirement *Req, sema::TemplateDeductionInfo &DeductionInfo,
527e5dd7070Spatrick SourceRange InstantiationRange)
528e5dd7070Spatrick : InstantiatingTemplate(
529e5dd7070Spatrick SemaRef, CodeSynthesisContext::RequirementInstantiation,
530e5dd7070Spatrick PointOfInstantiation, InstantiationRange, /*Entity=*/nullptr,
531*12c85518Srobert /*Template=*/nullptr, /*TemplateArgs=*/std::nullopt, &DeductionInfo) {
532*12c85518Srobert }
533e5dd7070Spatrick
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,concepts::NestedRequirement * Req,ConstraintsCheck,SourceRange InstantiationRange)534e5dd7070Spatrick Sema::InstantiatingTemplate::InstantiatingTemplate(
535e5dd7070Spatrick Sema &SemaRef, SourceLocation PointOfInstantiation,
536e5dd7070Spatrick concepts::NestedRequirement *Req, ConstraintsCheck,
537e5dd7070Spatrick SourceRange InstantiationRange)
538e5dd7070Spatrick : InstantiatingTemplate(
539e5dd7070Spatrick SemaRef, CodeSynthesisContext::NestedRequirementConstraintsCheck,
540e5dd7070Spatrick PointOfInstantiation, InstantiationRange, /*Entity=*/nullptr,
541*12c85518Srobert /*Template=*/nullptr, /*TemplateArgs=*/std::nullopt) {}
542e5dd7070Spatrick
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,const RequiresExpr * RE,sema::TemplateDeductionInfo & DeductionInfo,SourceRange InstantiationRange)543*12c85518Srobert Sema::InstantiatingTemplate::InstantiatingTemplate(
544*12c85518Srobert Sema &SemaRef, SourceLocation PointOfInstantiation, const RequiresExpr *RE,
545*12c85518Srobert sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
546*12c85518Srobert : InstantiatingTemplate(
547*12c85518Srobert SemaRef, CodeSynthesisContext::RequirementParameterInstantiation,
548*12c85518Srobert PointOfInstantiation, InstantiationRange, /*Entity=*/nullptr,
549*12c85518Srobert /*Template=*/nullptr, /*TemplateArgs=*/std::nullopt, &DeductionInfo) {
550*12c85518Srobert }
551e5dd7070Spatrick
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,ConstraintsCheck,NamedDecl * Template,ArrayRef<TemplateArgument> TemplateArgs,SourceRange InstantiationRange)552e5dd7070Spatrick Sema::InstantiatingTemplate::InstantiatingTemplate(
553e5dd7070Spatrick Sema &SemaRef, SourceLocation PointOfInstantiation,
554e5dd7070Spatrick ConstraintsCheck, NamedDecl *Template,
555e5dd7070Spatrick ArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange)
556e5dd7070Spatrick : InstantiatingTemplate(
557e5dd7070Spatrick SemaRef, CodeSynthesisContext::ConstraintsCheck,
558e5dd7070Spatrick PointOfInstantiation, InstantiationRange, Template, nullptr,
559e5dd7070Spatrick TemplateArgs) {}
560e5dd7070Spatrick
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,ConstraintSubstitution,NamedDecl * Template,sema::TemplateDeductionInfo & DeductionInfo,SourceRange InstantiationRange)561e5dd7070Spatrick Sema::InstantiatingTemplate::InstantiatingTemplate(
562e5dd7070Spatrick Sema &SemaRef, SourceLocation PointOfInstantiation,
563e5dd7070Spatrick ConstraintSubstitution, NamedDecl *Template,
564e5dd7070Spatrick sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
565e5dd7070Spatrick : InstantiatingTemplate(
566e5dd7070Spatrick SemaRef, CodeSynthesisContext::ConstraintSubstitution,
567e5dd7070Spatrick PointOfInstantiation, InstantiationRange, Template, nullptr,
568e5dd7070Spatrick {}, &DeductionInfo) {}
569e5dd7070Spatrick
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,ConstraintNormalization,NamedDecl * Template,SourceRange InstantiationRange)570e5dd7070Spatrick Sema::InstantiatingTemplate::InstantiatingTemplate(
571e5dd7070Spatrick Sema &SemaRef, SourceLocation PointOfInstantiation,
572e5dd7070Spatrick ConstraintNormalization, NamedDecl *Template,
573e5dd7070Spatrick SourceRange InstantiationRange)
574e5dd7070Spatrick : InstantiatingTemplate(
575e5dd7070Spatrick SemaRef, CodeSynthesisContext::ConstraintNormalization,
576e5dd7070Spatrick PointOfInstantiation, InstantiationRange, Template) {}
577e5dd7070Spatrick
InstantiatingTemplate(Sema & SemaRef,SourceLocation PointOfInstantiation,ParameterMappingSubstitution,NamedDecl * Template,SourceRange InstantiationRange)578e5dd7070Spatrick Sema::InstantiatingTemplate::InstantiatingTemplate(
579e5dd7070Spatrick Sema &SemaRef, SourceLocation PointOfInstantiation,
580e5dd7070Spatrick ParameterMappingSubstitution, NamedDecl *Template,
581e5dd7070Spatrick SourceRange InstantiationRange)
582e5dd7070Spatrick : InstantiatingTemplate(
583e5dd7070Spatrick SemaRef, CodeSynthesisContext::ParameterMappingSubstitution,
584e5dd7070Spatrick PointOfInstantiation, InstantiationRange, Template) {}
585e5dd7070Spatrick
586*12c85518Srobert
pushCodeSynthesisContext(CodeSynthesisContext Ctx)587e5dd7070Spatrick void Sema::pushCodeSynthesisContext(CodeSynthesisContext Ctx) {
588e5dd7070Spatrick Ctx.SavedInNonInstantiationSFINAEContext = InNonInstantiationSFINAEContext;
589e5dd7070Spatrick InNonInstantiationSFINAEContext = false;
590e5dd7070Spatrick
591e5dd7070Spatrick CodeSynthesisContexts.push_back(Ctx);
592e5dd7070Spatrick
593e5dd7070Spatrick if (!Ctx.isInstantiationRecord())
594e5dd7070Spatrick ++NonInstantiationEntries;
595e5dd7070Spatrick
596e5dd7070Spatrick // Check to see if we're low on stack space. We can't do anything about this
597e5dd7070Spatrick // from here, but we can at least warn the user.
598e5dd7070Spatrick if (isStackNearlyExhausted())
599e5dd7070Spatrick warnStackExhausted(Ctx.PointOfInstantiation);
600e5dd7070Spatrick }
601e5dd7070Spatrick
popCodeSynthesisContext()602e5dd7070Spatrick void Sema::popCodeSynthesisContext() {
603e5dd7070Spatrick auto &Active = CodeSynthesisContexts.back();
604e5dd7070Spatrick if (!Active.isInstantiationRecord()) {
605e5dd7070Spatrick assert(NonInstantiationEntries > 0);
606e5dd7070Spatrick --NonInstantiationEntries;
607e5dd7070Spatrick }
608e5dd7070Spatrick
609e5dd7070Spatrick InNonInstantiationSFINAEContext = Active.SavedInNonInstantiationSFINAEContext;
610e5dd7070Spatrick
611e5dd7070Spatrick // Name lookup no longer looks in this template's defining module.
612e5dd7070Spatrick assert(CodeSynthesisContexts.size() >=
613e5dd7070Spatrick CodeSynthesisContextLookupModules.size() &&
614e5dd7070Spatrick "forgot to remove a lookup module for a template instantiation");
615e5dd7070Spatrick if (CodeSynthesisContexts.size() ==
616e5dd7070Spatrick CodeSynthesisContextLookupModules.size()) {
617e5dd7070Spatrick if (Module *M = CodeSynthesisContextLookupModules.back())
618e5dd7070Spatrick LookupModulesCache.erase(M);
619e5dd7070Spatrick CodeSynthesisContextLookupModules.pop_back();
620e5dd7070Spatrick }
621e5dd7070Spatrick
622e5dd7070Spatrick // If we've left the code synthesis context for the current context stack,
623e5dd7070Spatrick // stop remembering that we've emitted that stack.
624e5dd7070Spatrick if (CodeSynthesisContexts.size() ==
625e5dd7070Spatrick LastEmittedCodeSynthesisContextDepth)
626e5dd7070Spatrick LastEmittedCodeSynthesisContextDepth = 0;
627e5dd7070Spatrick
628e5dd7070Spatrick CodeSynthesisContexts.pop_back();
629e5dd7070Spatrick }
630e5dd7070Spatrick
Clear()631e5dd7070Spatrick void Sema::InstantiatingTemplate::Clear() {
632e5dd7070Spatrick if (!Invalid) {
633e5dd7070Spatrick if (!AlreadyInstantiating) {
634e5dd7070Spatrick auto &Active = SemaRef.CodeSynthesisContexts.back();
635e5dd7070Spatrick if (Active.Entity)
636e5dd7070Spatrick SemaRef.InstantiatingSpecializations.erase(
637a9ac8606Spatrick {Active.Entity->getCanonicalDecl(), Active.Kind});
638e5dd7070Spatrick }
639e5dd7070Spatrick
640e5dd7070Spatrick atTemplateEnd(SemaRef.TemplateInstCallbacks, SemaRef,
641e5dd7070Spatrick SemaRef.CodeSynthesisContexts.back());
642e5dd7070Spatrick
643e5dd7070Spatrick SemaRef.popCodeSynthesisContext();
644e5dd7070Spatrick Invalid = true;
645e5dd7070Spatrick }
646e5dd7070Spatrick }
647e5dd7070Spatrick
convertCallArgsToString(Sema & S,llvm::ArrayRef<const Expr * > Args)648*12c85518Srobert static std::string convertCallArgsToString(Sema &S,
649*12c85518Srobert llvm::ArrayRef<const Expr *> Args) {
650*12c85518Srobert std::string Result;
651*12c85518Srobert llvm::raw_string_ostream OS(Result);
652*12c85518Srobert llvm::ListSeparator Comma;
653*12c85518Srobert for (const Expr *Arg : Args) {
654*12c85518Srobert OS << Comma;
655*12c85518Srobert Arg->IgnoreParens()->printPretty(OS, nullptr,
656*12c85518Srobert S.Context.getPrintingPolicy());
657*12c85518Srobert }
658*12c85518Srobert return Result;
659*12c85518Srobert }
660*12c85518Srobert
CheckInstantiationDepth(SourceLocation PointOfInstantiation,SourceRange InstantiationRange)661e5dd7070Spatrick bool Sema::InstantiatingTemplate::CheckInstantiationDepth(
662e5dd7070Spatrick SourceLocation PointOfInstantiation,
663e5dd7070Spatrick SourceRange InstantiationRange) {
664e5dd7070Spatrick assert(SemaRef.NonInstantiationEntries <=
665e5dd7070Spatrick SemaRef.CodeSynthesisContexts.size());
666e5dd7070Spatrick if ((SemaRef.CodeSynthesisContexts.size() -
667e5dd7070Spatrick SemaRef.NonInstantiationEntries)
668e5dd7070Spatrick <= SemaRef.getLangOpts().InstantiationDepth)
669e5dd7070Spatrick return false;
670e5dd7070Spatrick
671e5dd7070Spatrick SemaRef.Diag(PointOfInstantiation,
672e5dd7070Spatrick diag::err_template_recursion_depth_exceeded)
673e5dd7070Spatrick << SemaRef.getLangOpts().InstantiationDepth
674e5dd7070Spatrick << InstantiationRange;
675e5dd7070Spatrick SemaRef.Diag(PointOfInstantiation, diag::note_template_recursion_depth)
676e5dd7070Spatrick << SemaRef.getLangOpts().InstantiationDepth;
677e5dd7070Spatrick return true;
678e5dd7070Spatrick }
679e5dd7070Spatrick
680e5dd7070Spatrick /// Prints the current instantiation stack through a series of
681e5dd7070Spatrick /// notes.
PrintInstantiationStack()682e5dd7070Spatrick void Sema::PrintInstantiationStack() {
683e5dd7070Spatrick // Determine which template instantiations to skip, if any.
684e5dd7070Spatrick unsigned SkipStart = CodeSynthesisContexts.size(), SkipEnd = SkipStart;
685e5dd7070Spatrick unsigned Limit = Diags.getTemplateBacktraceLimit();
686e5dd7070Spatrick if (Limit && Limit < CodeSynthesisContexts.size()) {
687e5dd7070Spatrick SkipStart = Limit / 2 + Limit % 2;
688e5dd7070Spatrick SkipEnd = CodeSynthesisContexts.size() - Limit / 2;
689e5dd7070Spatrick }
690e5dd7070Spatrick
691e5dd7070Spatrick // FIXME: In all of these cases, we need to show the template arguments
692e5dd7070Spatrick unsigned InstantiationIdx = 0;
693e5dd7070Spatrick for (SmallVectorImpl<CodeSynthesisContext>::reverse_iterator
694e5dd7070Spatrick Active = CodeSynthesisContexts.rbegin(),
695e5dd7070Spatrick ActiveEnd = CodeSynthesisContexts.rend();
696e5dd7070Spatrick Active != ActiveEnd;
697e5dd7070Spatrick ++Active, ++InstantiationIdx) {
698e5dd7070Spatrick // Skip this instantiation?
699e5dd7070Spatrick if (InstantiationIdx >= SkipStart && InstantiationIdx < SkipEnd) {
700e5dd7070Spatrick if (InstantiationIdx == SkipStart) {
701e5dd7070Spatrick // Note that we're skipping instantiations.
702e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation,
703e5dd7070Spatrick diag::note_instantiation_contexts_suppressed)
704e5dd7070Spatrick << unsigned(CodeSynthesisContexts.size() - Limit);
705e5dd7070Spatrick }
706e5dd7070Spatrick continue;
707e5dd7070Spatrick }
708e5dd7070Spatrick
709e5dd7070Spatrick switch (Active->Kind) {
710e5dd7070Spatrick case CodeSynthesisContext::TemplateInstantiation: {
711e5dd7070Spatrick Decl *D = Active->Entity;
712e5dd7070Spatrick if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) {
713e5dd7070Spatrick unsigned DiagID = diag::note_template_member_class_here;
714e5dd7070Spatrick if (isa<ClassTemplateSpecializationDecl>(Record))
715e5dd7070Spatrick DiagID = diag::note_template_class_instantiation_here;
716e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation, DiagID)
717e5dd7070Spatrick << Record << Active->InstantiationRange;
718e5dd7070Spatrick } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
719e5dd7070Spatrick unsigned DiagID;
720e5dd7070Spatrick if (Function->getPrimaryTemplate())
721e5dd7070Spatrick DiagID = diag::note_function_template_spec_here;
722e5dd7070Spatrick else
723e5dd7070Spatrick DiagID = diag::note_template_member_function_here;
724e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation, DiagID)
725e5dd7070Spatrick << Function
726e5dd7070Spatrick << Active->InstantiationRange;
727e5dd7070Spatrick } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
728e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation,
729e5dd7070Spatrick VD->isStaticDataMember()?
730e5dd7070Spatrick diag::note_template_static_data_member_def_here
731e5dd7070Spatrick : diag::note_template_variable_def_here)
732e5dd7070Spatrick << VD
733e5dd7070Spatrick << Active->InstantiationRange;
734e5dd7070Spatrick } else if (EnumDecl *ED = dyn_cast<EnumDecl>(D)) {
735e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation,
736e5dd7070Spatrick diag::note_template_enum_def_here)
737e5dd7070Spatrick << ED
738e5dd7070Spatrick << Active->InstantiationRange;
739e5dd7070Spatrick } else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
740e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation,
741e5dd7070Spatrick diag::note_template_nsdmi_here)
742e5dd7070Spatrick << FD << Active->InstantiationRange;
743e5dd7070Spatrick } else {
744e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation,
745e5dd7070Spatrick diag::note_template_type_alias_instantiation_here)
746e5dd7070Spatrick << cast<TypeAliasTemplateDecl>(D)
747e5dd7070Spatrick << Active->InstantiationRange;
748e5dd7070Spatrick }
749e5dd7070Spatrick break;
750e5dd7070Spatrick }
751e5dd7070Spatrick
752e5dd7070Spatrick case CodeSynthesisContext::DefaultTemplateArgumentInstantiation: {
753e5dd7070Spatrick TemplateDecl *Template = cast<TemplateDecl>(Active->Template);
754a9ac8606Spatrick SmallString<128> TemplateArgsStr;
755e5dd7070Spatrick llvm::raw_svector_ostream OS(TemplateArgsStr);
756*12c85518Srobert Template->printName(OS, getPrintingPolicy());
757e5dd7070Spatrick printTemplateArgumentList(OS, Active->template_arguments(),
758e5dd7070Spatrick getPrintingPolicy());
759e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation,
760e5dd7070Spatrick diag::note_default_arg_instantiation_here)
761e5dd7070Spatrick << OS.str()
762e5dd7070Spatrick << Active->InstantiationRange;
763e5dd7070Spatrick break;
764e5dd7070Spatrick }
765e5dd7070Spatrick
766e5dd7070Spatrick case CodeSynthesisContext::ExplicitTemplateArgumentSubstitution: {
767e5dd7070Spatrick FunctionTemplateDecl *FnTmpl = cast<FunctionTemplateDecl>(Active->Entity);
768e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation,
769e5dd7070Spatrick diag::note_explicit_template_arg_substitution_here)
770e5dd7070Spatrick << FnTmpl
771e5dd7070Spatrick << getTemplateArgumentBindingsText(FnTmpl->getTemplateParameters(),
772e5dd7070Spatrick Active->TemplateArgs,
773e5dd7070Spatrick Active->NumTemplateArgs)
774e5dd7070Spatrick << Active->InstantiationRange;
775e5dd7070Spatrick break;
776e5dd7070Spatrick }
777e5dd7070Spatrick
778e5dd7070Spatrick case CodeSynthesisContext::DeducedTemplateArgumentSubstitution: {
779e5dd7070Spatrick if (FunctionTemplateDecl *FnTmpl =
780e5dd7070Spatrick dyn_cast<FunctionTemplateDecl>(Active->Entity)) {
781e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation,
782e5dd7070Spatrick diag::note_function_template_deduction_instantiation_here)
783e5dd7070Spatrick << FnTmpl
784e5dd7070Spatrick << getTemplateArgumentBindingsText(FnTmpl->getTemplateParameters(),
785e5dd7070Spatrick Active->TemplateArgs,
786e5dd7070Spatrick Active->NumTemplateArgs)
787e5dd7070Spatrick << Active->InstantiationRange;
788e5dd7070Spatrick } else {
789e5dd7070Spatrick bool IsVar = isa<VarTemplateDecl>(Active->Entity) ||
790e5dd7070Spatrick isa<VarTemplateSpecializationDecl>(Active->Entity);
791e5dd7070Spatrick bool IsTemplate = false;
792e5dd7070Spatrick TemplateParameterList *Params;
793e5dd7070Spatrick if (auto *D = dyn_cast<TemplateDecl>(Active->Entity)) {
794e5dd7070Spatrick IsTemplate = true;
795e5dd7070Spatrick Params = D->getTemplateParameters();
796e5dd7070Spatrick } else if (auto *D = dyn_cast<ClassTemplatePartialSpecializationDecl>(
797e5dd7070Spatrick Active->Entity)) {
798e5dd7070Spatrick Params = D->getTemplateParameters();
799e5dd7070Spatrick } else if (auto *D = dyn_cast<VarTemplatePartialSpecializationDecl>(
800e5dd7070Spatrick Active->Entity)) {
801e5dd7070Spatrick Params = D->getTemplateParameters();
802e5dd7070Spatrick } else {
803e5dd7070Spatrick llvm_unreachable("unexpected template kind");
804e5dd7070Spatrick }
805e5dd7070Spatrick
806e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation,
807e5dd7070Spatrick diag::note_deduced_template_arg_substitution_here)
808e5dd7070Spatrick << IsVar << IsTemplate << cast<NamedDecl>(Active->Entity)
809e5dd7070Spatrick << getTemplateArgumentBindingsText(Params, Active->TemplateArgs,
810e5dd7070Spatrick Active->NumTemplateArgs)
811e5dd7070Spatrick << Active->InstantiationRange;
812e5dd7070Spatrick }
813e5dd7070Spatrick break;
814e5dd7070Spatrick }
815e5dd7070Spatrick
816e5dd7070Spatrick case CodeSynthesisContext::DefaultFunctionArgumentInstantiation: {
817e5dd7070Spatrick ParmVarDecl *Param = cast<ParmVarDecl>(Active->Entity);
818e5dd7070Spatrick FunctionDecl *FD = cast<FunctionDecl>(Param->getDeclContext());
819e5dd7070Spatrick
820a9ac8606Spatrick SmallString<128> TemplateArgsStr;
821e5dd7070Spatrick llvm::raw_svector_ostream OS(TemplateArgsStr);
822*12c85518Srobert FD->printName(OS, getPrintingPolicy());
823e5dd7070Spatrick printTemplateArgumentList(OS, Active->template_arguments(),
824e5dd7070Spatrick getPrintingPolicy());
825e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation,
826e5dd7070Spatrick diag::note_default_function_arg_instantiation_here)
827e5dd7070Spatrick << OS.str()
828e5dd7070Spatrick << Active->InstantiationRange;
829e5dd7070Spatrick break;
830e5dd7070Spatrick }
831e5dd7070Spatrick
832e5dd7070Spatrick case CodeSynthesisContext::PriorTemplateArgumentSubstitution: {
833e5dd7070Spatrick NamedDecl *Parm = cast<NamedDecl>(Active->Entity);
834e5dd7070Spatrick std::string Name;
835e5dd7070Spatrick if (!Parm->getName().empty())
836e5dd7070Spatrick Name = std::string(" '") + Parm->getName().str() + "'";
837e5dd7070Spatrick
838e5dd7070Spatrick TemplateParameterList *TemplateParams = nullptr;
839e5dd7070Spatrick if (TemplateDecl *Template = dyn_cast<TemplateDecl>(Active->Template))
840e5dd7070Spatrick TemplateParams = Template->getTemplateParameters();
841e5dd7070Spatrick else
842e5dd7070Spatrick TemplateParams =
843e5dd7070Spatrick cast<ClassTemplatePartialSpecializationDecl>(Active->Template)
844e5dd7070Spatrick ->getTemplateParameters();
845e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation,
846e5dd7070Spatrick diag::note_prior_template_arg_substitution)
847e5dd7070Spatrick << isa<TemplateTemplateParmDecl>(Parm)
848e5dd7070Spatrick << Name
849e5dd7070Spatrick << getTemplateArgumentBindingsText(TemplateParams,
850e5dd7070Spatrick Active->TemplateArgs,
851e5dd7070Spatrick Active->NumTemplateArgs)
852e5dd7070Spatrick << Active->InstantiationRange;
853e5dd7070Spatrick break;
854e5dd7070Spatrick }
855e5dd7070Spatrick
856e5dd7070Spatrick case CodeSynthesisContext::DefaultTemplateArgumentChecking: {
857e5dd7070Spatrick TemplateParameterList *TemplateParams = nullptr;
858e5dd7070Spatrick if (TemplateDecl *Template = dyn_cast<TemplateDecl>(Active->Template))
859e5dd7070Spatrick TemplateParams = Template->getTemplateParameters();
860e5dd7070Spatrick else
861e5dd7070Spatrick TemplateParams =
862e5dd7070Spatrick cast<ClassTemplatePartialSpecializationDecl>(Active->Template)
863e5dd7070Spatrick ->getTemplateParameters();
864e5dd7070Spatrick
865e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation,
866e5dd7070Spatrick diag::note_template_default_arg_checking)
867e5dd7070Spatrick << getTemplateArgumentBindingsText(TemplateParams,
868e5dd7070Spatrick Active->TemplateArgs,
869e5dd7070Spatrick Active->NumTemplateArgs)
870e5dd7070Spatrick << Active->InstantiationRange;
871e5dd7070Spatrick break;
872e5dd7070Spatrick }
873e5dd7070Spatrick
874e5dd7070Spatrick case CodeSynthesisContext::ExceptionSpecEvaluation:
875e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation,
876e5dd7070Spatrick diag::note_evaluating_exception_spec_here)
877e5dd7070Spatrick << cast<FunctionDecl>(Active->Entity);
878e5dd7070Spatrick break;
879e5dd7070Spatrick
880e5dd7070Spatrick case CodeSynthesisContext::ExceptionSpecInstantiation:
881e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation,
882e5dd7070Spatrick diag::note_template_exception_spec_instantiation_here)
883e5dd7070Spatrick << cast<FunctionDecl>(Active->Entity)
884e5dd7070Spatrick << Active->InstantiationRange;
885e5dd7070Spatrick break;
886e5dd7070Spatrick
887e5dd7070Spatrick case CodeSynthesisContext::RequirementInstantiation:
888e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation,
889e5dd7070Spatrick diag::note_template_requirement_instantiation_here)
890e5dd7070Spatrick << Active->InstantiationRange;
891e5dd7070Spatrick break;
892*12c85518Srobert case CodeSynthesisContext::RequirementParameterInstantiation:
893*12c85518Srobert Diags.Report(Active->PointOfInstantiation,
894*12c85518Srobert diag::note_template_requirement_params_instantiation_here)
895*12c85518Srobert << Active->InstantiationRange;
896*12c85518Srobert break;
897e5dd7070Spatrick
898e5dd7070Spatrick case CodeSynthesisContext::NestedRequirementConstraintsCheck:
899e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation,
900e5dd7070Spatrick diag::note_nested_requirement_here)
901e5dd7070Spatrick << Active->InstantiationRange;
902e5dd7070Spatrick break;
903e5dd7070Spatrick
904e5dd7070Spatrick case CodeSynthesisContext::DeclaringSpecialMember:
905e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation,
906e5dd7070Spatrick diag::note_in_declaration_of_implicit_special_member)
907e5dd7070Spatrick << cast<CXXRecordDecl>(Active->Entity) << Active->SpecialMember;
908e5dd7070Spatrick break;
909e5dd7070Spatrick
910e5dd7070Spatrick case CodeSynthesisContext::DeclaringImplicitEqualityComparison:
911e5dd7070Spatrick Diags.Report(Active->Entity->getLocation(),
912e5dd7070Spatrick diag::note_in_declaration_of_implicit_equality_comparison);
913e5dd7070Spatrick break;
914e5dd7070Spatrick
915e5dd7070Spatrick case CodeSynthesisContext::DefiningSynthesizedFunction: {
916e5dd7070Spatrick // FIXME: For synthesized functions that are not defaulted,
917e5dd7070Spatrick // produce a note.
918e5dd7070Spatrick auto *FD = dyn_cast<FunctionDecl>(Active->Entity);
919e5dd7070Spatrick DefaultedFunctionKind DFK =
920e5dd7070Spatrick FD ? getDefaultedFunctionKind(FD) : DefaultedFunctionKind();
921e5dd7070Spatrick if (DFK.isSpecialMember()) {
922e5dd7070Spatrick auto *MD = cast<CXXMethodDecl>(FD);
923e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation,
924e5dd7070Spatrick diag::note_member_synthesized_at)
925e5dd7070Spatrick << MD->isExplicitlyDefaulted() << DFK.asSpecialMember()
926e5dd7070Spatrick << Context.getTagDeclType(MD->getParent());
927e5dd7070Spatrick } else if (DFK.isComparison()) {
928e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation,
929e5dd7070Spatrick diag::note_comparison_synthesized_at)
930e5dd7070Spatrick << (int)DFK.asComparison()
931e5dd7070Spatrick << Context.getTagDeclType(
932e5dd7070Spatrick cast<CXXRecordDecl>(FD->getLexicalDeclContext()));
933e5dd7070Spatrick }
934e5dd7070Spatrick break;
935e5dd7070Spatrick }
936e5dd7070Spatrick
937e5dd7070Spatrick case CodeSynthesisContext::RewritingOperatorAsSpaceship:
938e5dd7070Spatrick Diags.Report(Active->Entity->getLocation(),
939e5dd7070Spatrick diag::note_rewriting_operator_as_spaceship);
940e5dd7070Spatrick break;
941e5dd7070Spatrick
942ec727ea7Spatrick case CodeSynthesisContext::InitializingStructuredBinding:
943ec727ea7Spatrick Diags.Report(Active->PointOfInstantiation,
944ec727ea7Spatrick diag::note_in_binding_decl_init)
945ec727ea7Spatrick << cast<BindingDecl>(Active->Entity);
946ec727ea7Spatrick break;
947ec727ea7Spatrick
948ec727ea7Spatrick case CodeSynthesisContext::MarkingClassDllexported:
949ec727ea7Spatrick Diags.Report(Active->PointOfInstantiation,
950ec727ea7Spatrick diag::note_due_to_dllexported_class)
951ec727ea7Spatrick << cast<CXXRecordDecl>(Active->Entity) << !getLangOpts().CPlusPlus11;
952ec727ea7Spatrick break;
953ec727ea7Spatrick
954*12c85518Srobert case CodeSynthesisContext::BuildingBuiltinDumpStructCall:
955*12c85518Srobert Diags.Report(Active->PointOfInstantiation,
956*12c85518Srobert diag::note_building_builtin_dump_struct_call)
957*12c85518Srobert << convertCallArgsToString(
958*12c85518Srobert *this, llvm::ArrayRef(Active->CallArgs, Active->NumCallArgs));
959*12c85518Srobert break;
960*12c85518Srobert
961e5dd7070Spatrick case CodeSynthesisContext::Memoization:
962e5dd7070Spatrick break;
963e5dd7070Spatrick
964e5dd7070Spatrick case CodeSynthesisContext::ConstraintsCheck: {
965e5dd7070Spatrick unsigned DiagID = 0;
966e5dd7070Spatrick if (!Active->Entity) {
967e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation,
968e5dd7070Spatrick diag::note_nested_requirement_here)
969e5dd7070Spatrick << Active->InstantiationRange;
970e5dd7070Spatrick break;
971e5dd7070Spatrick }
972e5dd7070Spatrick if (isa<ConceptDecl>(Active->Entity))
973e5dd7070Spatrick DiagID = diag::note_concept_specialization_here;
974e5dd7070Spatrick else if (isa<TemplateDecl>(Active->Entity))
975e5dd7070Spatrick DiagID = diag::note_checking_constraints_for_template_id_here;
976e5dd7070Spatrick else if (isa<VarTemplatePartialSpecializationDecl>(Active->Entity))
977e5dd7070Spatrick DiagID = diag::note_checking_constraints_for_var_spec_id_here;
978e5dd7070Spatrick else if (isa<ClassTemplatePartialSpecializationDecl>(Active->Entity))
979e5dd7070Spatrick DiagID = diag::note_checking_constraints_for_class_spec_id_here;
980e5dd7070Spatrick else {
981e5dd7070Spatrick assert(isa<FunctionDecl>(Active->Entity));
982e5dd7070Spatrick DiagID = diag::note_checking_constraints_for_function_here;
983e5dd7070Spatrick }
984a9ac8606Spatrick SmallString<128> TemplateArgsStr;
985e5dd7070Spatrick llvm::raw_svector_ostream OS(TemplateArgsStr);
986*12c85518Srobert cast<NamedDecl>(Active->Entity)->printName(OS, getPrintingPolicy());
987a9ac8606Spatrick if (!isa<FunctionDecl>(Active->Entity)) {
988e5dd7070Spatrick printTemplateArgumentList(OS, Active->template_arguments(),
989e5dd7070Spatrick getPrintingPolicy());
990a9ac8606Spatrick }
991e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation, DiagID) << OS.str()
992e5dd7070Spatrick << Active->InstantiationRange;
993e5dd7070Spatrick break;
994e5dd7070Spatrick }
995e5dd7070Spatrick case CodeSynthesisContext::ConstraintSubstitution:
996e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation,
997e5dd7070Spatrick diag::note_constraint_substitution_here)
998e5dd7070Spatrick << Active->InstantiationRange;
999e5dd7070Spatrick break;
1000e5dd7070Spatrick case CodeSynthesisContext::ConstraintNormalization:
1001e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation,
1002e5dd7070Spatrick diag::note_constraint_normalization_here)
1003e5dd7070Spatrick << cast<NamedDecl>(Active->Entity)->getName()
1004e5dd7070Spatrick << Active->InstantiationRange;
1005e5dd7070Spatrick break;
1006e5dd7070Spatrick case CodeSynthesisContext::ParameterMappingSubstitution:
1007e5dd7070Spatrick Diags.Report(Active->PointOfInstantiation,
1008e5dd7070Spatrick diag::note_parameter_mapping_substitution_here)
1009e5dd7070Spatrick << Active->InstantiationRange;
1010e5dd7070Spatrick break;
1011e5dd7070Spatrick }
1012e5dd7070Spatrick }
1013e5dd7070Spatrick }
1014e5dd7070Spatrick
isSFINAEContext() const1015*12c85518Srobert std::optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const {
1016e5dd7070Spatrick if (InNonInstantiationSFINAEContext)
1017*12c85518Srobert return std::optional<TemplateDeductionInfo *>(nullptr);
1018e5dd7070Spatrick
1019e5dd7070Spatrick for (SmallVectorImpl<CodeSynthesisContext>::const_reverse_iterator
1020e5dd7070Spatrick Active = CodeSynthesisContexts.rbegin(),
1021e5dd7070Spatrick ActiveEnd = CodeSynthesisContexts.rend();
1022e5dd7070Spatrick Active != ActiveEnd;
1023e5dd7070Spatrick ++Active)
1024e5dd7070Spatrick {
1025e5dd7070Spatrick switch (Active->Kind) {
1026e5dd7070Spatrick case CodeSynthesisContext::TemplateInstantiation:
1027e5dd7070Spatrick // An instantiation of an alias template may or may not be a SFINAE
1028e5dd7070Spatrick // context, depending on what else is on the stack.
1029e5dd7070Spatrick if (isa<TypeAliasTemplateDecl>(Active->Entity))
1030e5dd7070Spatrick break;
1031*12c85518Srobert [[fallthrough]];
1032e5dd7070Spatrick case CodeSynthesisContext::DefaultFunctionArgumentInstantiation:
1033e5dd7070Spatrick case CodeSynthesisContext::ExceptionSpecInstantiation:
1034e5dd7070Spatrick case CodeSynthesisContext::ConstraintsCheck:
1035e5dd7070Spatrick case CodeSynthesisContext::ParameterMappingSubstitution:
1036e5dd7070Spatrick case CodeSynthesisContext::ConstraintNormalization:
1037e5dd7070Spatrick case CodeSynthesisContext::NestedRequirementConstraintsCheck:
1038e5dd7070Spatrick // This is a template instantiation, so there is no SFINAE.
1039*12c85518Srobert return std::nullopt;
1040e5dd7070Spatrick
1041e5dd7070Spatrick case CodeSynthesisContext::DefaultTemplateArgumentInstantiation:
1042e5dd7070Spatrick case CodeSynthesisContext::PriorTemplateArgumentSubstitution:
1043e5dd7070Spatrick case CodeSynthesisContext::DefaultTemplateArgumentChecking:
1044a9ac8606Spatrick case CodeSynthesisContext::RewritingOperatorAsSpaceship:
1045e5dd7070Spatrick // A default template argument instantiation and substitution into
1046e5dd7070Spatrick // template parameters with arguments for prior parameters may or may
1047e5dd7070Spatrick // not be a SFINAE context; look further up the stack.
1048e5dd7070Spatrick break;
1049e5dd7070Spatrick
1050e5dd7070Spatrick case CodeSynthesisContext::ExplicitTemplateArgumentSubstitution:
1051e5dd7070Spatrick case CodeSynthesisContext::DeducedTemplateArgumentSubstitution:
1052e5dd7070Spatrick case CodeSynthesisContext::ConstraintSubstitution:
1053e5dd7070Spatrick case CodeSynthesisContext::RequirementInstantiation:
1054*12c85518Srobert case CodeSynthesisContext::RequirementParameterInstantiation:
1055e5dd7070Spatrick // We're either substituting explicitly-specified template arguments,
1056e5dd7070Spatrick // deduced template arguments, a constraint expression or a requirement
1057e5dd7070Spatrick // in a requires expression, so SFINAE applies.
1058e5dd7070Spatrick assert(Active->DeductionInfo && "Missing deduction info pointer");
1059e5dd7070Spatrick return Active->DeductionInfo;
1060e5dd7070Spatrick
1061e5dd7070Spatrick case CodeSynthesisContext::DeclaringSpecialMember:
1062e5dd7070Spatrick case CodeSynthesisContext::DeclaringImplicitEqualityComparison:
1063e5dd7070Spatrick case CodeSynthesisContext::DefiningSynthesizedFunction:
1064ec727ea7Spatrick case CodeSynthesisContext::InitializingStructuredBinding:
1065ec727ea7Spatrick case CodeSynthesisContext::MarkingClassDllexported:
1066*12c85518Srobert case CodeSynthesisContext::BuildingBuiltinDumpStructCall:
1067e5dd7070Spatrick // This happens in a context unrelated to template instantiation, so
1068e5dd7070Spatrick // there is no SFINAE.
1069*12c85518Srobert return std::nullopt;
1070e5dd7070Spatrick
1071e5dd7070Spatrick case CodeSynthesisContext::ExceptionSpecEvaluation:
1072e5dd7070Spatrick // FIXME: This should not be treated as a SFINAE context, because
1073e5dd7070Spatrick // we will cache an incorrect exception specification. However, clang
1074e5dd7070Spatrick // bootstrap relies this! See PR31692.
1075e5dd7070Spatrick break;
1076e5dd7070Spatrick
1077e5dd7070Spatrick case CodeSynthesisContext::Memoization:
1078e5dd7070Spatrick break;
1079e5dd7070Spatrick }
1080e5dd7070Spatrick
1081e5dd7070Spatrick // The inner context was transparent for SFINAE. If it occurred within a
1082e5dd7070Spatrick // non-instantiation SFINAE context, then SFINAE applies.
1083e5dd7070Spatrick if (Active->SavedInNonInstantiationSFINAEContext)
1084*12c85518Srobert return std::optional<TemplateDeductionInfo *>(nullptr);
1085e5dd7070Spatrick }
1086e5dd7070Spatrick
1087*12c85518Srobert return std::nullopt;
1088e5dd7070Spatrick }
1089e5dd7070Spatrick
1090e5dd7070Spatrick //===----------------------------------------------------------------------===/
1091e5dd7070Spatrick // Template Instantiation for Types
1092e5dd7070Spatrick //===----------------------------------------------------------------------===/
1093e5dd7070Spatrick namespace {
1094e5dd7070Spatrick class TemplateInstantiator : public TreeTransform<TemplateInstantiator> {
1095e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs;
1096e5dd7070Spatrick SourceLocation Loc;
1097e5dd7070Spatrick DeclarationName Entity;
1098*12c85518Srobert bool EvaluateConstraints = true;
1099e5dd7070Spatrick
1100e5dd7070Spatrick public:
1101e5dd7070Spatrick typedef TreeTransform<TemplateInstantiator> inherited;
1102e5dd7070Spatrick
TemplateInstantiator(Sema & SemaRef,const MultiLevelTemplateArgumentList & TemplateArgs,SourceLocation Loc,DeclarationName Entity)1103e5dd7070Spatrick TemplateInstantiator(Sema &SemaRef,
1104e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs,
1105*12c85518Srobert SourceLocation Loc, DeclarationName Entity)
1106e5dd7070Spatrick : inherited(SemaRef), TemplateArgs(TemplateArgs), Loc(Loc),
1107e5dd7070Spatrick Entity(Entity) {}
1108e5dd7070Spatrick
setEvaluateConstraints(bool B)1109*12c85518Srobert void setEvaluateConstraints(bool B) {
1110*12c85518Srobert EvaluateConstraints = B;
1111*12c85518Srobert }
getEvaluateConstraints()1112*12c85518Srobert bool getEvaluateConstraints() {
1113*12c85518Srobert return EvaluateConstraints;
1114*12c85518Srobert }
1115*12c85518Srobert
1116e5dd7070Spatrick /// Determine whether the given type \p T has already been
1117e5dd7070Spatrick /// transformed.
1118e5dd7070Spatrick ///
1119e5dd7070Spatrick /// For the purposes of template instantiation, a type has already been
1120e5dd7070Spatrick /// transformed if it is NULL or if it is not dependent.
1121e5dd7070Spatrick bool AlreadyTransformed(QualType T);
1122e5dd7070Spatrick
1123e5dd7070Spatrick /// Returns the location of the entity being instantiated, if known.
getBaseLocation()1124e5dd7070Spatrick SourceLocation getBaseLocation() { return Loc; }
1125e5dd7070Spatrick
1126e5dd7070Spatrick /// Returns the name of the entity being instantiated, if any.
getBaseEntity()1127e5dd7070Spatrick DeclarationName getBaseEntity() { return Entity; }
1128e5dd7070Spatrick
1129e5dd7070Spatrick /// Sets the "base" location and entity when that
1130e5dd7070Spatrick /// information is known based on another transformation.
setBase(SourceLocation Loc,DeclarationName Entity)1131e5dd7070Spatrick void setBase(SourceLocation Loc, DeclarationName Entity) {
1132e5dd7070Spatrick this->Loc = Loc;
1133e5dd7070Spatrick this->Entity = Entity;
1134e5dd7070Spatrick }
1135e5dd7070Spatrick
TransformTemplateDepth(unsigned Depth)1136e5dd7070Spatrick unsigned TransformTemplateDepth(unsigned Depth) {
1137e5dd7070Spatrick return TemplateArgs.getNewDepth(Depth);
1138e5dd7070Spatrick }
1139e5dd7070Spatrick
getPackIndex(TemplateArgument Pack)1140*12c85518Srobert std::optional<unsigned> getPackIndex(TemplateArgument Pack) {
1141*12c85518Srobert int Index = getSema().ArgumentPackSubstitutionIndex;
1142*12c85518Srobert if (Index == -1)
1143*12c85518Srobert return std::nullopt;
1144*12c85518Srobert return Pack.pack_size() - 1 - Index;
1145*12c85518Srobert }
1146*12c85518Srobert
TryExpandParameterPacks(SourceLocation EllipsisLoc,SourceRange PatternRange,ArrayRef<UnexpandedParameterPack> Unexpanded,bool & ShouldExpand,bool & RetainExpansion,std::optional<unsigned> & NumExpansions)1147e5dd7070Spatrick bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
1148e5dd7070Spatrick SourceRange PatternRange,
1149e5dd7070Spatrick ArrayRef<UnexpandedParameterPack> Unexpanded,
1150e5dd7070Spatrick bool &ShouldExpand, bool &RetainExpansion,
1151*12c85518Srobert std::optional<unsigned> &NumExpansions) {
1152e5dd7070Spatrick return getSema().CheckParameterPacksForExpansion(EllipsisLoc,
1153e5dd7070Spatrick PatternRange, Unexpanded,
1154e5dd7070Spatrick TemplateArgs,
1155e5dd7070Spatrick ShouldExpand,
1156e5dd7070Spatrick RetainExpansion,
1157e5dd7070Spatrick NumExpansions);
1158e5dd7070Spatrick }
1159e5dd7070Spatrick
ExpandingFunctionParameterPack(ParmVarDecl * Pack)1160e5dd7070Spatrick void ExpandingFunctionParameterPack(ParmVarDecl *Pack) {
1161e5dd7070Spatrick SemaRef.CurrentInstantiationScope->MakeInstantiatedLocalArgPack(Pack);
1162e5dd7070Spatrick }
1163e5dd7070Spatrick
ForgetPartiallySubstitutedPack()1164e5dd7070Spatrick TemplateArgument ForgetPartiallySubstitutedPack() {
1165e5dd7070Spatrick TemplateArgument Result;
1166e5dd7070Spatrick if (NamedDecl *PartialPack
1167e5dd7070Spatrick = SemaRef.CurrentInstantiationScope->getPartiallySubstitutedPack()){
1168e5dd7070Spatrick MultiLevelTemplateArgumentList &TemplateArgs
1169e5dd7070Spatrick = const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs);
1170e5dd7070Spatrick unsigned Depth, Index;
1171e5dd7070Spatrick std::tie(Depth, Index) = getDepthAndIndex(PartialPack);
1172e5dd7070Spatrick if (TemplateArgs.hasTemplateArgument(Depth, Index)) {
1173e5dd7070Spatrick Result = TemplateArgs(Depth, Index);
1174e5dd7070Spatrick TemplateArgs.setArgument(Depth, Index, TemplateArgument());
1175e5dd7070Spatrick }
1176e5dd7070Spatrick }
1177e5dd7070Spatrick
1178e5dd7070Spatrick return Result;
1179e5dd7070Spatrick }
1180e5dd7070Spatrick
RememberPartiallySubstitutedPack(TemplateArgument Arg)1181e5dd7070Spatrick void RememberPartiallySubstitutedPack(TemplateArgument Arg) {
1182e5dd7070Spatrick if (Arg.isNull())
1183e5dd7070Spatrick return;
1184e5dd7070Spatrick
1185e5dd7070Spatrick if (NamedDecl *PartialPack
1186e5dd7070Spatrick = SemaRef.CurrentInstantiationScope->getPartiallySubstitutedPack()){
1187e5dd7070Spatrick MultiLevelTemplateArgumentList &TemplateArgs
1188e5dd7070Spatrick = const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs);
1189e5dd7070Spatrick unsigned Depth, Index;
1190e5dd7070Spatrick std::tie(Depth, Index) = getDepthAndIndex(PartialPack);
1191e5dd7070Spatrick TemplateArgs.setArgument(Depth, Index, Arg);
1192e5dd7070Spatrick }
1193e5dd7070Spatrick }
1194e5dd7070Spatrick
1195e5dd7070Spatrick /// Transform the given declaration by instantiating a reference to
1196e5dd7070Spatrick /// this declaration.
1197e5dd7070Spatrick Decl *TransformDecl(SourceLocation Loc, Decl *D);
1198e5dd7070Spatrick
transformAttrs(Decl * Old,Decl * New)1199e5dd7070Spatrick void transformAttrs(Decl *Old, Decl *New) {
1200e5dd7070Spatrick SemaRef.InstantiateAttrs(TemplateArgs, Old, New);
1201e5dd7070Spatrick }
1202e5dd7070Spatrick
transformedLocalDecl(Decl * Old,ArrayRef<Decl * > NewDecls)1203e5dd7070Spatrick void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> NewDecls) {
1204e5dd7070Spatrick if (Old->isParameterPack()) {
1205e5dd7070Spatrick SemaRef.CurrentInstantiationScope->MakeInstantiatedLocalArgPack(Old);
1206e5dd7070Spatrick for (auto *New : NewDecls)
1207e5dd7070Spatrick SemaRef.CurrentInstantiationScope->InstantiatedLocalPackArg(
1208e5dd7070Spatrick Old, cast<VarDecl>(New));
1209e5dd7070Spatrick return;
1210e5dd7070Spatrick }
1211e5dd7070Spatrick
1212e5dd7070Spatrick assert(NewDecls.size() == 1 &&
1213e5dd7070Spatrick "should only have multiple expansions for a pack");
1214e5dd7070Spatrick Decl *New = NewDecls.front();
1215e5dd7070Spatrick
1216e5dd7070Spatrick // If we've instantiated the call operator of a lambda or the call
1217e5dd7070Spatrick // operator template of a generic lambda, update the "instantiation of"
1218e5dd7070Spatrick // information.
1219e5dd7070Spatrick auto *NewMD = dyn_cast<CXXMethodDecl>(New);
1220e5dd7070Spatrick if (NewMD && isLambdaCallOperator(NewMD)) {
1221e5dd7070Spatrick auto *OldMD = dyn_cast<CXXMethodDecl>(Old);
1222e5dd7070Spatrick if (auto *NewTD = NewMD->getDescribedFunctionTemplate())
1223e5dd7070Spatrick NewTD->setInstantiatedFromMemberTemplate(
1224e5dd7070Spatrick OldMD->getDescribedFunctionTemplate());
1225e5dd7070Spatrick else
1226e5dd7070Spatrick NewMD->setInstantiationOfMemberFunction(OldMD,
1227e5dd7070Spatrick TSK_ImplicitInstantiation);
1228e5dd7070Spatrick }
1229e5dd7070Spatrick
1230e5dd7070Spatrick SemaRef.CurrentInstantiationScope->InstantiatedLocal(Old, New);
1231e5dd7070Spatrick
1232e5dd7070Spatrick // We recreated a local declaration, but not by instantiating it. There
1233e5dd7070Spatrick // may be pending dependent diagnostics to produce.
1234*12c85518Srobert if (auto *DC = dyn_cast<DeclContext>(Old); DC && DC->isDependentContext())
1235e5dd7070Spatrick SemaRef.PerformDependentDiagnostics(DC, TemplateArgs);
1236e5dd7070Spatrick }
1237e5dd7070Spatrick
1238e5dd7070Spatrick /// Transform the definition of the given declaration by
1239e5dd7070Spatrick /// instantiating it.
1240e5dd7070Spatrick Decl *TransformDefinition(SourceLocation Loc, Decl *D);
1241e5dd7070Spatrick
1242e5dd7070Spatrick /// Transform the first qualifier within a scope by instantiating the
1243e5dd7070Spatrick /// declaration.
1244e5dd7070Spatrick NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc);
1245e5dd7070Spatrick
1246e5dd7070Spatrick /// Rebuild the exception declaration and register the declaration
1247e5dd7070Spatrick /// as an instantiated local.
1248e5dd7070Spatrick VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
1249e5dd7070Spatrick TypeSourceInfo *Declarator,
1250e5dd7070Spatrick SourceLocation StartLoc,
1251e5dd7070Spatrick SourceLocation NameLoc,
1252e5dd7070Spatrick IdentifierInfo *Name);
1253e5dd7070Spatrick
1254e5dd7070Spatrick /// Rebuild the Objective-C exception declaration and register the
1255e5dd7070Spatrick /// declaration as an instantiated local.
1256e5dd7070Spatrick VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
1257e5dd7070Spatrick TypeSourceInfo *TSInfo, QualType T);
1258e5dd7070Spatrick
1259e5dd7070Spatrick /// Check for tag mismatches when instantiating an
1260e5dd7070Spatrick /// elaborated type.
1261e5dd7070Spatrick QualType RebuildElaboratedType(SourceLocation KeywordLoc,
1262e5dd7070Spatrick ElaboratedTypeKeyword Keyword,
1263e5dd7070Spatrick NestedNameSpecifierLoc QualifierLoc,
1264e5dd7070Spatrick QualType T);
1265e5dd7070Spatrick
1266e5dd7070Spatrick TemplateName
1267e5dd7070Spatrick TransformTemplateName(CXXScopeSpec &SS, TemplateName Name,
1268e5dd7070Spatrick SourceLocation NameLoc,
1269e5dd7070Spatrick QualType ObjectType = QualType(),
1270e5dd7070Spatrick NamedDecl *FirstQualifierInScope = nullptr,
1271e5dd7070Spatrick bool AllowInjectedClassName = false);
1272e5dd7070Spatrick
1273e5dd7070Spatrick const LoopHintAttr *TransformLoopHintAttr(const LoopHintAttr *LH);
1274e5dd7070Spatrick
1275e5dd7070Spatrick ExprResult TransformPredefinedExpr(PredefinedExpr *E);
1276e5dd7070Spatrick ExprResult TransformDeclRefExpr(DeclRefExpr *E);
1277e5dd7070Spatrick ExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E);
1278e5dd7070Spatrick
1279e5dd7070Spatrick ExprResult TransformTemplateParmRefExpr(DeclRefExpr *E,
1280e5dd7070Spatrick NonTypeTemplateParmDecl *D);
1281e5dd7070Spatrick ExprResult TransformSubstNonTypeTemplateParmPackExpr(
1282e5dd7070Spatrick SubstNonTypeTemplateParmPackExpr *E);
1283e5dd7070Spatrick ExprResult TransformSubstNonTypeTemplateParmExpr(
1284e5dd7070Spatrick SubstNonTypeTemplateParmExpr *E);
1285e5dd7070Spatrick
1286e5dd7070Spatrick /// Rebuild a DeclRefExpr for a VarDecl reference.
1287e5dd7070Spatrick ExprResult RebuildVarDeclRefExpr(VarDecl *PD, SourceLocation Loc);
1288e5dd7070Spatrick
1289e5dd7070Spatrick /// Transform a reference to a function or init-capture parameter pack.
1290e5dd7070Spatrick ExprResult TransformFunctionParmPackRefExpr(DeclRefExpr *E, VarDecl *PD);
1291e5dd7070Spatrick
1292e5dd7070Spatrick /// Transform a FunctionParmPackExpr which was built when we couldn't
1293e5dd7070Spatrick /// expand a function parameter pack reference which refers to an expanded
1294e5dd7070Spatrick /// pack.
1295e5dd7070Spatrick ExprResult TransformFunctionParmPackExpr(FunctionParmPackExpr *E);
1296e5dd7070Spatrick
TransformFunctionProtoType(TypeLocBuilder & TLB,FunctionProtoTypeLoc TL)1297e5dd7070Spatrick QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
1298e5dd7070Spatrick FunctionProtoTypeLoc TL) {
1299e5dd7070Spatrick // Call the base version; it will forward to our overridden version below.
1300e5dd7070Spatrick return inherited::TransformFunctionProtoType(TLB, TL);
1301e5dd7070Spatrick }
1302e5dd7070Spatrick
1303e5dd7070Spatrick template<typename Fn>
1304e5dd7070Spatrick QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
1305e5dd7070Spatrick FunctionProtoTypeLoc TL,
1306e5dd7070Spatrick CXXRecordDecl *ThisContext,
1307e5dd7070Spatrick Qualifiers ThisTypeQuals,
1308e5dd7070Spatrick Fn TransformExceptionSpec);
1309e5dd7070Spatrick
1310*12c85518Srobert ParmVarDecl *
1311*12c85518Srobert TransformFunctionTypeParam(ParmVarDecl *OldParm, int indexAdjustment,
1312*12c85518Srobert std::optional<unsigned> NumExpansions,
1313e5dd7070Spatrick bool ExpectParameterPack);
1314e5dd7070Spatrick
1315*12c85518Srobert using inherited::TransformTemplateTypeParmType;
1316e5dd7070Spatrick /// Transforms a template type parameter type by performing
1317e5dd7070Spatrick /// substitution of the corresponding template type argument.
1318e5dd7070Spatrick QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
1319*12c85518Srobert TemplateTypeParmTypeLoc TL,
1320*12c85518Srobert bool SuppressObjCLifetime);
1321*12c85518Srobert
1322*12c85518Srobert QualType BuildSubstTemplateTypeParmType(
1323*12c85518Srobert TypeLocBuilder &TLB, bool SuppressObjCLifetime, bool Final,
1324*12c85518Srobert Decl *AssociatedDecl, unsigned Index, std::optional<unsigned> PackIndex,
1325*12c85518Srobert TemplateArgument Arg, SourceLocation NameLoc);
1326e5dd7070Spatrick
1327e5dd7070Spatrick /// Transforms an already-substituted template type parameter pack
1328e5dd7070Spatrick /// into either itself (if we aren't substituting into its pack expansion)
1329e5dd7070Spatrick /// or the appropriate substituted argument.
1330*12c85518Srobert using inherited::TransformSubstTemplateTypeParmPackType;
1331*12c85518Srobert QualType
1332*12c85518Srobert TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB,
1333*12c85518Srobert SubstTemplateTypeParmPackTypeLoc TL,
1334*12c85518Srobert bool SuppressObjCLifetime);
1335e5dd7070Spatrick
TransformLambdaExpr(LambdaExpr * E)1336e5dd7070Spatrick ExprResult TransformLambdaExpr(LambdaExpr *E) {
1337e5dd7070Spatrick LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
1338*12c85518Srobert Sema::ConstraintEvalRAII<TemplateInstantiator> RAII(*this);
1339*12c85518Srobert ExprResult Result = inherited::TransformLambdaExpr(E);
1340*12c85518Srobert if (Result.isInvalid())
1341*12c85518Srobert return Result;
1342*12c85518Srobert
1343*12c85518Srobert CXXMethodDecl *MD = Result.getAs<LambdaExpr>()->getCallOperator();
1344*12c85518Srobert for (ParmVarDecl *PVD : MD->parameters()) {
1345*12c85518Srobert if (!PVD->hasDefaultArg())
1346*12c85518Srobert continue;
1347*12c85518Srobert Expr *UninstExpr = PVD->getUninstantiatedDefaultArg();
1348*12c85518Srobert // FIXME: Obtain the source location for the '=' token.
1349*12c85518Srobert SourceLocation EqualLoc = UninstExpr->getBeginLoc();
1350*12c85518Srobert if (SemaRef.SubstDefaultArgument(EqualLoc, PVD, TemplateArgs)) {
1351*12c85518Srobert // If substitution fails, the default argument is set to a
1352*12c85518Srobert // RecoveryExpr that wraps the uninstantiated default argument so
1353*12c85518Srobert // that downstream diagnostics are omitted.
1354*12c85518Srobert ExprResult ErrorResult = SemaRef.CreateRecoveryExpr(
1355*12c85518Srobert UninstExpr->getBeginLoc(), UninstExpr->getEndLoc(),
1356*12c85518Srobert { UninstExpr }, UninstExpr->getType());
1357*12c85518Srobert if (ErrorResult.isUsable())
1358*12c85518Srobert PVD->setDefaultArg(ErrorResult.get());
1359*12c85518Srobert }
1360*12c85518Srobert }
1361*12c85518Srobert
1362*12c85518Srobert return Result;
1363e5dd7070Spatrick }
1364e5dd7070Spatrick
TransformRequiresExpr(RequiresExpr * E)1365e5dd7070Spatrick ExprResult TransformRequiresExpr(RequiresExpr *E) {
1366e5dd7070Spatrick LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
1367*12c85518Srobert ExprResult TransReq = inherited::TransformRequiresExpr(E);
1368*12c85518Srobert if (TransReq.isInvalid())
1369*12c85518Srobert return TransReq;
1370*12c85518Srobert assert(TransReq.get() != E &&
1371*12c85518Srobert "Do not change value of isSatisfied for the existing expression. "
1372*12c85518Srobert "Create a new expression instead.");
1373*12c85518Srobert if (E->getBody()->isDependentContext()) {
1374*12c85518Srobert Sema::SFINAETrap Trap(SemaRef);
1375*12c85518Srobert // We recreate the RequiresExpr body, but not by instantiating it.
1376*12c85518Srobert // Produce pending diagnostics for dependent access check.
1377*12c85518Srobert SemaRef.PerformDependentDiagnostics(E->getBody(), TemplateArgs);
1378*12c85518Srobert // FIXME: Store SFINAE diagnostics in RequiresExpr for diagnosis.
1379*12c85518Srobert if (Trap.hasErrorOccurred())
1380*12c85518Srobert TransReq.getAs<RequiresExpr>()->setSatisfied(false);
1381*12c85518Srobert }
1382*12c85518Srobert return TransReq;
1383e5dd7070Spatrick }
1384e5dd7070Spatrick
TransformRequiresExprRequirements(ArrayRef<concepts::Requirement * > Reqs,SmallVectorImpl<concepts::Requirement * > & Transformed)1385e5dd7070Spatrick bool TransformRequiresExprRequirements(
1386e5dd7070Spatrick ArrayRef<concepts::Requirement *> Reqs,
1387e5dd7070Spatrick SmallVectorImpl<concepts::Requirement *> &Transformed) {
1388e5dd7070Spatrick bool SatisfactionDetermined = false;
1389e5dd7070Spatrick for (concepts::Requirement *Req : Reqs) {
1390e5dd7070Spatrick concepts::Requirement *TransReq = nullptr;
1391e5dd7070Spatrick if (!SatisfactionDetermined) {
1392e5dd7070Spatrick if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req))
1393e5dd7070Spatrick TransReq = TransformTypeRequirement(TypeReq);
1394e5dd7070Spatrick else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req))
1395e5dd7070Spatrick TransReq = TransformExprRequirement(ExprReq);
1396e5dd7070Spatrick else
1397e5dd7070Spatrick TransReq = TransformNestedRequirement(
1398e5dd7070Spatrick cast<concepts::NestedRequirement>(Req));
1399e5dd7070Spatrick if (!TransReq)
1400e5dd7070Spatrick return true;
1401e5dd7070Spatrick if (!TransReq->isDependent() && !TransReq->isSatisfied())
1402e5dd7070Spatrick // [expr.prim.req]p6
1403e5dd7070Spatrick // [...] The substitution and semantic constraint checking
1404e5dd7070Spatrick // proceeds in lexical order and stops when a condition that
1405e5dd7070Spatrick // determines the result of the requires-expression is
1406e5dd7070Spatrick // encountered. [..]
1407e5dd7070Spatrick SatisfactionDetermined = true;
1408e5dd7070Spatrick } else
1409e5dd7070Spatrick TransReq = Req;
1410e5dd7070Spatrick Transformed.push_back(TransReq);
1411e5dd7070Spatrick }
1412e5dd7070Spatrick return false;
1413e5dd7070Spatrick }
1414e5dd7070Spatrick
TransformTemplateParameterList(TemplateParameterList * OrigTPL)1415e5dd7070Spatrick TemplateParameterList *TransformTemplateParameterList(
1416e5dd7070Spatrick TemplateParameterList *OrigTPL) {
1417e5dd7070Spatrick if (!OrigTPL || !OrigTPL->size()) return OrigTPL;
1418e5dd7070Spatrick
1419e5dd7070Spatrick DeclContext *Owner = OrigTPL->getParam(0)->getDeclContext();
1420e5dd7070Spatrick TemplateDeclInstantiator DeclInstantiator(getSema(),
1421e5dd7070Spatrick /* DeclContext *Owner */ Owner, TemplateArgs);
1422*12c85518Srobert DeclInstantiator.setEvaluateConstraints(EvaluateConstraints);
1423e5dd7070Spatrick return DeclInstantiator.SubstTemplateParams(OrigTPL);
1424e5dd7070Spatrick }
1425e5dd7070Spatrick
1426e5dd7070Spatrick concepts::TypeRequirement *
1427e5dd7070Spatrick TransformTypeRequirement(concepts::TypeRequirement *Req);
1428e5dd7070Spatrick concepts::ExprRequirement *
1429e5dd7070Spatrick TransformExprRequirement(concepts::ExprRequirement *Req);
1430e5dd7070Spatrick concepts::NestedRequirement *
1431e5dd7070Spatrick TransformNestedRequirement(concepts::NestedRequirement *Req);
1432*12c85518Srobert ExprResult TransformRequiresTypeParams(
1433*12c85518Srobert SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
1434*12c85518Srobert RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,
1435*12c85518Srobert SmallVectorImpl<QualType> &PTypes,
1436*12c85518Srobert SmallVectorImpl<ParmVarDecl *> &TransParams,
1437*12c85518Srobert Sema::ExtParameterInfoBuilder &PInfos);
1438e5dd7070Spatrick
1439e5dd7070Spatrick private:
1440*12c85518Srobert ExprResult
1441*12c85518Srobert transformNonTypeTemplateParmRef(Decl *AssociatedDecl,
1442*12c85518Srobert const NonTypeTemplateParmDecl *parm,
1443*12c85518Srobert SourceLocation loc, TemplateArgument arg,
1444*12c85518Srobert std::optional<unsigned> PackIndex);
1445e5dd7070Spatrick };
1446e5dd7070Spatrick }
1447e5dd7070Spatrick
AlreadyTransformed(QualType T)1448e5dd7070Spatrick bool TemplateInstantiator::AlreadyTransformed(QualType T) {
1449e5dd7070Spatrick if (T.isNull())
1450e5dd7070Spatrick return true;
1451e5dd7070Spatrick
1452e5dd7070Spatrick if (T->isInstantiationDependentType() || T->isVariablyModifiedType())
1453e5dd7070Spatrick return false;
1454e5dd7070Spatrick
1455e5dd7070Spatrick getSema().MarkDeclarationsReferencedInType(Loc, T);
1456e5dd7070Spatrick return true;
1457e5dd7070Spatrick }
1458e5dd7070Spatrick
1459e5dd7070Spatrick static TemplateArgument
getPackSubstitutedTemplateArgument(Sema & S,TemplateArgument Arg)1460e5dd7070Spatrick getPackSubstitutedTemplateArgument(Sema &S, TemplateArgument Arg) {
1461e5dd7070Spatrick assert(S.ArgumentPackSubstitutionIndex >= 0);
1462e5dd7070Spatrick assert(S.ArgumentPackSubstitutionIndex < (int)Arg.pack_size());
1463e5dd7070Spatrick Arg = Arg.pack_begin()[S.ArgumentPackSubstitutionIndex];
1464e5dd7070Spatrick if (Arg.isPackExpansion())
1465e5dd7070Spatrick Arg = Arg.getPackExpansionPattern();
1466e5dd7070Spatrick return Arg;
1467e5dd7070Spatrick }
1468e5dd7070Spatrick
TransformDecl(SourceLocation Loc,Decl * D)1469e5dd7070Spatrick Decl *TemplateInstantiator::TransformDecl(SourceLocation Loc, Decl *D) {
1470e5dd7070Spatrick if (!D)
1471e5dd7070Spatrick return nullptr;
1472e5dd7070Spatrick
1473e5dd7070Spatrick if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(D)) {
1474e5dd7070Spatrick if (TTP->getDepth() < TemplateArgs.getNumLevels()) {
1475e5dd7070Spatrick // If the corresponding template argument is NULL or non-existent, it's
1476e5dd7070Spatrick // because we are performing instantiation from explicitly-specified
1477e5dd7070Spatrick // template arguments in a function template, but there were some
1478e5dd7070Spatrick // arguments left unspecified.
1479e5dd7070Spatrick if (!TemplateArgs.hasTemplateArgument(TTP->getDepth(),
1480e5dd7070Spatrick TTP->getPosition()))
1481e5dd7070Spatrick return D;
1482e5dd7070Spatrick
1483e5dd7070Spatrick TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getPosition());
1484e5dd7070Spatrick
1485e5dd7070Spatrick if (TTP->isParameterPack()) {
1486e5dd7070Spatrick assert(Arg.getKind() == TemplateArgument::Pack &&
1487e5dd7070Spatrick "Missing argument pack");
1488e5dd7070Spatrick Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
1489e5dd7070Spatrick }
1490e5dd7070Spatrick
1491e5dd7070Spatrick TemplateName Template = Arg.getAsTemplate().getNameToSubstitute();
1492e5dd7070Spatrick assert(!Template.isNull() && Template.getAsTemplateDecl() &&
1493e5dd7070Spatrick "Wrong kind of template template argument");
1494e5dd7070Spatrick return Template.getAsTemplateDecl();
1495e5dd7070Spatrick }
1496e5dd7070Spatrick
1497e5dd7070Spatrick // Fall through to find the instantiated declaration for this template
1498e5dd7070Spatrick // template parameter.
1499e5dd7070Spatrick }
1500e5dd7070Spatrick
1501e5dd7070Spatrick return SemaRef.FindInstantiatedDecl(Loc, cast<NamedDecl>(D), TemplateArgs);
1502e5dd7070Spatrick }
1503e5dd7070Spatrick
TransformDefinition(SourceLocation Loc,Decl * D)1504e5dd7070Spatrick Decl *TemplateInstantiator::TransformDefinition(SourceLocation Loc, Decl *D) {
1505e5dd7070Spatrick Decl *Inst = getSema().SubstDecl(D, getSema().CurContext, TemplateArgs);
1506e5dd7070Spatrick if (!Inst)
1507e5dd7070Spatrick return nullptr;
1508e5dd7070Spatrick
1509e5dd7070Spatrick getSema().CurrentInstantiationScope->InstantiatedLocal(D, Inst);
1510e5dd7070Spatrick return Inst;
1511e5dd7070Spatrick }
1512e5dd7070Spatrick
1513e5dd7070Spatrick NamedDecl *
TransformFirstQualifierInScope(NamedDecl * D,SourceLocation Loc)1514e5dd7070Spatrick TemplateInstantiator::TransformFirstQualifierInScope(NamedDecl *D,
1515e5dd7070Spatrick SourceLocation Loc) {
1516e5dd7070Spatrick // If the first part of the nested-name-specifier was a template type
1517e5dd7070Spatrick // parameter, instantiate that type parameter down to a tag type.
1518e5dd7070Spatrick if (TemplateTypeParmDecl *TTPD = dyn_cast_or_null<TemplateTypeParmDecl>(D)) {
1519e5dd7070Spatrick const TemplateTypeParmType *TTP
1520e5dd7070Spatrick = cast<TemplateTypeParmType>(getSema().Context.getTypeDeclType(TTPD));
1521e5dd7070Spatrick
1522e5dd7070Spatrick if (TTP->getDepth() < TemplateArgs.getNumLevels()) {
1523e5dd7070Spatrick // FIXME: This needs testing w/ member access expressions.
1524e5dd7070Spatrick TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getIndex());
1525e5dd7070Spatrick
1526e5dd7070Spatrick if (TTP->isParameterPack()) {
1527e5dd7070Spatrick assert(Arg.getKind() == TemplateArgument::Pack &&
1528e5dd7070Spatrick "Missing argument pack");
1529e5dd7070Spatrick
1530e5dd7070Spatrick if (getSema().ArgumentPackSubstitutionIndex == -1)
1531e5dd7070Spatrick return nullptr;
1532e5dd7070Spatrick
1533e5dd7070Spatrick Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
1534e5dd7070Spatrick }
1535e5dd7070Spatrick
1536e5dd7070Spatrick QualType T = Arg.getAsType();
1537e5dd7070Spatrick if (T.isNull())
1538e5dd7070Spatrick return cast_or_null<NamedDecl>(TransformDecl(Loc, D));
1539e5dd7070Spatrick
1540e5dd7070Spatrick if (const TagType *Tag = T->getAs<TagType>())
1541e5dd7070Spatrick return Tag->getDecl();
1542e5dd7070Spatrick
1543e5dd7070Spatrick // The resulting type is not a tag; complain.
1544e5dd7070Spatrick getSema().Diag(Loc, diag::err_nested_name_spec_non_tag) << T;
1545e5dd7070Spatrick return nullptr;
1546e5dd7070Spatrick }
1547e5dd7070Spatrick }
1548e5dd7070Spatrick
1549e5dd7070Spatrick return cast_or_null<NamedDecl>(TransformDecl(Loc, D));
1550e5dd7070Spatrick }
1551e5dd7070Spatrick
1552e5dd7070Spatrick VarDecl *
RebuildExceptionDecl(VarDecl * ExceptionDecl,TypeSourceInfo * Declarator,SourceLocation StartLoc,SourceLocation NameLoc,IdentifierInfo * Name)1553e5dd7070Spatrick TemplateInstantiator::RebuildExceptionDecl(VarDecl *ExceptionDecl,
1554e5dd7070Spatrick TypeSourceInfo *Declarator,
1555e5dd7070Spatrick SourceLocation StartLoc,
1556e5dd7070Spatrick SourceLocation NameLoc,
1557e5dd7070Spatrick IdentifierInfo *Name) {
1558e5dd7070Spatrick VarDecl *Var = inherited::RebuildExceptionDecl(ExceptionDecl, Declarator,
1559e5dd7070Spatrick StartLoc, NameLoc, Name);
1560e5dd7070Spatrick if (Var)
1561e5dd7070Spatrick getSema().CurrentInstantiationScope->InstantiatedLocal(ExceptionDecl, Var);
1562e5dd7070Spatrick return Var;
1563e5dd7070Spatrick }
1564e5dd7070Spatrick
RebuildObjCExceptionDecl(VarDecl * ExceptionDecl,TypeSourceInfo * TSInfo,QualType T)1565e5dd7070Spatrick VarDecl *TemplateInstantiator::RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
1566e5dd7070Spatrick TypeSourceInfo *TSInfo,
1567e5dd7070Spatrick QualType T) {
1568e5dd7070Spatrick VarDecl *Var = inherited::RebuildObjCExceptionDecl(ExceptionDecl, TSInfo, T);
1569e5dd7070Spatrick if (Var)
1570e5dd7070Spatrick getSema().CurrentInstantiationScope->InstantiatedLocal(ExceptionDecl, Var);
1571e5dd7070Spatrick return Var;
1572e5dd7070Spatrick }
1573e5dd7070Spatrick
1574e5dd7070Spatrick QualType
RebuildElaboratedType(SourceLocation KeywordLoc,ElaboratedTypeKeyword Keyword,NestedNameSpecifierLoc QualifierLoc,QualType T)1575e5dd7070Spatrick TemplateInstantiator::RebuildElaboratedType(SourceLocation KeywordLoc,
1576e5dd7070Spatrick ElaboratedTypeKeyword Keyword,
1577e5dd7070Spatrick NestedNameSpecifierLoc QualifierLoc,
1578e5dd7070Spatrick QualType T) {
1579e5dd7070Spatrick if (const TagType *TT = T->getAs<TagType>()) {
1580e5dd7070Spatrick TagDecl* TD = TT->getDecl();
1581e5dd7070Spatrick
1582e5dd7070Spatrick SourceLocation TagLocation = KeywordLoc;
1583e5dd7070Spatrick
1584e5dd7070Spatrick IdentifierInfo *Id = TD->getIdentifier();
1585e5dd7070Spatrick
1586e5dd7070Spatrick // TODO: should we even warn on struct/class mismatches for this? Seems
1587e5dd7070Spatrick // like it's likely to produce a lot of spurious errors.
1588e5dd7070Spatrick if (Id && Keyword != ETK_None && Keyword != ETK_Typename) {
1589e5dd7070Spatrick TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
1590e5dd7070Spatrick if (!SemaRef.isAcceptableTagRedeclaration(TD, Kind, /*isDefinition*/false,
1591e5dd7070Spatrick TagLocation, Id)) {
1592e5dd7070Spatrick SemaRef.Diag(TagLocation, diag::err_use_with_wrong_tag)
1593e5dd7070Spatrick << Id
1594e5dd7070Spatrick << FixItHint::CreateReplacement(SourceRange(TagLocation),
1595e5dd7070Spatrick TD->getKindName());
1596e5dd7070Spatrick SemaRef.Diag(TD->getLocation(), diag::note_previous_use);
1597e5dd7070Spatrick }
1598e5dd7070Spatrick }
1599e5dd7070Spatrick }
1600e5dd7070Spatrick
1601*12c85518Srobert return inherited::RebuildElaboratedType(KeywordLoc, Keyword, QualifierLoc, T);
1602e5dd7070Spatrick }
1603e5dd7070Spatrick
TransformTemplateName(CXXScopeSpec & SS,TemplateName Name,SourceLocation NameLoc,QualType ObjectType,NamedDecl * FirstQualifierInScope,bool AllowInjectedClassName)1604e5dd7070Spatrick TemplateName TemplateInstantiator::TransformTemplateName(
1605e5dd7070Spatrick CXXScopeSpec &SS, TemplateName Name, SourceLocation NameLoc,
1606e5dd7070Spatrick QualType ObjectType, NamedDecl *FirstQualifierInScope,
1607e5dd7070Spatrick bool AllowInjectedClassName) {
1608e5dd7070Spatrick if (TemplateTemplateParmDecl *TTP
1609e5dd7070Spatrick = dyn_cast_or_null<TemplateTemplateParmDecl>(Name.getAsTemplateDecl())) {
1610e5dd7070Spatrick if (TTP->getDepth() < TemplateArgs.getNumLevels()) {
1611e5dd7070Spatrick // If the corresponding template argument is NULL or non-existent, it's
1612e5dd7070Spatrick // because we are performing instantiation from explicitly-specified
1613e5dd7070Spatrick // template arguments in a function template, but there were some
1614e5dd7070Spatrick // arguments left unspecified.
1615e5dd7070Spatrick if (!TemplateArgs.hasTemplateArgument(TTP->getDepth(),
1616e5dd7070Spatrick TTP->getPosition()))
1617e5dd7070Spatrick return Name;
1618e5dd7070Spatrick
1619e5dd7070Spatrick TemplateArgument Arg = TemplateArgs(TTP->getDepth(), TTP->getPosition());
1620e5dd7070Spatrick
1621ec727ea7Spatrick if (TemplateArgs.isRewrite()) {
1622ec727ea7Spatrick // We're rewriting the template parameter as a reference to another
1623ec727ea7Spatrick // template parameter.
1624ec727ea7Spatrick if (Arg.getKind() == TemplateArgument::Pack) {
1625ec727ea7Spatrick assert(Arg.pack_size() == 1 && Arg.pack_begin()->isPackExpansion() &&
1626ec727ea7Spatrick "unexpected pack arguments in template rewrite");
1627ec727ea7Spatrick Arg = Arg.pack_begin()->getPackExpansionPattern();
1628ec727ea7Spatrick }
1629ec727ea7Spatrick assert(Arg.getKind() == TemplateArgument::Template &&
1630ec727ea7Spatrick "unexpected nontype template argument kind in template rewrite");
1631ec727ea7Spatrick return Arg.getAsTemplate();
1632ec727ea7Spatrick }
1633ec727ea7Spatrick
1634*12c85518Srobert auto [AssociatedDecl, Final] =
1635*12c85518Srobert TemplateArgs.getAssociatedDecl(TTP->getDepth());
1636*12c85518Srobert std::optional<unsigned> PackIndex;
1637e5dd7070Spatrick if (TTP->isParameterPack()) {
1638e5dd7070Spatrick assert(Arg.getKind() == TemplateArgument::Pack &&
1639e5dd7070Spatrick "Missing argument pack");
1640e5dd7070Spatrick
1641e5dd7070Spatrick if (getSema().ArgumentPackSubstitutionIndex == -1) {
1642e5dd7070Spatrick // We have the template argument pack to substitute, but we're not
1643e5dd7070Spatrick // actually expanding the enclosing pack expansion yet. So, just
1644e5dd7070Spatrick // keep the entire argument pack.
1645*12c85518Srobert return getSema().Context.getSubstTemplateTemplateParmPack(
1646*12c85518Srobert Arg, AssociatedDecl, TTP->getIndex(), Final);
1647e5dd7070Spatrick }
1648e5dd7070Spatrick
1649*12c85518Srobert PackIndex = getPackIndex(Arg);
1650e5dd7070Spatrick Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
1651e5dd7070Spatrick }
1652e5dd7070Spatrick
1653e5dd7070Spatrick TemplateName Template = Arg.getAsTemplate().getNameToSubstitute();
1654e5dd7070Spatrick assert(!Template.isNull() && "Null template template argument");
1655e5dd7070Spatrick assert(!Template.getAsQualifiedTemplateName() &&
1656e5dd7070Spatrick "template decl to substitute is qualified?");
1657e5dd7070Spatrick
1658*12c85518Srobert if (Final)
1659e5dd7070Spatrick return Template;
1660*12c85518Srobert return getSema().Context.getSubstTemplateTemplateParm(
1661*12c85518Srobert Template, AssociatedDecl, TTP->getIndex(), PackIndex);
1662e5dd7070Spatrick }
1663e5dd7070Spatrick }
1664e5dd7070Spatrick
1665e5dd7070Spatrick if (SubstTemplateTemplateParmPackStorage *SubstPack
1666e5dd7070Spatrick = Name.getAsSubstTemplateTemplateParmPack()) {
1667e5dd7070Spatrick if (getSema().ArgumentPackSubstitutionIndex == -1)
1668e5dd7070Spatrick return Name;
1669e5dd7070Spatrick
1670*12c85518Srobert TemplateArgument Pack = SubstPack->getArgumentPack();
1671*12c85518Srobert TemplateName Template =
1672*12c85518Srobert getPackSubstitutedTemplateArgument(getSema(), Pack).getAsTemplate();
1673*12c85518Srobert if (SubstPack->getFinal())
1674*12c85518Srobert return Template;
1675*12c85518Srobert return getSema().Context.getSubstTemplateTemplateParm(
1676*12c85518Srobert Template.getNameToSubstitute(), SubstPack->getAssociatedDecl(),
1677*12c85518Srobert SubstPack->getIndex(), getPackIndex(Pack));
1678e5dd7070Spatrick }
1679e5dd7070Spatrick
1680e5dd7070Spatrick return inherited::TransformTemplateName(SS, Name, NameLoc, ObjectType,
1681e5dd7070Spatrick FirstQualifierInScope,
1682e5dd7070Spatrick AllowInjectedClassName);
1683e5dd7070Spatrick }
1684e5dd7070Spatrick
1685e5dd7070Spatrick ExprResult
TransformPredefinedExpr(PredefinedExpr * E)1686e5dd7070Spatrick TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) {
1687e5dd7070Spatrick if (!E->isTypeDependent())
1688e5dd7070Spatrick return E;
1689e5dd7070Spatrick
1690e5dd7070Spatrick return getSema().BuildPredefinedExpr(E->getLocation(), E->getIdentKind());
1691e5dd7070Spatrick }
1692e5dd7070Spatrick
1693e5dd7070Spatrick ExprResult
TransformTemplateParmRefExpr(DeclRefExpr * E,NonTypeTemplateParmDecl * NTTP)1694e5dd7070Spatrick TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,
1695e5dd7070Spatrick NonTypeTemplateParmDecl *NTTP) {
1696e5dd7070Spatrick // If the corresponding template argument is NULL or non-existent, it's
1697e5dd7070Spatrick // because we are performing instantiation from explicitly-specified
1698e5dd7070Spatrick // template arguments in a function template, but there were some
1699e5dd7070Spatrick // arguments left unspecified.
1700e5dd7070Spatrick if (!TemplateArgs.hasTemplateArgument(NTTP->getDepth(),
1701e5dd7070Spatrick NTTP->getPosition()))
1702e5dd7070Spatrick return E;
1703e5dd7070Spatrick
1704e5dd7070Spatrick TemplateArgument Arg = TemplateArgs(NTTP->getDepth(), NTTP->getPosition());
1705e5dd7070Spatrick
1706ec727ea7Spatrick if (TemplateArgs.isRewrite()) {
1707ec727ea7Spatrick // We're rewriting the template parameter as a reference to another
1708ec727ea7Spatrick // template parameter.
1709e5dd7070Spatrick if (Arg.getKind() == TemplateArgument::Pack) {
1710e5dd7070Spatrick assert(Arg.pack_size() == 1 && Arg.pack_begin()->isPackExpansion() &&
1711ec727ea7Spatrick "unexpected pack arguments in template rewrite");
1712e5dd7070Spatrick Arg = Arg.pack_begin()->getPackExpansionPattern();
1713e5dd7070Spatrick }
1714e5dd7070Spatrick assert(Arg.getKind() == TemplateArgument::Expression &&
1715ec727ea7Spatrick "unexpected nontype template argument kind in template rewrite");
1716ec727ea7Spatrick // FIXME: This can lead to the same subexpression appearing multiple times
1717ec727ea7Spatrick // in a complete expression.
1718e5dd7070Spatrick return Arg.getAsExpr();
1719e5dd7070Spatrick }
1720e5dd7070Spatrick
1721*12c85518Srobert auto [AssociatedDecl, _] = TemplateArgs.getAssociatedDecl(NTTP->getDepth());
1722*12c85518Srobert std::optional<unsigned> PackIndex;
1723e5dd7070Spatrick if (NTTP->isParameterPack()) {
1724e5dd7070Spatrick assert(Arg.getKind() == TemplateArgument::Pack &&
1725e5dd7070Spatrick "Missing argument pack");
1726e5dd7070Spatrick
1727e5dd7070Spatrick if (getSema().ArgumentPackSubstitutionIndex == -1) {
1728e5dd7070Spatrick // We have an argument pack, but we can't select a particular argument
1729e5dd7070Spatrick // out of it yet. Therefore, we'll build an expression to hold on to that
1730e5dd7070Spatrick // argument pack.
1731e5dd7070Spatrick QualType TargetType = SemaRef.SubstType(NTTP->getType(), TemplateArgs,
1732e5dd7070Spatrick E->getLocation(),
1733e5dd7070Spatrick NTTP->getDeclName());
1734e5dd7070Spatrick if (TargetType.isNull())
1735e5dd7070Spatrick return ExprError();
1736e5dd7070Spatrick
1737a9ac8606Spatrick QualType ExprType = TargetType.getNonLValueExprType(SemaRef.Context);
1738a9ac8606Spatrick if (TargetType->isRecordType())
1739a9ac8606Spatrick ExprType.addConst();
1740*12c85518Srobert // FIXME: Pass in Final.
1741e5dd7070Spatrick return new (SemaRef.Context) SubstNonTypeTemplateParmPackExpr(
1742a9ac8606Spatrick ExprType, TargetType->isReferenceType() ? VK_LValue : VK_PRValue,
1743*12c85518Srobert E->getLocation(), Arg, AssociatedDecl, NTTP->getPosition());
1744e5dd7070Spatrick }
1745*12c85518Srobert PackIndex = getPackIndex(Arg);
1746e5dd7070Spatrick Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
1747e5dd7070Spatrick }
1748*12c85518Srobert // FIXME: Don't put subst node on Final replacement.
1749*12c85518Srobert return transformNonTypeTemplateParmRef(AssociatedDecl, NTTP, E->getLocation(),
1750*12c85518Srobert Arg, PackIndex);
1751e5dd7070Spatrick }
1752e5dd7070Spatrick
1753e5dd7070Spatrick const LoopHintAttr *
TransformLoopHintAttr(const LoopHintAttr * LH)1754e5dd7070Spatrick TemplateInstantiator::TransformLoopHintAttr(const LoopHintAttr *LH) {
1755e5dd7070Spatrick Expr *TransformedExpr = getDerived().TransformExpr(LH->getValue()).get();
1756e5dd7070Spatrick
1757e5dd7070Spatrick if (TransformedExpr == LH->getValue())
1758e5dd7070Spatrick return LH;
1759e5dd7070Spatrick
1760e5dd7070Spatrick // Generate error if there is a problem with the value.
1761e5dd7070Spatrick if (getSema().CheckLoopHintExpr(TransformedExpr, LH->getLocation()))
1762e5dd7070Spatrick return LH;
1763e5dd7070Spatrick
1764e5dd7070Spatrick // Create new LoopHintValueAttr with integral expression in place of the
1765e5dd7070Spatrick // non-type template parameter.
1766e5dd7070Spatrick return LoopHintAttr::CreateImplicit(getSema().Context, LH->getOption(),
1767e5dd7070Spatrick LH->getState(), TransformedExpr, *LH);
1768e5dd7070Spatrick }
1769e5dd7070Spatrick
transformNonTypeTemplateParmRef(Decl * AssociatedDecl,const NonTypeTemplateParmDecl * parm,SourceLocation loc,TemplateArgument arg,std::optional<unsigned> PackIndex)1770e5dd7070Spatrick ExprResult TemplateInstantiator::transformNonTypeTemplateParmRef(
1771*12c85518Srobert Decl *AssociatedDecl, const NonTypeTemplateParmDecl *parm,
1772*12c85518Srobert SourceLocation loc, TemplateArgument arg,
1773*12c85518Srobert std::optional<unsigned> PackIndex) {
1774e5dd7070Spatrick ExprResult result;
1775e5dd7070Spatrick
1776a9ac8606Spatrick // Determine the substituted parameter type. We can usually infer this from
1777a9ac8606Spatrick // the template argument, but not always.
1778a9ac8606Spatrick auto SubstParamType = [&] {
1779a9ac8606Spatrick QualType T;
1780a9ac8606Spatrick if (parm->isExpandedParameterPack())
1781a9ac8606Spatrick T = parm->getExpansionType(SemaRef.ArgumentPackSubstitutionIndex);
1782a9ac8606Spatrick else
1783a9ac8606Spatrick T = parm->getType();
1784a9ac8606Spatrick if (parm->isParameterPack() && isa<PackExpansionType>(T))
1785a9ac8606Spatrick T = cast<PackExpansionType>(T)->getPattern();
1786a9ac8606Spatrick return SemaRef.SubstType(T, TemplateArgs, loc, parm->getDeclName());
1787a9ac8606Spatrick };
1788a9ac8606Spatrick
1789a9ac8606Spatrick bool refParam = false;
1790a9ac8606Spatrick
1791a9ac8606Spatrick // The template argument itself might be an expression, in which case we just
1792a9ac8606Spatrick // return that expression. This happens when substituting into an alias
1793a9ac8606Spatrick // template.
1794e5dd7070Spatrick if (arg.getKind() == TemplateArgument::Expression) {
1795e5dd7070Spatrick Expr *argExpr = arg.getAsExpr();
1796e5dd7070Spatrick result = argExpr;
1797a9ac8606Spatrick if (argExpr->isLValue()) {
1798a9ac8606Spatrick if (argExpr->getType()->isRecordType()) {
1799a9ac8606Spatrick // Check whether the parameter was actually a reference.
1800a9ac8606Spatrick QualType paramType = SubstParamType();
1801a9ac8606Spatrick if (paramType.isNull())
1802a9ac8606Spatrick return ExprError();
1803a9ac8606Spatrick refParam = paramType->isReferenceType();
1804a9ac8606Spatrick } else {
1805a9ac8606Spatrick refParam = true;
1806a9ac8606Spatrick }
1807a9ac8606Spatrick }
1808e5dd7070Spatrick } else if (arg.getKind() == TemplateArgument::Declaration ||
1809e5dd7070Spatrick arg.getKind() == TemplateArgument::NullPtr) {
1810e5dd7070Spatrick ValueDecl *VD;
1811e5dd7070Spatrick if (arg.getKind() == TemplateArgument::Declaration) {
1812e5dd7070Spatrick VD = arg.getAsDecl();
1813e5dd7070Spatrick
1814e5dd7070Spatrick // Find the instantiation of the template argument. This is
1815e5dd7070Spatrick // required for nested templates.
1816e5dd7070Spatrick VD = cast_or_null<ValueDecl>(
1817e5dd7070Spatrick getSema().FindInstantiatedDecl(loc, VD, TemplateArgs));
1818e5dd7070Spatrick if (!VD)
1819e5dd7070Spatrick return ExprError();
1820e5dd7070Spatrick } else {
1821e5dd7070Spatrick // Propagate NULL template argument.
1822e5dd7070Spatrick VD = nullptr;
1823e5dd7070Spatrick }
1824e5dd7070Spatrick
1825a9ac8606Spatrick QualType paramType = VD ? arg.getParamTypeForDecl() : arg.getNullPtrType();
1826a9ac8606Spatrick assert(!paramType.isNull() && "type substitution failed for param type");
1827a9ac8606Spatrick assert(!paramType->isDependentType() && "param type still dependent");
1828a9ac8606Spatrick result = SemaRef.BuildExpressionFromDeclTemplateArgument(arg, paramType, loc);
1829a9ac8606Spatrick refParam = paramType->isReferenceType();
1830e5dd7070Spatrick } else {
1831e5dd7070Spatrick result = SemaRef.BuildExpressionFromIntegralTemplateArgument(arg, loc);
1832a9ac8606Spatrick assert(result.isInvalid() ||
1833a9ac8606Spatrick SemaRef.Context.hasSameType(result.get()->getType(),
1834a9ac8606Spatrick arg.getIntegralType()));
1835e5dd7070Spatrick }
1836a9ac8606Spatrick
1837a9ac8606Spatrick if (result.isInvalid())
1838a9ac8606Spatrick return ExprError();
1839e5dd7070Spatrick
1840e5dd7070Spatrick Expr *resultExpr = result.get();
1841*12c85518Srobert // FIXME: Don't put subst node on final replacement.
1842e5dd7070Spatrick return new (SemaRef.Context) SubstNonTypeTemplateParmExpr(
1843*12c85518Srobert resultExpr->getType(), resultExpr->getValueKind(), loc, resultExpr,
1844*12c85518Srobert AssociatedDecl, parm->getIndex(), PackIndex, refParam);
1845e5dd7070Spatrick }
1846e5dd7070Spatrick
1847e5dd7070Spatrick ExprResult
TransformSubstNonTypeTemplateParmPackExpr(SubstNonTypeTemplateParmPackExpr * E)1848e5dd7070Spatrick TemplateInstantiator::TransformSubstNonTypeTemplateParmPackExpr(
1849e5dd7070Spatrick SubstNonTypeTemplateParmPackExpr *E) {
1850e5dd7070Spatrick if (getSema().ArgumentPackSubstitutionIndex == -1) {
1851e5dd7070Spatrick // We aren't expanding the parameter pack, so just return ourselves.
1852e5dd7070Spatrick return E;
1853e5dd7070Spatrick }
1854e5dd7070Spatrick
1855*12c85518Srobert TemplateArgument Pack = E->getArgumentPack();
1856*12c85518Srobert TemplateArgument Arg = getPackSubstitutedTemplateArgument(getSema(), Pack);
1857*12c85518Srobert // FIXME: Don't put subst node on final replacement.
1858*12c85518Srobert return transformNonTypeTemplateParmRef(
1859*12c85518Srobert E->getAssociatedDecl(), E->getParameterPack(),
1860*12c85518Srobert E->getParameterPackLocation(), Arg, getPackIndex(Pack));
1861e5dd7070Spatrick }
1862e5dd7070Spatrick
1863e5dd7070Spatrick ExprResult
TransformSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr * E)1864e5dd7070Spatrick TemplateInstantiator::TransformSubstNonTypeTemplateParmExpr(
1865e5dd7070Spatrick SubstNonTypeTemplateParmExpr *E) {
1866a9ac8606Spatrick ExprResult SubstReplacement = E->getReplacement();
1867a9ac8606Spatrick if (!isa<ConstantExpr>(SubstReplacement.get()))
1868a9ac8606Spatrick SubstReplacement = TransformExpr(E->getReplacement());
1869e5dd7070Spatrick if (SubstReplacement.isInvalid())
1870e5dd7070Spatrick return true;
1871a9ac8606Spatrick QualType SubstType = TransformType(E->getParameterType(getSema().Context));
1872e5dd7070Spatrick if (SubstType.isNull())
1873e5dd7070Spatrick return true;
1874e5dd7070Spatrick // The type may have been previously dependent and not now, which means we
1875e5dd7070Spatrick // might have to implicit cast the argument to the new type, for example:
1876e5dd7070Spatrick // template<auto T, decltype(T) U>
1877e5dd7070Spatrick // concept C = sizeof(U) == 4;
1878e5dd7070Spatrick // void foo() requires C<2, 'a'> { }
1879e5dd7070Spatrick // When normalizing foo(), we first form the normalized constraints of C:
1880e5dd7070Spatrick // AtomicExpr(sizeof(U) == 4,
1881e5dd7070Spatrick // U=SubstNonTypeTemplateParmExpr(Param=U,
1882e5dd7070Spatrick // Expr=DeclRef(U),
1883e5dd7070Spatrick // Type=decltype(T)))
1884e5dd7070Spatrick // Then we substitute T = 2, U = 'a' into the parameter mapping, and need to
1885e5dd7070Spatrick // produce:
1886e5dd7070Spatrick // AtomicExpr(sizeof(U) == 4,
1887e5dd7070Spatrick // U=SubstNonTypeTemplateParmExpr(Param=U,
1888e5dd7070Spatrick // Expr=ImpCast(
1889e5dd7070Spatrick // decltype(2),
1890e5dd7070Spatrick // SubstNTTPE(Param=U, Expr='a',
1891e5dd7070Spatrick // Type=char)),
1892e5dd7070Spatrick // Type=decltype(2)))
1893e5dd7070Spatrick // The call to CheckTemplateArgument here produces the ImpCast.
1894*12c85518Srobert TemplateArgument SugaredConverted, CanonicalConverted;
1895*12c85518Srobert if (SemaRef
1896*12c85518Srobert .CheckTemplateArgument(E->getParameter(), SubstType,
1897*12c85518Srobert SubstReplacement.get(), SugaredConverted,
1898*12c85518Srobert CanonicalConverted, Sema::CTAK_Specified)
1899*12c85518Srobert .isInvalid())
1900e5dd7070Spatrick return true;
1901*12c85518Srobert return transformNonTypeTemplateParmRef(E->getAssociatedDecl(),
1902*12c85518Srobert E->getParameter(), E->getExprLoc(),
1903*12c85518Srobert SugaredConverted, E->getPackIndex());
1904e5dd7070Spatrick }
1905e5dd7070Spatrick
RebuildVarDeclRefExpr(VarDecl * PD,SourceLocation Loc)1906e5dd7070Spatrick ExprResult TemplateInstantiator::RebuildVarDeclRefExpr(VarDecl *PD,
1907e5dd7070Spatrick SourceLocation Loc) {
1908e5dd7070Spatrick DeclarationNameInfo NameInfo(PD->getDeclName(), Loc);
1909e5dd7070Spatrick return getSema().BuildDeclarationNameExpr(CXXScopeSpec(), NameInfo, PD);
1910e5dd7070Spatrick }
1911e5dd7070Spatrick
1912e5dd7070Spatrick ExprResult
TransformFunctionParmPackExpr(FunctionParmPackExpr * E)1913e5dd7070Spatrick TemplateInstantiator::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
1914e5dd7070Spatrick if (getSema().ArgumentPackSubstitutionIndex != -1) {
1915e5dd7070Spatrick // We can expand this parameter pack now.
1916e5dd7070Spatrick VarDecl *D = E->getExpansion(getSema().ArgumentPackSubstitutionIndex);
1917e5dd7070Spatrick VarDecl *VD = cast_or_null<VarDecl>(TransformDecl(E->getExprLoc(), D));
1918e5dd7070Spatrick if (!VD)
1919e5dd7070Spatrick return ExprError();
1920e5dd7070Spatrick return RebuildVarDeclRefExpr(VD, E->getExprLoc());
1921e5dd7070Spatrick }
1922e5dd7070Spatrick
1923e5dd7070Spatrick QualType T = TransformType(E->getType());
1924e5dd7070Spatrick if (T.isNull())
1925e5dd7070Spatrick return ExprError();
1926e5dd7070Spatrick
1927e5dd7070Spatrick // Transform each of the parameter expansions into the corresponding
1928e5dd7070Spatrick // parameters in the instantiation of the function decl.
1929e5dd7070Spatrick SmallVector<VarDecl *, 8> Vars;
1930e5dd7070Spatrick Vars.reserve(E->getNumExpansions());
1931e5dd7070Spatrick for (FunctionParmPackExpr::iterator I = E->begin(), End = E->end();
1932e5dd7070Spatrick I != End; ++I) {
1933e5dd7070Spatrick VarDecl *D = cast_or_null<VarDecl>(TransformDecl(E->getExprLoc(), *I));
1934e5dd7070Spatrick if (!D)
1935e5dd7070Spatrick return ExprError();
1936e5dd7070Spatrick Vars.push_back(D);
1937e5dd7070Spatrick }
1938e5dd7070Spatrick
1939e5dd7070Spatrick auto *PackExpr =
1940e5dd7070Spatrick FunctionParmPackExpr::Create(getSema().Context, T, E->getParameterPack(),
1941e5dd7070Spatrick E->getParameterPackLocation(), Vars);
1942e5dd7070Spatrick getSema().MarkFunctionParmPackReferenced(PackExpr);
1943e5dd7070Spatrick return PackExpr;
1944e5dd7070Spatrick }
1945e5dd7070Spatrick
1946e5dd7070Spatrick ExprResult
TransformFunctionParmPackRefExpr(DeclRefExpr * E,VarDecl * PD)1947e5dd7070Spatrick TemplateInstantiator::TransformFunctionParmPackRefExpr(DeclRefExpr *E,
1948e5dd7070Spatrick VarDecl *PD) {
1949e5dd7070Spatrick typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
1950e5dd7070Spatrick llvm::PointerUnion<Decl *, DeclArgumentPack *> *Found
1951e5dd7070Spatrick = getSema().CurrentInstantiationScope->findInstantiationOf(PD);
1952e5dd7070Spatrick assert(Found && "no instantiation for parameter pack");
1953e5dd7070Spatrick
1954e5dd7070Spatrick Decl *TransformedDecl;
1955e5dd7070Spatrick if (DeclArgumentPack *Pack = Found->dyn_cast<DeclArgumentPack *>()) {
1956e5dd7070Spatrick // If this is a reference to a function parameter pack which we can
1957e5dd7070Spatrick // substitute but can't yet expand, build a FunctionParmPackExpr for it.
1958e5dd7070Spatrick if (getSema().ArgumentPackSubstitutionIndex == -1) {
1959e5dd7070Spatrick QualType T = TransformType(E->getType());
1960e5dd7070Spatrick if (T.isNull())
1961e5dd7070Spatrick return ExprError();
1962e5dd7070Spatrick auto *PackExpr = FunctionParmPackExpr::Create(getSema().Context, T, PD,
1963e5dd7070Spatrick E->getExprLoc(), *Pack);
1964e5dd7070Spatrick getSema().MarkFunctionParmPackReferenced(PackExpr);
1965e5dd7070Spatrick return PackExpr;
1966e5dd7070Spatrick }
1967e5dd7070Spatrick
1968e5dd7070Spatrick TransformedDecl = (*Pack)[getSema().ArgumentPackSubstitutionIndex];
1969e5dd7070Spatrick } else {
1970e5dd7070Spatrick TransformedDecl = Found->get<Decl*>();
1971e5dd7070Spatrick }
1972e5dd7070Spatrick
1973e5dd7070Spatrick // We have either an unexpanded pack or a specific expansion.
1974e5dd7070Spatrick return RebuildVarDeclRefExpr(cast<VarDecl>(TransformedDecl), E->getExprLoc());
1975e5dd7070Spatrick }
1976e5dd7070Spatrick
1977e5dd7070Spatrick ExprResult
TransformDeclRefExpr(DeclRefExpr * E)1978e5dd7070Spatrick TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E) {
1979e5dd7070Spatrick NamedDecl *D = E->getDecl();
1980e5dd7070Spatrick
1981e5dd7070Spatrick // Handle references to non-type template parameters and non-type template
1982e5dd7070Spatrick // parameter packs.
1983e5dd7070Spatrick if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
1984e5dd7070Spatrick if (NTTP->getDepth() < TemplateArgs.getNumLevels())
1985e5dd7070Spatrick return TransformTemplateParmRefExpr(E, NTTP);
1986e5dd7070Spatrick
1987e5dd7070Spatrick // We have a non-type template parameter that isn't fully substituted;
1988e5dd7070Spatrick // FindInstantiatedDecl will find it in the local instantiation scope.
1989e5dd7070Spatrick }
1990e5dd7070Spatrick
1991e5dd7070Spatrick // Handle references to function parameter packs.
1992e5dd7070Spatrick if (VarDecl *PD = dyn_cast<VarDecl>(D))
1993e5dd7070Spatrick if (PD->isParameterPack())
1994e5dd7070Spatrick return TransformFunctionParmPackRefExpr(E, PD);
1995e5dd7070Spatrick
1996*12c85518Srobert return inherited::TransformDeclRefExpr(E);
1997e5dd7070Spatrick }
1998e5dd7070Spatrick
TransformCXXDefaultArgExpr(CXXDefaultArgExpr * E)1999e5dd7070Spatrick ExprResult TemplateInstantiator::TransformCXXDefaultArgExpr(
2000e5dd7070Spatrick CXXDefaultArgExpr *E) {
2001e5dd7070Spatrick assert(!cast<FunctionDecl>(E->getParam()->getDeclContext())->
2002e5dd7070Spatrick getDescribedFunctionTemplate() &&
2003e5dd7070Spatrick "Default arg expressions are never formed in dependent cases.");
2004*12c85518Srobert return SemaRef.BuildCXXDefaultArgExpr(
2005*12c85518Srobert E->getUsedLocation(), cast<FunctionDecl>(E->getParam()->getDeclContext()),
2006e5dd7070Spatrick E->getParam());
2007e5dd7070Spatrick }
2008e5dd7070Spatrick
2009e5dd7070Spatrick template<typename Fn>
TransformFunctionProtoType(TypeLocBuilder & TLB,FunctionProtoTypeLoc TL,CXXRecordDecl * ThisContext,Qualifiers ThisTypeQuals,Fn TransformExceptionSpec)2010e5dd7070Spatrick QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB,
2011e5dd7070Spatrick FunctionProtoTypeLoc TL,
2012e5dd7070Spatrick CXXRecordDecl *ThisContext,
2013e5dd7070Spatrick Qualifiers ThisTypeQuals,
2014e5dd7070Spatrick Fn TransformExceptionSpec) {
2015e5dd7070Spatrick // We need a local instantiation scope for this function prototype.
2016e5dd7070Spatrick LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
2017e5dd7070Spatrick return inherited::TransformFunctionProtoType(
2018e5dd7070Spatrick TLB, TL, ThisContext, ThisTypeQuals, TransformExceptionSpec);
2019e5dd7070Spatrick }
2020e5dd7070Spatrick
TransformFunctionTypeParam(ParmVarDecl * OldParm,int indexAdjustment,std::optional<unsigned> NumExpansions,bool ExpectParameterPack)2021*12c85518Srobert ParmVarDecl *TemplateInstantiator::TransformFunctionTypeParam(
2022*12c85518Srobert ParmVarDecl *OldParm, int indexAdjustment,
2023*12c85518Srobert std::optional<unsigned> NumExpansions, bool ExpectParameterPack) {
2024*12c85518Srobert auto NewParm = SemaRef.SubstParmVarDecl(
2025*12c85518Srobert OldParm, TemplateArgs, indexAdjustment, NumExpansions,
2026*12c85518Srobert ExpectParameterPack, EvaluateConstraints);
2027e5dd7070Spatrick if (NewParm && SemaRef.getLangOpts().OpenCL)
2028e5dd7070Spatrick SemaRef.deduceOpenCLAddressSpace(NewParm);
2029e5dd7070Spatrick return NewParm;
2030e5dd7070Spatrick }
2031e5dd7070Spatrick
BuildSubstTemplateTypeParmType(TypeLocBuilder & TLB,bool SuppressObjCLifetime,bool Final,Decl * AssociatedDecl,unsigned Index,std::optional<unsigned> PackIndex,TemplateArgument Arg,SourceLocation NameLoc)2032*12c85518Srobert QualType TemplateInstantiator::BuildSubstTemplateTypeParmType(
2033*12c85518Srobert TypeLocBuilder &TLB, bool SuppressObjCLifetime, bool Final,
2034*12c85518Srobert Decl *AssociatedDecl, unsigned Index, std::optional<unsigned> PackIndex,
2035*12c85518Srobert TemplateArgument Arg, SourceLocation NameLoc) {
2036*12c85518Srobert QualType Replacement = Arg.getAsType();
2037*12c85518Srobert
2038*12c85518Srobert // If the template parameter had ObjC lifetime qualifiers,
2039*12c85518Srobert // then any such qualifiers on the replacement type are ignored.
2040*12c85518Srobert if (SuppressObjCLifetime) {
2041*12c85518Srobert Qualifiers RQs;
2042*12c85518Srobert RQs = Replacement.getQualifiers();
2043*12c85518Srobert RQs.removeObjCLifetime();
2044*12c85518Srobert Replacement =
2045*12c85518Srobert SemaRef.Context.getQualifiedType(Replacement.getUnqualifiedType(), RQs);
2046*12c85518Srobert }
2047*12c85518Srobert
2048*12c85518Srobert if (Final) {
2049*12c85518Srobert TLB.pushTrivial(SemaRef.Context, Replacement, NameLoc);
2050*12c85518Srobert return Replacement;
2051*12c85518Srobert }
2052*12c85518Srobert // TODO: only do this uniquing once, at the start of instantiation.
2053*12c85518Srobert QualType Result = getSema().Context.getSubstTemplateTypeParmType(
2054*12c85518Srobert Replacement, AssociatedDecl, Index, PackIndex);
2055*12c85518Srobert SubstTemplateTypeParmTypeLoc NewTL =
2056*12c85518Srobert TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
2057*12c85518Srobert NewTL.setNameLoc(NameLoc);
2058*12c85518Srobert return Result;
2059*12c85518Srobert }
2060*12c85518Srobert
2061e5dd7070Spatrick QualType
TransformTemplateTypeParmType(TypeLocBuilder & TLB,TemplateTypeParmTypeLoc TL,bool SuppressObjCLifetime)2062e5dd7070Spatrick TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB,
2063*12c85518Srobert TemplateTypeParmTypeLoc TL,
2064*12c85518Srobert bool SuppressObjCLifetime) {
2065e5dd7070Spatrick const TemplateTypeParmType *T = TL.getTypePtr();
2066e5dd7070Spatrick if (T->getDepth() < TemplateArgs.getNumLevels()) {
2067e5dd7070Spatrick // Replace the template type parameter with its corresponding
2068e5dd7070Spatrick // template argument.
2069e5dd7070Spatrick
2070e5dd7070Spatrick // If the corresponding template argument is NULL or doesn't exist, it's
2071e5dd7070Spatrick // because we are performing instantiation from explicitly-specified
2072e5dd7070Spatrick // template arguments in a function template class, but there were some
2073e5dd7070Spatrick // arguments left unspecified.
2074e5dd7070Spatrick if (!TemplateArgs.hasTemplateArgument(T->getDepth(), T->getIndex())) {
2075e5dd7070Spatrick TemplateTypeParmTypeLoc NewTL
2076e5dd7070Spatrick = TLB.push<TemplateTypeParmTypeLoc>(TL.getType());
2077e5dd7070Spatrick NewTL.setNameLoc(TL.getNameLoc());
2078e5dd7070Spatrick return TL.getType();
2079e5dd7070Spatrick }
2080e5dd7070Spatrick
2081e5dd7070Spatrick TemplateArgument Arg = TemplateArgs(T->getDepth(), T->getIndex());
2082e5dd7070Spatrick
2083ec727ea7Spatrick if (TemplateArgs.isRewrite()) {
2084ec727ea7Spatrick // We're rewriting the template parameter as a reference to another
2085ec727ea7Spatrick // template parameter.
2086ec727ea7Spatrick if (Arg.getKind() == TemplateArgument::Pack) {
2087ec727ea7Spatrick assert(Arg.pack_size() == 1 && Arg.pack_begin()->isPackExpansion() &&
2088ec727ea7Spatrick "unexpected pack arguments in template rewrite");
2089ec727ea7Spatrick Arg = Arg.pack_begin()->getPackExpansionPattern();
2090ec727ea7Spatrick }
2091ec727ea7Spatrick assert(Arg.getKind() == TemplateArgument::Type &&
2092ec727ea7Spatrick "unexpected nontype template argument kind in template rewrite");
2093ec727ea7Spatrick QualType NewT = Arg.getAsType();
2094ec727ea7Spatrick assert(isa<TemplateTypeParmType>(NewT) &&
2095ec727ea7Spatrick "type parm not rewritten to type parm");
2096ec727ea7Spatrick auto NewTL = TLB.push<TemplateTypeParmTypeLoc>(NewT);
2097ec727ea7Spatrick NewTL.setNameLoc(TL.getNameLoc());
2098ec727ea7Spatrick return NewT;
2099ec727ea7Spatrick }
2100ec727ea7Spatrick
2101*12c85518Srobert auto [AssociatedDecl, Final] =
2102*12c85518Srobert TemplateArgs.getAssociatedDecl(T->getDepth());
2103*12c85518Srobert std::optional<unsigned> PackIndex;
2104e5dd7070Spatrick if (T->isParameterPack()) {
2105e5dd7070Spatrick assert(Arg.getKind() == TemplateArgument::Pack &&
2106e5dd7070Spatrick "Missing argument pack");
2107e5dd7070Spatrick
2108e5dd7070Spatrick if (getSema().ArgumentPackSubstitutionIndex == -1) {
2109e5dd7070Spatrick // We have the template argument pack, but we're not expanding the
2110e5dd7070Spatrick // enclosing pack expansion yet. Just save the template argument
2111e5dd7070Spatrick // pack for later substitution.
2112*12c85518Srobert QualType Result = getSema().Context.getSubstTemplateTypeParmPackType(
2113*12c85518Srobert AssociatedDecl, T->getIndex(), Final, Arg);
2114e5dd7070Spatrick SubstTemplateTypeParmPackTypeLoc NewTL
2115e5dd7070Spatrick = TLB.push<SubstTemplateTypeParmPackTypeLoc>(Result);
2116e5dd7070Spatrick NewTL.setNameLoc(TL.getNameLoc());
2117e5dd7070Spatrick return Result;
2118e5dd7070Spatrick }
2119e5dd7070Spatrick
2120*12c85518Srobert // PackIndex starts from last element.
2121*12c85518Srobert PackIndex = getPackIndex(Arg);
2122e5dd7070Spatrick Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
2123e5dd7070Spatrick }
2124e5dd7070Spatrick
2125e5dd7070Spatrick assert(Arg.getKind() == TemplateArgument::Type &&
2126e5dd7070Spatrick "Template argument kind mismatch");
2127e5dd7070Spatrick
2128*12c85518Srobert return BuildSubstTemplateTypeParmType(TLB, SuppressObjCLifetime, Final,
2129*12c85518Srobert AssociatedDecl, T->getIndex(),
2130*12c85518Srobert PackIndex, Arg, TL.getNameLoc());
2131e5dd7070Spatrick }
2132e5dd7070Spatrick
2133e5dd7070Spatrick // The template type parameter comes from an inner template (e.g.,
2134e5dd7070Spatrick // the template parameter list of a member template inside the
2135e5dd7070Spatrick // template we are instantiating). Create a new template type
2136e5dd7070Spatrick // parameter with the template "level" reduced by one.
2137e5dd7070Spatrick TemplateTypeParmDecl *NewTTPDecl = nullptr;
2138e5dd7070Spatrick if (TemplateTypeParmDecl *OldTTPDecl = T->getDecl())
2139e5dd7070Spatrick NewTTPDecl = cast_or_null<TemplateTypeParmDecl>(
2140e5dd7070Spatrick TransformDecl(TL.getNameLoc(), OldTTPDecl));
2141e5dd7070Spatrick QualType Result = getSema().Context.getTemplateTypeParmType(
2142e5dd7070Spatrick T->getDepth() - TemplateArgs.getNumSubstitutedLevels(), T->getIndex(),
2143e5dd7070Spatrick T->isParameterPack(), NewTTPDecl);
2144e5dd7070Spatrick TemplateTypeParmTypeLoc NewTL = TLB.push<TemplateTypeParmTypeLoc>(Result);
2145e5dd7070Spatrick NewTL.setNameLoc(TL.getNameLoc());
2146e5dd7070Spatrick return Result;
2147e5dd7070Spatrick }
2148e5dd7070Spatrick
TransformSubstTemplateTypeParmPackType(TypeLocBuilder & TLB,SubstTemplateTypeParmPackTypeLoc TL,bool SuppressObjCLifetime)2149*12c85518Srobert QualType TemplateInstantiator::TransformSubstTemplateTypeParmPackType(
2150*12c85518Srobert TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL,
2151*12c85518Srobert bool SuppressObjCLifetime) {
2152*12c85518Srobert const SubstTemplateTypeParmPackType *T = TL.getTypePtr();
2153*12c85518Srobert
2154*12c85518Srobert Decl *NewReplaced = TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
2155*12c85518Srobert
2156e5dd7070Spatrick if (getSema().ArgumentPackSubstitutionIndex == -1) {
2157e5dd7070Spatrick // We aren't expanding the parameter pack, so just return ourselves.
2158*12c85518Srobert QualType Result = TL.getType();
2159*12c85518Srobert if (NewReplaced != T->getAssociatedDecl())
2160*12c85518Srobert Result = getSema().Context.getSubstTemplateTypeParmPackType(
2161*12c85518Srobert NewReplaced, T->getIndex(), T->getFinal(), T->getArgumentPack());
2162*12c85518Srobert SubstTemplateTypeParmPackTypeLoc NewTL =
2163*12c85518Srobert TLB.push<SubstTemplateTypeParmPackTypeLoc>(Result);
2164e5dd7070Spatrick NewTL.setNameLoc(TL.getNameLoc());
2165e5dd7070Spatrick return Result;
2166e5dd7070Spatrick }
2167e5dd7070Spatrick
2168*12c85518Srobert TemplateArgument Pack = T->getArgumentPack();
2169*12c85518Srobert TemplateArgument Arg = getPackSubstitutedTemplateArgument(getSema(), Pack);
2170*12c85518Srobert return BuildSubstTemplateTypeParmType(
2171*12c85518Srobert TLB, SuppressObjCLifetime, T->getFinal(), NewReplaced, T->getIndex(),
2172*12c85518Srobert getPackIndex(Pack), Arg, TL.getNameLoc());
2173*12c85518Srobert }
2174*12c85518Srobert
2175e5dd7070Spatrick template<typename EntityPrinter>
2176e5dd7070Spatrick static concepts::Requirement::SubstitutionDiagnostic *
createSubstDiag(Sema & S,TemplateDeductionInfo & Info,EntityPrinter Printer)2177e5dd7070Spatrick createSubstDiag(Sema &S, TemplateDeductionInfo &Info, EntityPrinter Printer) {
2178e5dd7070Spatrick SmallString<128> Message;
2179e5dd7070Spatrick SourceLocation ErrorLoc;
2180e5dd7070Spatrick if (Info.hasSFINAEDiagnostic()) {
2181e5dd7070Spatrick PartialDiagnosticAt PDA(SourceLocation(),
2182e5dd7070Spatrick PartialDiagnostic::NullDiagnostic{});
2183e5dd7070Spatrick Info.takeSFINAEDiagnostic(PDA);
2184e5dd7070Spatrick PDA.second.EmitToString(S.getDiagnostics(), Message);
2185e5dd7070Spatrick ErrorLoc = PDA.first;
2186e5dd7070Spatrick } else {
2187e5dd7070Spatrick ErrorLoc = Info.getLocation();
2188e5dd7070Spatrick }
2189e5dd7070Spatrick char *MessageBuf = new (S.Context) char[Message.size()];
2190e5dd7070Spatrick std::copy(Message.begin(), Message.end(), MessageBuf);
2191e5dd7070Spatrick SmallString<128> Entity;
2192e5dd7070Spatrick llvm::raw_svector_ostream OS(Entity);
2193e5dd7070Spatrick Printer(OS);
2194e5dd7070Spatrick char *EntityBuf = new (S.Context) char[Entity.size()];
2195e5dd7070Spatrick std::copy(Entity.begin(), Entity.end(), EntityBuf);
2196e5dd7070Spatrick return new (S.Context) concepts::Requirement::SubstitutionDiagnostic{
2197e5dd7070Spatrick StringRef(EntityBuf, Entity.size()), ErrorLoc,
2198e5dd7070Spatrick StringRef(MessageBuf, Message.size())};
2199e5dd7070Spatrick }
2200e5dd7070Spatrick
TransformRequiresTypeParams(SourceLocation KWLoc,SourceLocation RBraceLoc,const RequiresExpr * RE,RequiresExprBodyDecl * Body,ArrayRef<ParmVarDecl * > Params,SmallVectorImpl<QualType> & PTypes,SmallVectorImpl<ParmVarDecl * > & TransParams,Sema::ExtParameterInfoBuilder & PInfos)2201*12c85518Srobert ExprResult TemplateInstantiator::TransformRequiresTypeParams(
2202*12c85518Srobert SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
2203*12c85518Srobert RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,
2204*12c85518Srobert SmallVectorImpl<QualType> &PTypes,
2205*12c85518Srobert SmallVectorImpl<ParmVarDecl *> &TransParams,
2206*12c85518Srobert Sema::ExtParameterInfoBuilder &PInfos) {
2207*12c85518Srobert
2208*12c85518Srobert TemplateDeductionInfo Info(KWLoc);
2209*12c85518Srobert Sema::InstantiatingTemplate TypeInst(SemaRef, KWLoc,
2210*12c85518Srobert RE, Info,
2211*12c85518Srobert SourceRange{KWLoc, RBraceLoc});
2212*12c85518Srobert Sema::SFINAETrap Trap(SemaRef);
2213*12c85518Srobert
2214*12c85518Srobert unsigned ErrorIdx;
2215*12c85518Srobert if (getDerived().TransformFunctionTypeParams(
2216*12c85518Srobert KWLoc, Params, /*ParamTypes=*/nullptr, /*ParamInfos=*/nullptr, PTypes,
2217*12c85518Srobert &TransParams, PInfos, &ErrorIdx) ||
2218*12c85518Srobert Trap.hasErrorOccurred()) {
2219*12c85518Srobert SmallVector<concepts::Requirement *, 4> TransReqs;
2220*12c85518Srobert ParmVarDecl *FailedDecl = Params[ErrorIdx];
2221*12c85518Srobert // Add a 'failed' Requirement to contain the error that caused the failure
2222*12c85518Srobert // here.
2223*12c85518Srobert TransReqs.push_back(RebuildTypeRequirement(createSubstDiag(
2224*12c85518Srobert SemaRef, Info, [&](llvm::raw_ostream &OS) { OS << *FailedDecl; })));
2225*12c85518Srobert return getDerived().RebuildRequiresExpr(KWLoc, Body, TransParams, TransReqs,
2226*12c85518Srobert RBraceLoc);
2227*12c85518Srobert }
2228*12c85518Srobert
2229*12c85518Srobert return ExprResult{};
2230*12c85518Srobert }
2231*12c85518Srobert
2232e5dd7070Spatrick concepts::TypeRequirement *
TransformTypeRequirement(concepts::TypeRequirement * Req)2233e5dd7070Spatrick TemplateInstantiator::TransformTypeRequirement(concepts::TypeRequirement *Req) {
2234e5dd7070Spatrick if (!Req->isDependent() && !AlwaysRebuild())
2235e5dd7070Spatrick return Req;
2236e5dd7070Spatrick if (Req->isSubstitutionFailure()) {
2237e5dd7070Spatrick if (AlwaysRebuild())
2238e5dd7070Spatrick return RebuildTypeRequirement(
2239e5dd7070Spatrick Req->getSubstitutionDiagnostic());
2240e5dd7070Spatrick return Req;
2241e5dd7070Spatrick }
2242e5dd7070Spatrick
2243e5dd7070Spatrick Sema::SFINAETrap Trap(SemaRef);
2244e5dd7070Spatrick TemplateDeductionInfo Info(Req->getType()->getTypeLoc().getBeginLoc());
2245e5dd7070Spatrick Sema::InstantiatingTemplate TypeInst(SemaRef,
2246e5dd7070Spatrick Req->getType()->getTypeLoc().getBeginLoc(), Req, Info,
2247e5dd7070Spatrick Req->getType()->getTypeLoc().getSourceRange());
2248e5dd7070Spatrick if (TypeInst.isInvalid())
2249e5dd7070Spatrick return nullptr;
2250e5dd7070Spatrick TypeSourceInfo *TransType = TransformType(Req->getType());
2251e5dd7070Spatrick if (!TransType || Trap.hasErrorOccurred())
2252e5dd7070Spatrick return RebuildTypeRequirement(createSubstDiag(SemaRef, Info,
2253e5dd7070Spatrick [&] (llvm::raw_ostream& OS) {
2254e5dd7070Spatrick Req->getType()->getType().print(OS, SemaRef.getPrintingPolicy());
2255e5dd7070Spatrick }));
2256e5dd7070Spatrick return RebuildTypeRequirement(TransType);
2257e5dd7070Spatrick }
2258e5dd7070Spatrick
2259e5dd7070Spatrick concepts::ExprRequirement *
TransformExprRequirement(concepts::ExprRequirement * Req)2260e5dd7070Spatrick TemplateInstantiator::TransformExprRequirement(concepts::ExprRequirement *Req) {
2261e5dd7070Spatrick if (!Req->isDependent() && !AlwaysRebuild())
2262e5dd7070Spatrick return Req;
2263e5dd7070Spatrick
2264e5dd7070Spatrick Sema::SFINAETrap Trap(SemaRef);
2265e5dd7070Spatrick
2266e5dd7070Spatrick llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *>
2267e5dd7070Spatrick TransExpr;
2268e5dd7070Spatrick if (Req->isExprSubstitutionFailure())
2269e5dd7070Spatrick TransExpr = Req->getExprSubstitutionDiagnostic();
2270e5dd7070Spatrick else {
2271a9ac8606Spatrick Expr *E = Req->getExpr();
2272a9ac8606Spatrick TemplateDeductionInfo Info(E->getBeginLoc());
2273a9ac8606Spatrick Sema::InstantiatingTemplate ExprInst(SemaRef, E->getBeginLoc(), Req, Info,
2274a9ac8606Spatrick E->getSourceRange());
2275e5dd7070Spatrick if (ExprInst.isInvalid())
2276e5dd7070Spatrick return nullptr;
2277a9ac8606Spatrick ExprResult TransExprRes = TransformExpr(E);
2278*12c85518Srobert if (!TransExprRes.isInvalid() && !Trap.hasErrorOccurred() &&
2279*12c85518Srobert TransExprRes.get()->hasPlaceholderType())
2280*12c85518Srobert TransExprRes = SemaRef.CheckPlaceholderExpr(TransExprRes.get());
2281e5dd7070Spatrick if (TransExprRes.isInvalid() || Trap.hasErrorOccurred())
2282a9ac8606Spatrick TransExpr = createSubstDiag(SemaRef, Info, [&](llvm::raw_ostream &OS) {
2283a9ac8606Spatrick E->printPretty(OS, nullptr, SemaRef.getPrintingPolicy());
2284e5dd7070Spatrick });
2285e5dd7070Spatrick else
2286e5dd7070Spatrick TransExpr = TransExprRes.get();
2287e5dd7070Spatrick }
2288e5dd7070Spatrick
2289*12c85518Srobert std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
2290e5dd7070Spatrick const auto &RetReq = Req->getReturnTypeRequirement();
2291e5dd7070Spatrick if (RetReq.isEmpty())
2292e5dd7070Spatrick TransRetReq.emplace();
2293e5dd7070Spatrick else if (RetReq.isSubstitutionFailure())
2294e5dd7070Spatrick TransRetReq.emplace(RetReq.getSubstitutionDiagnostic());
2295e5dd7070Spatrick else if (RetReq.isTypeConstraint()) {
2296e5dd7070Spatrick TemplateParameterList *OrigTPL =
2297e5dd7070Spatrick RetReq.getTypeConstraintTemplateParameterList();
2298a9ac8606Spatrick TemplateDeductionInfo Info(OrigTPL->getTemplateLoc());
2299e5dd7070Spatrick Sema::InstantiatingTemplate TPLInst(SemaRef, OrigTPL->getTemplateLoc(),
2300e5dd7070Spatrick Req, Info, OrigTPL->getSourceRange());
2301e5dd7070Spatrick if (TPLInst.isInvalid())
2302e5dd7070Spatrick return nullptr;
2303*12c85518Srobert TemplateParameterList *TPL = TransformTemplateParameterList(OrigTPL);
2304e5dd7070Spatrick if (!TPL)
2305e5dd7070Spatrick TransRetReq.emplace(createSubstDiag(SemaRef, Info,
2306e5dd7070Spatrick [&] (llvm::raw_ostream& OS) {
2307e5dd7070Spatrick RetReq.getTypeConstraint()->getImmediatelyDeclaredConstraint()
2308e5dd7070Spatrick ->printPretty(OS, nullptr, SemaRef.getPrintingPolicy());
2309e5dd7070Spatrick }));
2310e5dd7070Spatrick else {
2311e5dd7070Spatrick TPLInst.Clear();
2312e5dd7070Spatrick TransRetReq.emplace(TPL);
2313e5dd7070Spatrick }
2314e5dd7070Spatrick }
2315*12c85518Srobert assert(TransRetReq && "All code paths leading here must set TransRetReq");
2316e5dd7070Spatrick if (Expr *E = TransExpr.dyn_cast<Expr *>())
2317e5dd7070Spatrick return RebuildExprRequirement(E, Req->isSimple(), Req->getNoexceptLoc(),
2318e5dd7070Spatrick std::move(*TransRetReq));
2319e5dd7070Spatrick return RebuildExprRequirement(
2320e5dd7070Spatrick TransExpr.get<concepts::Requirement::SubstitutionDiagnostic *>(),
2321e5dd7070Spatrick Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
2322e5dd7070Spatrick }
2323e5dd7070Spatrick
2324e5dd7070Spatrick concepts::NestedRequirement *
TransformNestedRequirement(concepts::NestedRequirement * Req)2325e5dd7070Spatrick TemplateInstantiator::TransformNestedRequirement(
2326e5dd7070Spatrick concepts::NestedRequirement *Req) {
2327e5dd7070Spatrick if (!Req->isDependent() && !AlwaysRebuild())
2328e5dd7070Spatrick return Req;
2329*12c85518Srobert if (Req->hasInvalidConstraint()) {
2330e5dd7070Spatrick if (AlwaysRebuild())
2331*12c85518Srobert return RebuildNestedRequirement(Req->getInvalidConstraintEntity(),
2332*12c85518Srobert Req->getConstraintSatisfaction());
2333e5dd7070Spatrick return Req;
2334e5dd7070Spatrick }
2335e5dd7070Spatrick Sema::InstantiatingTemplate ReqInst(SemaRef,
2336e5dd7070Spatrick Req->getConstraintExpr()->getBeginLoc(), Req,
2337e5dd7070Spatrick Sema::InstantiatingTemplate::ConstraintsCheck{},
2338e5dd7070Spatrick Req->getConstraintExpr()->getSourceRange());
2339e5dd7070Spatrick
2340e5dd7070Spatrick ExprResult TransConstraint;
2341*12c85518Srobert ConstraintSatisfaction Satisfaction;
2342e5dd7070Spatrick TemplateDeductionInfo Info(Req->getConstraintExpr()->getBeginLoc());
2343e5dd7070Spatrick {
2344e5dd7070Spatrick EnterExpressionEvaluationContext ContextRAII(
2345e5dd7070Spatrick SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
2346e5dd7070Spatrick Sema::SFINAETrap Trap(SemaRef);
2347e5dd7070Spatrick Sema::InstantiatingTemplate ConstrInst(SemaRef,
2348e5dd7070Spatrick Req->getConstraintExpr()->getBeginLoc(), Req, Info,
2349e5dd7070Spatrick Req->getConstraintExpr()->getSourceRange());
2350e5dd7070Spatrick if (ConstrInst.isInvalid())
2351e5dd7070Spatrick return nullptr;
2352*12c85518Srobert llvm::SmallVector<Expr *> Result;
2353*12c85518Srobert if (!SemaRef.CheckConstraintSatisfaction(
2354*12c85518Srobert nullptr, {Req->getConstraintExpr()}, Result, TemplateArgs,
2355*12c85518Srobert Req->getConstraintExpr()->getSourceRange(), Satisfaction) &&
2356*12c85518Srobert !Result.empty())
2357*12c85518Srobert TransConstraint = Result[0];
2358*12c85518Srobert assert(!Trap.hasErrorOccurred() && "Substitution failures must be handled "
2359*12c85518Srobert "by CheckConstraintSatisfaction.");
2360*12c85518Srobert }
2361*12c85518Srobert if (TransConstraint.isUsable() &&
2362*12c85518Srobert TransConstraint.get()->isInstantiationDependent())
2363*12c85518Srobert return new (SemaRef.Context)
2364*12c85518Srobert concepts::NestedRequirement(TransConstraint.get());
2365*12c85518Srobert if (TransConstraint.isInvalid() || !TransConstraint.get() ||
2366*12c85518Srobert Satisfaction.HasSubstitutionFailure()) {
2367*12c85518Srobert SmallString<128> Entity;
2368*12c85518Srobert llvm::raw_svector_ostream OS(Entity);
2369e5dd7070Spatrick Req->getConstraintExpr()->printPretty(OS, nullptr,
2370e5dd7070Spatrick SemaRef.getPrintingPolicy());
2371*12c85518Srobert char *EntityBuf = new (SemaRef.Context) char[Entity.size()];
2372*12c85518Srobert std::copy(Entity.begin(), Entity.end(), EntityBuf);
2373*12c85518Srobert return new (SemaRef.Context) concepts::NestedRequirement(
2374*12c85518Srobert SemaRef.Context, StringRef(EntityBuf, Entity.size()), Satisfaction);
2375e5dd7070Spatrick }
2376*12c85518Srobert return new (SemaRef.Context) concepts::NestedRequirement(
2377*12c85518Srobert SemaRef.Context, TransConstraint.get(), Satisfaction);
2378e5dd7070Spatrick }
2379e5dd7070Spatrick
2380e5dd7070Spatrick
2381e5dd7070Spatrick /// Perform substitution on the type T with a given set of template
2382e5dd7070Spatrick /// arguments.
2383e5dd7070Spatrick ///
2384e5dd7070Spatrick /// This routine substitutes the given template arguments into the
2385e5dd7070Spatrick /// type T and produces the instantiated type.
2386e5dd7070Spatrick ///
2387e5dd7070Spatrick /// \param T the type into which the template arguments will be
2388e5dd7070Spatrick /// substituted. If this type is not dependent, it will be returned
2389e5dd7070Spatrick /// immediately.
2390e5dd7070Spatrick ///
2391e5dd7070Spatrick /// \param Args the template arguments that will be
2392e5dd7070Spatrick /// substituted for the top-level template parameters within T.
2393e5dd7070Spatrick ///
2394e5dd7070Spatrick /// \param Loc the location in the source code where this substitution
2395e5dd7070Spatrick /// is being performed. It will typically be the location of the
2396e5dd7070Spatrick /// declarator (if we're instantiating the type of some declaration)
2397e5dd7070Spatrick /// or the location of the type in the source code (if, e.g., we're
2398e5dd7070Spatrick /// instantiating the type of a cast expression).
2399e5dd7070Spatrick ///
2400e5dd7070Spatrick /// \param Entity the name of the entity associated with a declaration
2401e5dd7070Spatrick /// being instantiated (if any). May be empty to indicate that there
2402e5dd7070Spatrick /// is no such entity (if, e.g., this is a type that occurs as part of
2403e5dd7070Spatrick /// a cast expression) or that the entity has no name (e.g., an
2404e5dd7070Spatrick /// unnamed function parameter).
2405e5dd7070Spatrick ///
2406e5dd7070Spatrick /// \param AllowDeducedTST Whether a DeducedTemplateSpecializationType is
2407e5dd7070Spatrick /// acceptable as the top level type of the result.
2408e5dd7070Spatrick ///
2409e5dd7070Spatrick /// \returns If the instantiation succeeds, the instantiated
2410e5dd7070Spatrick /// type. Otherwise, produces diagnostics and returns a NULL type.
SubstType(TypeSourceInfo * T,const MultiLevelTemplateArgumentList & Args,SourceLocation Loc,DeclarationName Entity,bool AllowDeducedTST)2411e5dd7070Spatrick TypeSourceInfo *Sema::SubstType(TypeSourceInfo *T,
2412e5dd7070Spatrick const MultiLevelTemplateArgumentList &Args,
2413e5dd7070Spatrick SourceLocation Loc,
2414e5dd7070Spatrick DeclarationName Entity,
2415e5dd7070Spatrick bool AllowDeducedTST) {
2416e5dd7070Spatrick assert(!CodeSynthesisContexts.empty() &&
2417e5dd7070Spatrick "Cannot perform an instantiation without some context on the "
2418e5dd7070Spatrick "instantiation stack");
2419e5dd7070Spatrick
2420e5dd7070Spatrick if (!T->getType()->isInstantiationDependentType() &&
2421e5dd7070Spatrick !T->getType()->isVariablyModifiedType())
2422e5dd7070Spatrick return T;
2423e5dd7070Spatrick
2424e5dd7070Spatrick TemplateInstantiator Instantiator(*this, Args, Loc, Entity);
2425e5dd7070Spatrick return AllowDeducedTST ? Instantiator.TransformTypeWithDeducedTST(T)
2426e5dd7070Spatrick : Instantiator.TransformType(T);
2427e5dd7070Spatrick }
2428e5dd7070Spatrick
SubstType(TypeLoc TL,const MultiLevelTemplateArgumentList & Args,SourceLocation Loc,DeclarationName Entity)2429e5dd7070Spatrick TypeSourceInfo *Sema::SubstType(TypeLoc TL,
2430e5dd7070Spatrick const MultiLevelTemplateArgumentList &Args,
2431e5dd7070Spatrick SourceLocation Loc,
2432e5dd7070Spatrick DeclarationName Entity) {
2433e5dd7070Spatrick assert(!CodeSynthesisContexts.empty() &&
2434e5dd7070Spatrick "Cannot perform an instantiation without some context on the "
2435e5dd7070Spatrick "instantiation stack");
2436e5dd7070Spatrick
2437e5dd7070Spatrick if (TL.getType().isNull())
2438e5dd7070Spatrick return nullptr;
2439e5dd7070Spatrick
2440e5dd7070Spatrick if (!TL.getType()->isInstantiationDependentType() &&
2441e5dd7070Spatrick !TL.getType()->isVariablyModifiedType()) {
2442e5dd7070Spatrick // FIXME: Make a copy of the TypeLoc data here, so that we can
2443e5dd7070Spatrick // return a new TypeSourceInfo. Inefficient!
2444e5dd7070Spatrick TypeLocBuilder TLB;
2445e5dd7070Spatrick TLB.pushFullCopy(TL);
2446e5dd7070Spatrick return TLB.getTypeSourceInfo(Context, TL.getType());
2447e5dd7070Spatrick }
2448e5dd7070Spatrick
2449e5dd7070Spatrick TemplateInstantiator Instantiator(*this, Args, Loc, Entity);
2450e5dd7070Spatrick TypeLocBuilder TLB;
2451e5dd7070Spatrick TLB.reserve(TL.getFullDataSize());
2452e5dd7070Spatrick QualType Result = Instantiator.TransformType(TLB, TL);
2453e5dd7070Spatrick if (Result.isNull())
2454e5dd7070Spatrick return nullptr;
2455e5dd7070Spatrick
2456e5dd7070Spatrick return TLB.getTypeSourceInfo(Context, Result);
2457e5dd7070Spatrick }
2458e5dd7070Spatrick
2459e5dd7070Spatrick /// Deprecated form of the above.
SubstType(QualType T,const MultiLevelTemplateArgumentList & TemplateArgs,SourceLocation Loc,DeclarationName Entity)2460e5dd7070Spatrick QualType Sema::SubstType(QualType T,
2461e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs,
2462e5dd7070Spatrick SourceLocation Loc, DeclarationName Entity) {
2463e5dd7070Spatrick assert(!CodeSynthesisContexts.empty() &&
2464e5dd7070Spatrick "Cannot perform an instantiation without some context on the "
2465e5dd7070Spatrick "instantiation stack");
2466e5dd7070Spatrick
2467e5dd7070Spatrick // If T is not a dependent type or a variably-modified type, there
2468e5dd7070Spatrick // is nothing to do.
2469e5dd7070Spatrick if (!T->isInstantiationDependentType() && !T->isVariablyModifiedType())
2470e5dd7070Spatrick return T;
2471e5dd7070Spatrick
2472e5dd7070Spatrick TemplateInstantiator Instantiator(*this, TemplateArgs, Loc, Entity);
2473e5dd7070Spatrick return Instantiator.TransformType(T);
2474e5dd7070Spatrick }
2475e5dd7070Spatrick
NeedsInstantiationAsFunctionType(TypeSourceInfo * T)2476e5dd7070Spatrick static bool NeedsInstantiationAsFunctionType(TypeSourceInfo *T) {
2477e5dd7070Spatrick if (T->getType()->isInstantiationDependentType() ||
2478e5dd7070Spatrick T->getType()->isVariablyModifiedType())
2479e5dd7070Spatrick return true;
2480e5dd7070Spatrick
2481e5dd7070Spatrick TypeLoc TL = T->getTypeLoc().IgnoreParens();
2482e5dd7070Spatrick if (!TL.getAs<FunctionProtoTypeLoc>())
2483e5dd7070Spatrick return false;
2484e5dd7070Spatrick
2485e5dd7070Spatrick FunctionProtoTypeLoc FP = TL.castAs<FunctionProtoTypeLoc>();
2486e5dd7070Spatrick for (ParmVarDecl *P : FP.getParams()) {
2487e5dd7070Spatrick // This must be synthesized from a typedef.
2488e5dd7070Spatrick if (!P) continue;
2489e5dd7070Spatrick
2490e5dd7070Spatrick // If there are any parameters, a new TypeSourceInfo that refers to the
2491e5dd7070Spatrick // instantiated parameters must be built.
2492e5dd7070Spatrick return true;
2493e5dd7070Spatrick }
2494e5dd7070Spatrick
2495e5dd7070Spatrick return false;
2496e5dd7070Spatrick }
2497e5dd7070Spatrick
2498e5dd7070Spatrick /// A form of SubstType intended specifically for instantiating the
2499e5dd7070Spatrick /// type of a FunctionDecl. Its purpose is solely to force the
2500e5dd7070Spatrick /// instantiation of default-argument expressions and to avoid
2501e5dd7070Spatrick /// instantiating an exception-specification.
SubstFunctionDeclType(TypeSourceInfo * T,const MultiLevelTemplateArgumentList & Args,SourceLocation Loc,DeclarationName Entity,CXXRecordDecl * ThisContext,Qualifiers ThisTypeQuals,bool EvaluateConstraints)2502e5dd7070Spatrick TypeSourceInfo *Sema::SubstFunctionDeclType(TypeSourceInfo *T,
2503e5dd7070Spatrick const MultiLevelTemplateArgumentList &Args,
2504e5dd7070Spatrick SourceLocation Loc,
2505e5dd7070Spatrick DeclarationName Entity,
2506e5dd7070Spatrick CXXRecordDecl *ThisContext,
2507*12c85518Srobert Qualifiers ThisTypeQuals,
2508*12c85518Srobert bool EvaluateConstraints) {
2509e5dd7070Spatrick assert(!CodeSynthesisContexts.empty() &&
2510e5dd7070Spatrick "Cannot perform an instantiation without some context on the "
2511e5dd7070Spatrick "instantiation stack");
2512e5dd7070Spatrick
2513e5dd7070Spatrick if (!NeedsInstantiationAsFunctionType(T))
2514e5dd7070Spatrick return T;
2515e5dd7070Spatrick
2516e5dd7070Spatrick TemplateInstantiator Instantiator(*this, Args, Loc, Entity);
2517*12c85518Srobert Instantiator.setEvaluateConstraints(EvaluateConstraints);
2518e5dd7070Spatrick
2519e5dd7070Spatrick TypeLocBuilder TLB;
2520e5dd7070Spatrick
2521e5dd7070Spatrick TypeLoc TL = T->getTypeLoc();
2522e5dd7070Spatrick TLB.reserve(TL.getFullDataSize());
2523e5dd7070Spatrick
2524e5dd7070Spatrick QualType Result;
2525e5dd7070Spatrick
2526e5dd7070Spatrick if (FunctionProtoTypeLoc Proto =
2527e5dd7070Spatrick TL.IgnoreParens().getAs<FunctionProtoTypeLoc>()) {
2528e5dd7070Spatrick // Instantiate the type, other than its exception specification. The
2529e5dd7070Spatrick // exception specification is instantiated in InitFunctionInstantiation
2530e5dd7070Spatrick // once we've built the FunctionDecl.
2531e5dd7070Spatrick // FIXME: Set the exception specification to EST_Uninstantiated here,
2532e5dd7070Spatrick // instead of rebuilding the function type again later.
2533e5dd7070Spatrick Result = Instantiator.TransformFunctionProtoType(
2534e5dd7070Spatrick TLB, Proto, ThisContext, ThisTypeQuals,
2535e5dd7070Spatrick [](FunctionProtoType::ExceptionSpecInfo &ESI,
2536e5dd7070Spatrick bool &Changed) { return false; });
2537e5dd7070Spatrick } else {
2538e5dd7070Spatrick Result = Instantiator.TransformType(TLB, TL);
2539e5dd7070Spatrick }
2540e5dd7070Spatrick if (Result.isNull())
2541e5dd7070Spatrick return nullptr;
2542e5dd7070Spatrick
2543e5dd7070Spatrick return TLB.getTypeSourceInfo(Context, Result);
2544e5dd7070Spatrick }
2545e5dd7070Spatrick
SubstExceptionSpec(SourceLocation Loc,FunctionProtoType::ExceptionSpecInfo & ESI,SmallVectorImpl<QualType> & ExceptionStorage,const MultiLevelTemplateArgumentList & Args)2546e5dd7070Spatrick bool Sema::SubstExceptionSpec(SourceLocation Loc,
2547e5dd7070Spatrick FunctionProtoType::ExceptionSpecInfo &ESI,
2548e5dd7070Spatrick SmallVectorImpl<QualType> &ExceptionStorage,
2549e5dd7070Spatrick const MultiLevelTemplateArgumentList &Args) {
2550e5dd7070Spatrick assert(ESI.Type != EST_Uninstantiated);
2551e5dd7070Spatrick
2552e5dd7070Spatrick bool Changed = false;
2553e5dd7070Spatrick TemplateInstantiator Instantiator(*this, Args, Loc, DeclarationName());
2554e5dd7070Spatrick return Instantiator.TransformExceptionSpec(Loc, ESI, ExceptionStorage,
2555e5dd7070Spatrick Changed);
2556e5dd7070Spatrick }
2557e5dd7070Spatrick
SubstExceptionSpec(FunctionDecl * New,const FunctionProtoType * Proto,const MultiLevelTemplateArgumentList & Args)2558e5dd7070Spatrick void Sema::SubstExceptionSpec(FunctionDecl *New, const FunctionProtoType *Proto,
2559e5dd7070Spatrick const MultiLevelTemplateArgumentList &Args) {
2560e5dd7070Spatrick FunctionProtoType::ExceptionSpecInfo ESI =
2561e5dd7070Spatrick Proto->getExtProtoInfo().ExceptionSpec;
2562e5dd7070Spatrick
2563e5dd7070Spatrick SmallVector<QualType, 4> ExceptionStorage;
2564e5dd7070Spatrick if (SubstExceptionSpec(New->getTypeSourceInfo()->getTypeLoc().getEndLoc(),
2565e5dd7070Spatrick ESI, ExceptionStorage, Args))
2566e5dd7070Spatrick // On error, recover by dropping the exception specification.
2567e5dd7070Spatrick ESI.Type = EST_None;
2568e5dd7070Spatrick
2569e5dd7070Spatrick UpdateExceptionSpec(New, ESI);
2570e5dd7070Spatrick }
2571e5dd7070Spatrick
2572e5dd7070Spatrick namespace {
2573e5dd7070Spatrick
2574e5dd7070Spatrick struct GetContainedInventedTypeParmVisitor :
2575e5dd7070Spatrick public TypeVisitor<GetContainedInventedTypeParmVisitor,
2576e5dd7070Spatrick TemplateTypeParmDecl *> {
2577e5dd7070Spatrick using TypeVisitor<GetContainedInventedTypeParmVisitor,
2578e5dd7070Spatrick TemplateTypeParmDecl *>::Visit;
2579e5dd7070Spatrick
Visit__anon63295b2c0911::GetContainedInventedTypeParmVisitor2580e5dd7070Spatrick TemplateTypeParmDecl *Visit(QualType T) {
2581e5dd7070Spatrick if (T.isNull())
2582e5dd7070Spatrick return nullptr;
2583e5dd7070Spatrick return Visit(T.getTypePtr());
2584e5dd7070Spatrick }
2585e5dd7070Spatrick // The deduced type itself.
VisitTemplateTypeParmType__anon63295b2c0911::GetContainedInventedTypeParmVisitor2586e5dd7070Spatrick TemplateTypeParmDecl *VisitTemplateTypeParmType(
2587e5dd7070Spatrick const TemplateTypeParmType *T) {
2588e5dd7070Spatrick if (!T->getDecl() || !T->getDecl()->isImplicit())
2589e5dd7070Spatrick return nullptr;
2590e5dd7070Spatrick return T->getDecl();
2591e5dd7070Spatrick }
2592e5dd7070Spatrick
2593e5dd7070Spatrick // Only these types can contain 'auto' types, and subsequently be replaced
2594e5dd7070Spatrick // by references to invented parameters.
2595e5dd7070Spatrick
VisitElaboratedType__anon63295b2c0911::GetContainedInventedTypeParmVisitor2596e5dd7070Spatrick TemplateTypeParmDecl *VisitElaboratedType(const ElaboratedType *T) {
2597e5dd7070Spatrick return Visit(T->getNamedType());
2598e5dd7070Spatrick }
2599e5dd7070Spatrick
VisitPointerType__anon63295b2c0911::GetContainedInventedTypeParmVisitor2600e5dd7070Spatrick TemplateTypeParmDecl *VisitPointerType(const PointerType *T) {
2601e5dd7070Spatrick return Visit(T->getPointeeType());
2602e5dd7070Spatrick }
2603e5dd7070Spatrick
VisitBlockPointerType__anon63295b2c0911::GetContainedInventedTypeParmVisitor2604e5dd7070Spatrick TemplateTypeParmDecl *VisitBlockPointerType(const BlockPointerType *T) {
2605e5dd7070Spatrick return Visit(T->getPointeeType());
2606e5dd7070Spatrick }
2607e5dd7070Spatrick
VisitReferenceType__anon63295b2c0911::GetContainedInventedTypeParmVisitor2608e5dd7070Spatrick TemplateTypeParmDecl *VisitReferenceType(const ReferenceType *T) {
2609e5dd7070Spatrick return Visit(T->getPointeeTypeAsWritten());
2610e5dd7070Spatrick }
2611e5dd7070Spatrick
VisitMemberPointerType__anon63295b2c0911::GetContainedInventedTypeParmVisitor2612e5dd7070Spatrick TemplateTypeParmDecl *VisitMemberPointerType(const MemberPointerType *T) {
2613e5dd7070Spatrick return Visit(T->getPointeeType());
2614e5dd7070Spatrick }
2615e5dd7070Spatrick
VisitArrayType__anon63295b2c0911::GetContainedInventedTypeParmVisitor2616e5dd7070Spatrick TemplateTypeParmDecl *VisitArrayType(const ArrayType *T) {
2617e5dd7070Spatrick return Visit(T->getElementType());
2618e5dd7070Spatrick }
2619e5dd7070Spatrick
VisitDependentSizedExtVectorType__anon63295b2c0911::GetContainedInventedTypeParmVisitor2620e5dd7070Spatrick TemplateTypeParmDecl *VisitDependentSizedExtVectorType(
2621e5dd7070Spatrick const DependentSizedExtVectorType *T) {
2622e5dd7070Spatrick return Visit(T->getElementType());
2623e5dd7070Spatrick }
2624e5dd7070Spatrick
VisitVectorType__anon63295b2c0911::GetContainedInventedTypeParmVisitor2625e5dd7070Spatrick TemplateTypeParmDecl *VisitVectorType(const VectorType *T) {
2626e5dd7070Spatrick return Visit(T->getElementType());
2627e5dd7070Spatrick }
2628e5dd7070Spatrick
VisitFunctionProtoType__anon63295b2c0911::GetContainedInventedTypeParmVisitor2629e5dd7070Spatrick TemplateTypeParmDecl *VisitFunctionProtoType(const FunctionProtoType *T) {
2630e5dd7070Spatrick return VisitFunctionType(T);
2631e5dd7070Spatrick }
2632e5dd7070Spatrick
VisitFunctionType__anon63295b2c0911::GetContainedInventedTypeParmVisitor2633e5dd7070Spatrick TemplateTypeParmDecl *VisitFunctionType(const FunctionType *T) {
2634e5dd7070Spatrick return Visit(T->getReturnType());
2635e5dd7070Spatrick }
2636e5dd7070Spatrick
VisitParenType__anon63295b2c0911::GetContainedInventedTypeParmVisitor2637e5dd7070Spatrick TemplateTypeParmDecl *VisitParenType(const ParenType *T) {
2638e5dd7070Spatrick return Visit(T->getInnerType());
2639e5dd7070Spatrick }
2640e5dd7070Spatrick
VisitAttributedType__anon63295b2c0911::GetContainedInventedTypeParmVisitor2641e5dd7070Spatrick TemplateTypeParmDecl *VisitAttributedType(const AttributedType *T) {
2642e5dd7070Spatrick return Visit(T->getModifiedType());
2643e5dd7070Spatrick }
2644e5dd7070Spatrick
VisitMacroQualifiedType__anon63295b2c0911::GetContainedInventedTypeParmVisitor2645e5dd7070Spatrick TemplateTypeParmDecl *VisitMacroQualifiedType(const MacroQualifiedType *T) {
2646e5dd7070Spatrick return Visit(T->getUnderlyingType());
2647e5dd7070Spatrick }
2648e5dd7070Spatrick
VisitAdjustedType__anon63295b2c0911::GetContainedInventedTypeParmVisitor2649e5dd7070Spatrick TemplateTypeParmDecl *VisitAdjustedType(const AdjustedType *T) {
2650e5dd7070Spatrick return Visit(T->getOriginalType());
2651e5dd7070Spatrick }
2652e5dd7070Spatrick
VisitPackExpansionType__anon63295b2c0911::GetContainedInventedTypeParmVisitor2653e5dd7070Spatrick TemplateTypeParmDecl *VisitPackExpansionType(const PackExpansionType *T) {
2654e5dd7070Spatrick return Visit(T->getPattern());
2655e5dd7070Spatrick }
2656e5dd7070Spatrick };
2657e5dd7070Spatrick
2658e5dd7070Spatrick } // namespace
2659e5dd7070Spatrick
SubstTypeConstraint(TemplateTypeParmDecl * Inst,const TypeConstraint * TC,const MultiLevelTemplateArgumentList & TemplateArgs,bool EvaluateConstraints)2660*12c85518Srobert bool Sema::SubstTypeConstraint(
2661*12c85518Srobert TemplateTypeParmDecl *Inst, const TypeConstraint *TC,
2662e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs,
2663*12c85518Srobert bool EvaluateConstraints) {
2664*12c85518Srobert const ASTTemplateArgumentListInfo *TemplArgInfo =
2665*12c85518Srobert TC->getTemplateArgsAsWritten();
2666*12c85518Srobert
2667*12c85518Srobert if (!EvaluateConstraints) {
2668*12c85518Srobert Inst->setTypeConstraint(TC->getNestedNameSpecifierLoc(),
2669*12c85518Srobert TC->getConceptNameInfo(), TC->getNamedConcept(),
2670*12c85518Srobert TC->getNamedConcept(), TemplArgInfo,
2671*12c85518Srobert TC->getImmediatelyDeclaredConstraint());
2672*12c85518Srobert return false;
2673*12c85518Srobert }
2674*12c85518Srobert
2675*12c85518Srobert TemplateArgumentListInfo InstArgs;
2676*12c85518Srobert
2677*12c85518Srobert if (TemplArgInfo) {
2678*12c85518Srobert InstArgs.setLAngleLoc(TemplArgInfo->LAngleLoc);
2679*12c85518Srobert InstArgs.setRAngleLoc(TemplArgInfo->RAngleLoc);
2680*12c85518Srobert if (SubstTemplateArguments(TemplArgInfo->arguments(), TemplateArgs,
2681*12c85518Srobert InstArgs))
2682*12c85518Srobert return true;
2683*12c85518Srobert }
2684*12c85518Srobert return AttachTypeConstraint(
2685*12c85518Srobert TC->getNestedNameSpecifierLoc(), TC->getConceptNameInfo(),
2686*12c85518Srobert TC->getNamedConcept(), &InstArgs, Inst,
2687*12c85518Srobert Inst->isParameterPack()
2688*12c85518Srobert ? cast<CXXFoldExpr>(TC->getImmediatelyDeclaredConstraint())
2689*12c85518Srobert ->getEllipsisLoc()
2690*12c85518Srobert : SourceLocation());
2691*12c85518Srobert }
2692*12c85518Srobert
SubstParmVarDecl(ParmVarDecl * OldParm,const MultiLevelTemplateArgumentList & TemplateArgs,int indexAdjustment,std::optional<unsigned> NumExpansions,bool ExpectParameterPack,bool EvaluateConstraint)2693*12c85518Srobert ParmVarDecl *Sema::SubstParmVarDecl(
2694*12c85518Srobert ParmVarDecl *OldParm, const MultiLevelTemplateArgumentList &TemplateArgs,
2695*12c85518Srobert int indexAdjustment, std::optional<unsigned> NumExpansions,
2696*12c85518Srobert bool ExpectParameterPack, bool EvaluateConstraint) {
2697e5dd7070Spatrick TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
2698e5dd7070Spatrick TypeSourceInfo *NewDI = nullptr;
2699e5dd7070Spatrick
2700e5dd7070Spatrick TypeLoc OldTL = OldDI->getTypeLoc();
2701e5dd7070Spatrick if (PackExpansionTypeLoc ExpansionTL = OldTL.getAs<PackExpansionTypeLoc>()) {
2702e5dd7070Spatrick
2703e5dd7070Spatrick // We have a function parameter pack. Substitute into the pattern of the
2704e5dd7070Spatrick // expansion.
2705e5dd7070Spatrick NewDI = SubstType(ExpansionTL.getPatternLoc(), TemplateArgs,
2706e5dd7070Spatrick OldParm->getLocation(), OldParm->getDeclName());
2707e5dd7070Spatrick if (!NewDI)
2708e5dd7070Spatrick return nullptr;
2709e5dd7070Spatrick
2710e5dd7070Spatrick if (NewDI->getType()->containsUnexpandedParameterPack()) {
2711e5dd7070Spatrick // We still have unexpanded parameter packs, which means that
2712e5dd7070Spatrick // our function parameter is still a function parameter pack.
2713e5dd7070Spatrick // Therefore, make its type a pack expansion type.
2714e5dd7070Spatrick NewDI = CheckPackExpansion(NewDI, ExpansionTL.getEllipsisLoc(),
2715e5dd7070Spatrick NumExpansions);
2716e5dd7070Spatrick } else if (ExpectParameterPack) {
2717e5dd7070Spatrick // We expected to get a parameter pack but didn't (because the type
2718e5dd7070Spatrick // itself is not a pack expansion type), so complain. This can occur when
2719e5dd7070Spatrick // the substitution goes through an alias template that "loses" the
2720e5dd7070Spatrick // pack expansion.
2721e5dd7070Spatrick Diag(OldParm->getLocation(),
2722e5dd7070Spatrick diag::err_function_parameter_pack_without_parameter_packs)
2723e5dd7070Spatrick << NewDI->getType();
2724e5dd7070Spatrick return nullptr;
2725e5dd7070Spatrick }
2726e5dd7070Spatrick } else {
2727e5dd7070Spatrick NewDI = SubstType(OldDI, TemplateArgs, OldParm->getLocation(),
2728e5dd7070Spatrick OldParm->getDeclName());
2729e5dd7070Spatrick }
2730e5dd7070Spatrick
2731e5dd7070Spatrick if (!NewDI)
2732e5dd7070Spatrick return nullptr;
2733e5dd7070Spatrick
2734e5dd7070Spatrick if (NewDI->getType()->isVoidType()) {
2735e5dd7070Spatrick Diag(OldParm->getLocation(), diag::err_param_with_void_type);
2736e5dd7070Spatrick return nullptr;
2737e5dd7070Spatrick }
2738e5dd7070Spatrick
2739e5dd7070Spatrick // In abbreviated templates, TemplateTypeParmDecls with possible
2740e5dd7070Spatrick // TypeConstraints are created when the parameter list is originally parsed.
2741e5dd7070Spatrick // The TypeConstraints can therefore reference other functions parameters in
2742e5dd7070Spatrick // the abbreviated function template, which is why we must instantiate them
2743e5dd7070Spatrick // here, when the instantiated versions of those referenced parameters are in
2744e5dd7070Spatrick // scope.
2745e5dd7070Spatrick if (TemplateTypeParmDecl *TTP =
2746e5dd7070Spatrick GetContainedInventedTypeParmVisitor().Visit(OldDI->getType())) {
2747e5dd7070Spatrick if (const TypeConstraint *TC = TTP->getTypeConstraint()) {
2748e5dd7070Spatrick auto *Inst = cast_or_null<TemplateTypeParmDecl>(
2749e5dd7070Spatrick FindInstantiatedDecl(TTP->getLocation(), TTP, TemplateArgs));
2750e5dd7070Spatrick // We will first get here when instantiating the abbreviated function
2751e5dd7070Spatrick // template's described function, but we might also get here later.
2752e5dd7070Spatrick // Make sure we do not instantiate the TypeConstraint more than once.
2753e5dd7070Spatrick if (Inst && !Inst->getTypeConstraint()) {
2754*12c85518Srobert if (SubstTypeConstraint(Inst, TC, TemplateArgs, EvaluateConstraint))
2755e5dd7070Spatrick return nullptr;
2756e5dd7070Spatrick }
2757e5dd7070Spatrick }
2758e5dd7070Spatrick }
2759e5dd7070Spatrick
2760e5dd7070Spatrick ParmVarDecl *NewParm = CheckParameter(Context.getTranslationUnitDecl(),
2761e5dd7070Spatrick OldParm->getInnerLocStart(),
2762e5dd7070Spatrick OldParm->getLocation(),
2763e5dd7070Spatrick OldParm->getIdentifier(),
2764e5dd7070Spatrick NewDI->getType(), NewDI,
2765e5dd7070Spatrick OldParm->getStorageClass());
2766e5dd7070Spatrick if (!NewParm)
2767e5dd7070Spatrick return nullptr;
2768e5dd7070Spatrick
2769e5dd7070Spatrick // Mark the (new) default argument as uninstantiated (if any).
2770e5dd7070Spatrick if (OldParm->hasUninstantiatedDefaultArg()) {
2771e5dd7070Spatrick Expr *Arg = OldParm->getUninstantiatedDefaultArg();
2772e5dd7070Spatrick NewParm->setUninstantiatedDefaultArg(Arg);
2773e5dd7070Spatrick } else if (OldParm->hasUnparsedDefaultArg()) {
2774e5dd7070Spatrick NewParm->setUnparsedDefaultArg();
2775e5dd7070Spatrick UnparsedDefaultArgInstantiations[OldParm].push_back(NewParm);
2776e5dd7070Spatrick } else if (Expr *Arg = OldParm->getDefaultArg()) {
2777*12c85518Srobert // Default arguments cannot be substituted until the declaration context
2778*12c85518Srobert // for the associated function or lambda capture class is available.
2779*12c85518Srobert // This is necessary for cases like the following where construction of
2780*12c85518Srobert // the lambda capture class for the outer lambda is dependent on the
2781*12c85518Srobert // parameter types but where the default argument is dependent on the
2782*12c85518Srobert // outer lambda's declaration context.
2783*12c85518Srobert // template <typename T>
2784*12c85518Srobert // auto f() {
2785*12c85518Srobert // return [](T = []{ return T{}; }()) { return 0; };
2786*12c85518Srobert // }
2787e5dd7070Spatrick NewParm->setUninstantiatedDefaultArg(Arg);
2788e5dd7070Spatrick }
2789e5dd7070Spatrick
2790e5dd7070Spatrick NewParm->setHasInheritedDefaultArg(OldParm->hasInheritedDefaultArg());
2791e5dd7070Spatrick
2792e5dd7070Spatrick if (OldParm->isParameterPack() && !NewParm->isParameterPack()) {
2793e5dd7070Spatrick // Add the new parameter to the instantiated parameter pack.
2794e5dd7070Spatrick CurrentInstantiationScope->InstantiatedLocalPackArg(OldParm, NewParm);
2795e5dd7070Spatrick } else {
2796e5dd7070Spatrick // Introduce an Old -> New mapping
2797e5dd7070Spatrick CurrentInstantiationScope->InstantiatedLocal(OldParm, NewParm);
2798e5dd7070Spatrick }
2799e5dd7070Spatrick
2800e5dd7070Spatrick // FIXME: OldParm may come from a FunctionProtoType, in which case CurContext
2801e5dd7070Spatrick // can be anything, is this right ?
2802e5dd7070Spatrick NewParm->setDeclContext(CurContext);
2803e5dd7070Spatrick
2804e5dd7070Spatrick NewParm->setScopeInfo(OldParm->getFunctionScopeDepth(),
2805e5dd7070Spatrick OldParm->getFunctionScopeIndex() + indexAdjustment);
2806e5dd7070Spatrick
2807e5dd7070Spatrick InstantiateAttrs(TemplateArgs, OldParm, NewParm);
2808e5dd7070Spatrick
2809e5dd7070Spatrick return NewParm;
2810e5dd7070Spatrick }
2811e5dd7070Spatrick
2812e5dd7070Spatrick /// Substitute the given template arguments into the given set of
2813e5dd7070Spatrick /// parameters, producing the set of parameter types that would be generated
2814e5dd7070Spatrick /// from such a substitution.
SubstParmTypes(SourceLocation Loc,ArrayRef<ParmVarDecl * > Params,const FunctionProtoType::ExtParameterInfo * ExtParamInfos,const MultiLevelTemplateArgumentList & TemplateArgs,SmallVectorImpl<QualType> & ParamTypes,SmallVectorImpl<ParmVarDecl * > * OutParams,ExtParameterInfoBuilder & ParamInfos)2815e5dd7070Spatrick bool Sema::SubstParmTypes(
2816e5dd7070Spatrick SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
2817e5dd7070Spatrick const FunctionProtoType::ExtParameterInfo *ExtParamInfos,
2818e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs,
2819e5dd7070Spatrick SmallVectorImpl<QualType> &ParamTypes,
2820e5dd7070Spatrick SmallVectorImpl<ParmVarDecl *> *OutParams,
2821e5dd7070Spatrick ExtParameterInfoBuilder &ParamInfos) {
2822e5dd7070Spatrick assert(!CodeSynthesisContexts.empty() &&
2823e5dd7070Spatrick "Cannot perform an instantiation without some context on the "
2824e5dd7070Spatrick "instantiation stack");
2825e5dd7070Spatrick
2826e5dd7070Spatrick TemplateInstantiator Instantiator(*this, TemplateArgs, Loc,
2827e5dd7070Spatrick DeclarationName());
2828e5dd7070Spatrick return Instantiator.TransformFunctionTypeParams(
2829e5dd7070Spatrick Loc, Params, nullptr, ExtParamInfos, ParamTypes, OutParams, ParamInfos);
2830e5dd7070Spatrick }
2831e5dd7070Spatrick
2832*12c85518Srobert /// Substitute the given template arguments into the default argument.
SubstDefaultArgument(SourceLocation Loc,ParmVarDecl * Param,const MultiLevelTemplateArgumentList & TemplateArgs,bool ForCallExpr)2833*12c85518Srobert bool Sema::SubstDefaultArgument(
2834*12c85518Srobert SourceLocation Loc,
2835*12c85518Srobert ParmVarDecl *Param,
2836*12c85518Srobert const MultiLevelTemplateArgumentList &TemplateArgs,
2837*12c85518Srobert bool ForCallExpr) {
2838*12c85518Srobert FunctionDecl *FD = cast<FunctionDecl>(Param->getDeclContext());
2839*12c85518Srobert Expr *PatternExpr = Param->getUninstantiatedDefaultArg();
2840*12c85518Srobert
2841*12c85518Srobert EnterExpressionEvaluationContext EvalContext(
2842*12c85518Srobert *this, ExpressionEvaluationContext::PotentiallyEvaluated, Param);
2843*12c85518Srobert
2844*12c85518Srobert InstantiatingTemplate Inst(*this, Loc, Param, TemplateArgs.getInnermost());
2845*12c85518Srobert if (Inst.isInvalid())
2846*12c85518Srobert return true;
2847*12c85518Srobert if (Inst.isAlreadyInstantiating()) {
2848*12c85518Srobert Diag(Param->getBeginLoc(), diag::err_recursive_default_argument) << FD;
2849*12c85518Srobert Param->setInvalidDecl();
2850*12c85518Srobert return true;
2851*12c85518Srobert }
2852*12c85518Srobert
2853*12c85518Srobert ExprResult Result;
2854*12c85518Srobert {
2855*12c85518Srobert // C++ [dcl.fct.default]p5:
2856*12c85518Srobert // The names in the [default argument] expression are bound, and
2857*12c85518Srobert // the semantic constraints are checked, at the point where the
2858*12c85518Srobert // default argument expression appears.
2859*12c85518Srobert ContextRAII SavedContext(*this, FD);
2860*12c85518Srobert std::unique_ptr<LocalInstantiationScope> LIS;
2861*12c85518Srobert
2862*12c85518Srobert if (ForCallExpr) {
2863*12c85518Srobert // When instantiating a default argument due to use in a call expression,
2864*12c85518Srobert // an instantiation scope that includes the parameters of the callee is
2865*12c85518Srobert // required to satisfy references from the default argument. For example:
2866*12c85518Srobert // template<typename T> void f(T a, int = decltype(a)());
2867*12c85518Srobert // void g() { f(0); }
2868*12c85518Srobert LIS = std::make_unique<LocalInstantiationScope>(*this);
2869*12c85518Srobert FunctionDecl *PatternFD = FD->getTemplateInstantiationPattern(
2870*12c85518Srobert /*ForDefinition*/ false);
2871*12c85518Srobert if (addInstantiatedParametersToScope(FD, PatternFD, *LIS, TemplateArgs))
2872*12c85518Srobert return true;
2873*12c85518Srobert }
2874*12c85518Srobert
2875*12c85518Srobert runWithSufficientStackSpace(Loc, [&] {
2876*12c85518Srobert Result = SubstInitializer(PatternExpr, TemplateArgs,
2877*12c85518Srobert /*DirectInit*/false);
2878*12c85518Srobert });
2879*12c85518Srobert }
2880*12c85518Srobert if (Result.isInvalid())
2881*12c85518Srobert return true;
2882*12c85518Srobert
2883*12c85518Srobert if (ForCallExpr) {
2884*12c85518Srobert // Check the expression as an initializer for the parameter.
2885*12c85518Srobert InitializedEntity Entity
2886*12c85518Srobert = InitializedEntity::InitializeParameter(Context, Param);
2887*12c85518Srobert InitializationKind Kind = InitializationKind::CreateCopy(
2888*12c85518Srobert Param->getLocation(),
2889*12c85518Srobert /*FIXME:EqualLoc*/ PatternExpr->getBeginLoc());
2890*12c85518Srobert Expr *ResultE = Result.getAs<Expr>();
2891*12c85518Srobert
2892*12c85518Srobert InitializationSequence InitSeq(*this, Entity, Kind, ResultE);
2893*12c85518Srobert Result = InitSeq.Perform(*this, Entity, Kind, ResultE);
2894*12c85518Srobert if (Result.isInvalid())
2895*12c85518Srobert return true;
2896*12c85518Srobert
2897*12c85518Srobert Result =
2898*12c85518Srobert ActOnFinishFullExpr(Result.getAs<Expr>(), Param->getOuterLocStart(),
2899*12c85518Srobert /*DiscardedValue*/ false);
2900*12c85518Srobert } else {
2901*12c85518Srobert // FIXME: Obtain the source location for the '=' token.
2902*12c85518Srobert SourceLocation EqualLoc = PatternExpr->getBeginLoc();
2903*12c85518Srobert Result = ConvertParamDefaultArgument(Param, Result.getAs<Expr>(), EqualLoc);
2904*12c85518Srobert }
2905*12c85518Srobert if (Result.isInvalid())
2906*12c85518Srobert return true;
2907*12c85518Srobert
2908*12c85518Srobert // Remember the instantiated default argument.
2909*12c85518Srobert Param->setDefaultArg(Result.getAs<Expr>());
2910*12c85518Srobert
2911*12c85518Srobert return false;
2912*12c85518Srobert }
2913*12c85518Srobert
2914e5dd7070Spatrick /// Perform substitution on the base class specifiers of the
2915e5dd7070Spatrick /// given class template specialization.
2916e5dd7070Spatrick ///
2917e5dd7070Spatrick /// Produces a diagnostic and returns true on error, returns false and
2918e5dd7070Spatrick /// attaches the instantiated base classes to the class template
2919e5dd7070Spatrick /// specialization if successful.
2920e5dd7070Spatrick bool
SubstBaseSpecifiers(CXXRecordDecl * Instantiation,CXXRecordDecl * Pattern,const MultiLevelTemplateArgumentList & TemplateArgs)2921e5dd7070Spatrick Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
2922e5dd7070Spatrick CXXRecordDecl *Pattern,
2923e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs) {
2924e5dd7070Spatrick bool Invalid = false;
2925e5dd7070Spatrick SmallVector<CXXBaseSpecifier*, 4> InstantiatedBases;
2926e5dd7070Spatrick for (const auto &Base : Pattern->bases()) {
2927e5dd7070Spatrick if (!Base.getType()->isDependentType()) {
2928e5dd7070Spatrick if (const CXXRecordDecl *RD = Base.getType()->getAsCXXRecordDecl()) {
2929e5dd7070Spatrick if (RD->isInvalidDecl())
2930e5dd7070Spatrick Instantiation->setInvalidDecl();
2931e5dd7070Spatrick }
2932e5dd7070Spatrick InstantiatedBases.push_back(new (Context) CXXBaseSpecifier(Base));
2933e5dd7070Spatrick continue;
2934e5dd7070Spatrick }
2935e5dd7070Spatrick
2936e5dd7070Spatrick SourceLocation EllipsisLoc;
2937e5dd7070Spatrick TypeSourceInfo *BaseTypeLoc;
2938e5dd7070Spatrick if (Base.isPackExpansion()) {
2939e5dd7070Spatrick // This is a pack expansion. See whether we should expand it now, or
2940e5dd7070Spatrick // wait until later.
2941e5dd7070Spatrick SmallVector<UnexpandedParameterPack, 2> Unexpanded;
2942e5dd7070Spatrick collectUnexpandedParameterPacks(Base.getTypeSourceInfo()->getTypeLoc(),
2943e5dd7070Spatrick Unexpanded);
2944e5dd7070Spatrick bool ShouldExpand = false;
2945e5dd7070Spatrick bool RetainExpansion = false;
2946*12c85518Srobert std::optional<unsigned> NumExpansions;
2947e5dd7070Spatrick if (CheckParameterPacksForExpansion(Base.getEllipsisLoc(),
2948e5dd7070Spatrick Base.getSourceRange(),
2949e5dd7070Spatrick Unexpanded,
2950e5dd7070Spatrick TemplateArgs, ShouldExpand,
2951e5dd7070Spatrick RetainExpansion,
2952e5dd7070Spatrick NumExpansions)) {
2953e5dd7070Spatrick Invalid = true;
2954e5dd7070Spatrick continue;
2955e5dd7070Spatrick }
2956e5dd7070Spatrick
2957e5dd7070Spatrick // If we should expand this pack expansion now, do so.
2958e5dd7070Spatrick if (ShouldExpand) {
2959e5dd7070Spatrick for (unsigned I = 0; I != *NumExpansions; ++I) {
2960e5dd7070Spatrick Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, I);
2961e5dd7070Spatrick
2962e5dd7070Spatrick TypeSourceInfo *BaseTypeLoc = SubstType(Base.getTypeSourceInfo(),
2963e5dd7070Spatrick TemplateArgs,
2964e5dd7070Spatrick Base.getSourceRange().getBegin(),
2965e5dd7070Spatrick DeclarationName());
2966e5dd7070Spatrick if (!BaseTypeLoc) {
2967e5dd7070Spatrick Invalid = true;
2968e5dd7070Spatrick continue;
2969e5dd7070Spatrick }
2970e5dd7070Spatrick
2971e5dd7070Spatrick if (CXXBaseSpecifier *InstantiatedBase
2972e5dd7070Spatrick = CheckBaseSpecifier(Instantiation,
2973e5dd7070Spatrick Base.getSourceRange(),
2974e5dd7070Spatrick Base.isVirtual(),
2975e5dd7070Spatrick Base.getAccessSpecifierAsWritten(),
2976e5dd7070Spatrick BaseTypeLoc,
2977e5dd7070Spatrick SourceLocation()))
2978e5dd7070Spatrick InstantiatedBases.push_back(InstantiatedBase);
2979e5dd7070Spatrick else
2980e5dd7070Spatrick Invalid = true;
2981e5dd7070Spatrick }
2982e5dd7070Spatrick
2983e5dd7070Spatrick continue;
2984e5dd7070Spatrick }
2985e5dd7070Spatrick
2986e5dd7070Spatrick // The resulting base specifier will (still) be a pack expansion.
2987e5dd7070Spatrick EllipsisLoc = Base.getEllipsisLoc();
2988e5dd7070Spatrick Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, -1);
2989e5dd7070Spatrick BaseTypeLoc = SubstType(Base.getTypeSourceInfo(),
2990e5dd7070Spatrick TemplateArgs,
2991e5dd7070Spatrick Base.getSourceRange().getBegin(),
2992e5dd7070Spatrick DeclarationName());
2993e5dd7070Spatrick } else {
2994e5dd7070Spatrick BaseTypeLoc = SubstType(Base.getTypeSourceInfo(),
2995e5dd7070Spatrick TemplateArgs,
2996e5dd7070Spatrick Base.getSourceRange().getBegin(),
2997e5dd7070Spatrick DeclarationName());
2998e5dd7070Spatrick }
2999e5dd7070Spatrick
3000e5dd7070Spatrick if (!BaseTypeLoc) {
3001e5dd7070Spatrick Invalid = true;
3002e5dd7070Spatrick continue;
3003e5dd7070Spatrick }
3004e5dd7070Spatrick
3005e5dd7070Spatrick if (CXXBaseSpecifier *InstantiatedBase
3006e5dd7070Spatrick = CheckBaseSpecifier(Instantiation,
3007e5dd7070Spatrick Base.getSourceRange(),
3008e5dd7070Spatrick Base.isVirtual(),
3009e5dd7070Spatrick Base.getAccessSpecifierAsWritten(),
3010e5dd7070Spatrick BaseTypeLoc,
3011e5dd7070Spatrick EllipsisLoc))
3012e5dd7070Spatrick InstantiatedBases.push_back(InstantiatedBase);
3013e5dd7070Spatrick else
3014e5dd7070Spatrick Invalid = true;
3015e5dd7070Spatrick }
3016e5dd7070Spatrick
3017e5dd7070Spatrick if (!Invalid && AttachBaseSpecifiers(Instantiation, InstantiatedBases))
3018e5dd7070Spatrick Invalid = true;
3019e5dd7070Spatrick
3020e5dd7070Spatrick return Invalid;
3021e5dd7070Spatrick }
3022e5dd7070Spatrick
3023e5dd7070Spatrick // Defined via #include from SemaTemplateInstantiateDecl.cpp
3024e5dd7070Spatrick namespace clang {
3025e5dd7070Spatrick namespace sema {
3026e5dd7070Spatrick Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C, Sema &S,
3027e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs);
3028e5dd7070Spatrick Attr *instantiateTemplateAttributeForDecl(
3029e5dd7070Spatrick const Attr *At, ASTContext &C, Sema &S,
3030e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs);
3031e5dd7070Spatrick }
3032e5dd7070Spatrick }
3033e5dd7070Spatrick
3034e5dd7070Spatrick /// Instantiate the definition of a class from a given pattern.
3035e5dd7070Spatrick ///
3036e5dd7070Spatrick /// \param PointOfInstantiation The point of instantiation within the
3037e5dd7070Spatrick /// source code.
3038e5dd7070Spatrick ///
3039e5dd7070Spatrick /// \param Instantiation is the declaration whose definition is being
3040e5dd7070Spatrick /// instantiated. This will be either a class template specialization
3041e5dd7070Spatrick /// or a member class of a class template specialization.
3042e5dd7070Spatrick ///
3043e5dd7070Spatrick /// \param Pattern is the pattern from which the instantiation
3044e5dd7070Spatrick /// occurs. This will be either the declaration of a class template or
3045e5dd7070Spatrick /// the declaration of a member class of a class template.
3046e5dd7070Spatrick ///
3047e5dd7070Spatrick /// \param TemplateArgs The template arguments to be substituted into
3048e5dd7070Spatrick /// the pattern.
3049e5dd7070Spatrick ///
3050e5dd7070Spatrick /// \param TSK the kind of implicit or explicit instantiation to perform.
3051e5dd7070Spatrick ///
3052e5dd7070Spatrick /// \param Complain whether to complain if the class cannot be instantiated due
3053e5dd7070Spatrick /// to the lack of a definition.
3054e5dd7070Spatrick ///
3055e5dd7070Spatrick /// \returns true if an error occurred, false otherwise.
3056e5dd7070Spatrick bool
InstantiateClass(SourceLocation PointOfInstantiation,CXXRecordDecl * Instantiation,CXXRecordDecl * Pattern,const MultiLevelTemplateArgumentList & TemplateArgs,TemplateSpecializationKind TSK,bool Complain)3057e5dd7070Spatrick Sema::InstantiateClass(SourceLocation PointOfInstantiation,
3058e5dd7070Spatrick CXXRecordDecl *Instantiation, CXXRecordDecl *Pattern,
3059e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs,
3060e5dd7070Spatrick TemplateSpecializationKind TSK,
3061e5dd7070Spatrick bool Complain) {
3062e5dd7070Spatrick CXXRecordDecl *PatternDef
3063e5dd7070Spatrick = cast_or_null<CXXRecordDecl>(Pattern->getDefinition());
3064e5dd7070Spatrick if (DiagnoseUninstantiableTemplate(PointOfInstantiation, Instantiation,
3065e5dd7070Spatrick Instantiation->getInstantiatedFromMemberClass(),
3066e5dd7070Spatrick Pattern, PatternDef, TSK, Complain))
3067e5dd7070Spatrick return true;
3068e5dd7070Spatrick
3069e5dd7070Spatrick llvm::TimeTraceScope TimeScope("InstantiateClass", [&]() {
3070e5dd7070Spatrick std::string Name;
3071e5dd7070Spatrick llvm::raw_string_ostream OS(Name);
3072e5dd7070Spatrick Instantiation->getNameForDiagnostic(OS, getPrintingPolicy(),
3073e5dd7070Spatrick /*Qualified=*/true);
3074e5dd7070Spatrick return Name;
3075e5dd7070Spatrick });
3076e5dd7070Spatrick
3077e5dd7070Spatrick Pattern = PatternDef;
3078e5dd7070Spatrick
3079e5dd7070Spatrick // Record the point of instantiation.
3080e5dd7070Spatrick if (MemberSpecializationInfo *MSInfo
3081e5dd7070Spatrick = Instantiation->getMemberSpecializationInfo()) {
3082e5dd7070Spatrick MSInfo->setTemplateSpecializationKind(TSK);
3083e5dd7070Spatrick MSInfo->setPointOfInstantiation(PointOfInstantiation);
3084e5dd7070Spatrick } else if (ClassTemplateSpecializationDecl *Spec
3085e5dd7070Spatrick = dyn_cast<ClassTemplateSpecializationDecl>(Instantiation)) {
3086e5dd7070Spatrick Spec->setTemplateSpecializationKind(TSK);
3087e5dd7070Spatrick Spec->setPointOfInstantiation(PointOfInstantiation);
3088e5dd7070Spatrick }
3089e5dd7070Spatrick
3090e5dd7070Spatrick InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);
3091e5dd7070Spatrick if (Inst.isInvalid())
3092e5dd7070Spatrick return true;
3093e5dd7070Spatrick assert(!Inst.isAlreadyInstantiating() && "should have been caught by caller");
3094e5dd7070Spatrick PrettyDeclStackTraceEntry CrashInfo(Context, Instantiation, SourceLocation(),
3095e5dd7070Spatrick "instantiating class definition");
3096e5dd7070Spatrick
3097e5dd7070Spatrick // Enter the scope of this instantiation. We don't use
3098e5dd7070Spatrick // PushDeclContext because we don't have a scope.
3099e5dd7070Spatrick ContextRAII SavedContext(*this, Instantiation);
3100e5dd7070Spatrick EnterExpressionEvaluationContext EvalContext(
3101e5dd7070Spatrick *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
3102e5dd7070Spatrick
3103e5dd7070Spatrick // If this is an instantiation of a local class, merge this local
3104e5dd7070Spatrick // instantiation scope with the enclosing scope. Otherwise, every
3105e5dd7070Spatrick // instantiation of a class has its own local instantiation scope.
3106e5dd7070Spatrick bool MergeWithParentScope = !Instantiation->isDefinedOutsideFunctionOrMethod();
3107e5dd7070Spatrick LocalInstantiationScope Scope(*this, MergeWithParentScope);
3108e5dd7070Spatrick
3109e5dd7070Spatrick // Some class state isn't processed immediately but delayed till class
3110e5dd7070Spatrick // instantiation completes. We may not be ready to handle any delayed state
3111e5dd7070Spatrick // already on the stack as it might correspond to a different class, so save
3112e5dd7070Spatrick // it now and put it back later.
3113e5dd7070Spatrick SavePendingParsedClassStateRAII SavedPendingParsedClassState(*this);
3114e5dd7070Spatrick
3115e5dd7070Spatrick // Pull attributes from the pattern onto the instantiation.
3116e5dd7070Spatrick InstantiateAttrs(TemplateArgs, Pattern, Instantiation);
3117e5dd7070Spatrick
3118e5dd7070Spatrick // Start the definition of this instantiation.
3119e5dd7070Spatrick Instantiation->startDefinition();
3120e5dd7070Spatrick
3121e5dd7070Spatrick // The instantiation is visible here, even if it was first declared in an
3122e5dd7070Spatrick // unimported module.
3123e5dd7070Spatrick Instantiation->setVisibleDespiteOwningModule();
3124e5dd7070Spatrick
3125e5dd7070Spatrick // FIXME: This loses the as-written tag kind for an explicit instantiation.
3126e5dd7070Spatrick Instantiation->setTagKind(Pattern->getTagKind());
3127e5dd7070Spatrick
3128e5dd7070Spatrick // Do substitution on the base class specifiers.
3129e5dd7070Spatrick if (SubstBaseSpecifiers(Instantiation, Pattern, TemplateArgs))
3130e5dd7070Spatrick Instantiation->setInvalidDecl();
3131e5dd7070Spatrick
3132e5dd7070Spatrick TemplateDeclInstantiator Instantiator(*this, Instantiation, TemplateArgs);
3133*12c85518Srobert Instantiator.setEvaluateConstraints(false);
3134e5dd7070Spatrick SmallVector<Decl*, 4> Fields;
3135e5dd7070Spatrick // Delay instantiation of late parsed attributes.
3136e5dd7070Spatrick LateInstantiatedAttrVec LateAttrs;
3137e5dd7070Spatrick Instantiator.enableLateAttributeInstantiation(&LateAttrs);
3138e5dd7070Spatrick
3139e5dd7070Spatrick bool MightHaveConstexprVirtualFunctions = false;
3140e5dd7070Spatrick for (auto *Member : Pattern->decls()) {
3141e5dd7070Spatrick // Don't instantiate members not belonging in this semantic context.
3142e5dd7070Spatrick // e.g. for:
3143e5dd7070Spatrick // @code
3144e5dd7070Spatrick // template <int i> class A {
3145e5dd7070Spatrick // class B *g;
3146e5dd7070Spatrick // };
3147e5dd7070Spatrick // @endcode
3148e5dd7070Spatrick // 'class B' has the template as lexical context but semantically it is
3149e5dd7070Spatrick // introduced in namespace scope.
3150e5dd7070Spatrick if (Member->getDeclContext() != Pattern)
3151e5dd7070Spatrick continue;
3152e5dd7070Spatrick
3153e5dd7070Spatrick // BlockDecls can appear in a default-member-initializer. They must be the
3154e5dd7070Spatrick // child of a BlockExpr, so we only know how to instantiate them from there.
3155a9ac8606Spatrick // Similarly, lambda closure types are recreated when instantiating the
3156a9ac8606Spatrick // corresponding LambdaExpr.
3157a9ac8606Spatrick if (isa<BlockDecl>(Member) ||
3158a9ac8606Spatrick (isa<CXXRecordDecl>(Member) && cast<CXXRecordDecl>(Member)->isLambda()))
3159e5dd7070Spatrick continue;
3160e5dd7070Spatrick
3161e5dd7070Spatrick if (Member->isInvalidDecl()) {
3162e5dd7070Spatrick Instantiation->setInvalidDecl();
3163e5dd7070Spatrick continue;
3164e5dd7070Spatrick }
3165e5dd7070Spatrick
3166e5dd7070Spatrick Decl *NewMember = Instantiator.Visit(Member);
3167e5dd7070Spatrick if (NewMember) {
3168e5dd7070Spatrick if (FieldDecl *Field = dyn_cast<FieldDecl>(NewMember)) {
3169e5dd7070Spatrick Fields.push_back(Field);
3170e5dd7070Spatrick } else if (EnumDecl *Enum = dyn_cast<EnumDecl>(NewMember)) {
3171e5dd7070Spatrick // C++11 [temp.inst]p1: The implicit instantiation of a class template
3172e5dd7070Spatrick // specialization causes the implicit instantiation of the definitions
3173e5dd7070Spatrick // of unscoped member enumerations.
3174e5dd7070Spatrick // Record a point of instantiation for this implicit instantiation.
3175e5dd7070Spatrick if (TSK == TSK_ImplicitInstantiation && !Enum->isScoped() &&
3176e5dd7070Spatrick Enum->isCompleteDefinition()) {
3177e5dd7070Spatrick MemberSpecializationInfo *MSInfo =Enum->getMemberSpecializationInfo();
3178e5dd7070Spatrick assert(MSInfo && "no spec info for member enum specialization");
3179e5dd7070Spatrick MSInfo->setTemplateSpecializationKind(TSK_ImplicitInstantiation);
3180e5dd7070Spatrick MSInfo->setPointOfInstantiation(PointOfInstantiation);
3181e5dd7070Spatrick }
3182e5dd7070Spatrick } else if (StaticAssertDecl *SA = dyn_cast<StaticAssertDecl>(NewMember)) {
3183e5dd7070Spatrick if (SA->isFailed()) {
3184e5dd7070Spatrick // A static_assert failed. Bail out; instantiating this
3185e5dd7070Spatrick // class is probably not meaningful.
3186e5dd7070Spatrick Instantiation->setInvalidDecl();
3187e5dd7070Spatrick break;
3188e5dd7070Spatrick }
3189e5dd7070Spatrick } else if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewMember)) {
3190e5dd7070Spatrick if (MD->isConstexpr() && !MD->getFriendObjectKind() &&
3191e5dd7070Spatrick (MD->isVirtualAsWritten() || Instantiation->getNumBases()))
3192e5dd7070Spatrick MightHaveConstexprVirtualFunctions = true;
3193e5dd7070Spatrick }
3194e5dd7070Spatrick
3195e5dd7070Spatrick if (NewMember->isInvalidDecl())
3196e5dd7070Spatrick Instantiation->setInvalidDecl();
3197e5dd7070Spatrick } else {
3198e5dd7070Spatrick // FIXME: Eventually, a NULL return will mean that one of the
3199e5dd7070Spatrick // instantiations was a semantic disaster, and we'll want to mark the
3200e5dd7070Spatrick // declaration invalid.
3201e5dd7070Spatrick // For now, we expect to skip some members that we can't yet handle.
3202e5dd7070Spatrick }
3203e5dd7070Spatrick }
3204e5dd7070Spatrick
3205e5dd7070Spatrick // Finish checking fields.
3206e5dd7070Spatrick ActOnFields(nullptr, Instantiation->getLocation(), Instantiation, Fields,
3207e5dd7070Spatrick SourceLocation(), SourceLocation(), ParsedAttributesView());
3208e5dd7070Spatrick CheckCompletedCXXClass(nullptr, Instantiation);
3209e5dd7070Spatrick
3210e5dd7070Spatrick // Default arguments are parsed, if not instantiated. We can go instantiate
3211e5dd7070Spatrick // default arg exprs for default constructors if necessary now. Unless we're
3212e5dd7070Spatrick // parsing a class, in which case wait until that's finished.
3213e5dd7070Spatrick if (ParsingClassDepth == 0)
3214e5dd7070Spatrick ActOnFinishCXXNonNestedClass();
3215e5dd7070Spatrick
3216e5dd7070Spatrick // Instantiate late parsed attributes, and attach them to their decls.
3217e5dd7070Spatrick // See Sema::InstantiateAttrs
3218e5dd7070Spatrick for (LateInstantiatedAttrVec::iterator I = LateAttrs.begin(),
3219e5dd7070Spatrick E = LateAttrs.end(); I != E; ++I) {
3220e5dd7070Spatrick assert(CurrentInstantiationScope == Instantiator.getStartingScope());
3221e5dd7070Spatrick CurrentInstantiationScope = I->Scope;
3222e5dd7070Spatrick
3223e5dd7070Spatrick // Allow 'this' within late-parsed attributes.
3224*12c85518Srobert auto *ND = cast<NamedDecl>(I->NewDecl);
3225*12c85518Srobert auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext());
3226e5dd7070Spatrick CXXThisScopeRAII ThisScope(*this, ThisContext, Qualifiers(),
3227*12c85518Srobert ND->isCXXInstanceMember());
3228e5dd7070Spatrick
3229e5dd7070Spatrick Attr *NewAttr =
3230e5dd7070Spatrick instantiateTemplateAttribute(I->TmplAttr, Context, *this, TemplateArgs);
3231a9ac8606Spatrick if (NewAttr)
3232e5dd7070Spatrick I->NewDecl->addAttr(NewAttr);
3233e5dd7070Spatrick LocalInstantiationScope::deleteScopes(I->Scope,
3234e5dd7070Spatrick Instantiator.getStartingScope());
3235e5dd7070Spatrick }
3236e5dd7070Spatrick Instantiator.disableLateAttributeInstantiation();
3237e5dd7070Spatrick LateAttrs.clear();
3238e5dd7070Spatrick
3239e5dd7070Spatrick ActOnFinishDelayedMemberInitializers(Instantiation);
3240e5dd7070Spatrick
3241e5dd7070Spatrick // FIXME: We should do something similar for explicit instantiations so they
3242e5dd7070Spatrick // end up in the right module.
3243e5dd7070Spatrick if (TSK == TSK_ImplicitInstantiation) {
3244e5dd7070Spatrick Instantiation->setLocation(Pattern->getLocation());
3245e5dd7070Spatrick Instantiation->setLocStart(Pattern->getInnerLocStart());
3246e5dd7070Spatrick Instantiation->setBraceRange(Pattern->getBraceRange());
3247e5dd7070Spatrick }
3248e5dd7070Spatrick
3249e5dd7070Spatrick if (!Instantiation->isInvalidDecl()) {
3250e5dd7070Spatrick // Perform any dependent diagnostics from the pattern.
3251a9ac8606Spatrick if (Pattern->isDependentContext())
3252e5dd7070Spatrick PerformDependentDiagnostics(Pattern, TemplateArgs);
3253e5dd7070Spatrick
3254e5dd7070Spatrick // Instantiate any out-of-line class template partial
3255e5dd7070Spatrick // specializations now.
3256e5dd7070Spatrick for (TemplateDeclInstantiator::delayed_partial_spec_iterator
3257e5dd7070Spatrick P = Instantiator.delayed_partial_spec_begin(),
3258e5dd7070Spatrick PEnd = Instantiator.delayed_partial_spec_end();
3259e5dd7070Spatrick P != PEnd; ++P) {
3260e5dd7070Spatrick if (!Instantiator.InstantiateClassTemplatePartialSpecialization(
3261e5dd7070Spatrick P->first, P->second)) {
3262e5dd7070Spatrick Instantiation->setInvalidDecl();
3263e5dd7070Spatrick break;
3264e5dd7070Spatrick }
3265e5dd7070Spatrick }
3266e5dd7070Spatrick
3267e5dd7070Spatrick // Instantiate any out-of-line variable template partial
3268e5dd7070Spatrick // specializations now.
3269e5dd7070Spatrick for (TemplateDeclInstantiator::delayed_var_partial_spec_iterator
3270e5dd7070Spatrick P = Instantiator.delayed_var_partial_spec_begin(),
3271e5dd7070Spatrick PEnd = Instantiator.delayed_var_partial_spec_end();
3272e5dd7070Spatrick P != PEnd; ++P) {
3273e5dd7070Spatrick if (!Instantiator.InstantiateVarTemplatePartialSpecialization(
3274e5dd7070Spatrick P->first, P->second)) {
3275e5dd7070Spatrick Instantiation->setInvalidDecl();
3276e5dd7070Spatrick break;
3277e5dd7070Spatrick }
3278e5dd7070Spatrick }
3279e5dd7070Spatrick }
3280e5dd7070Spatrick
3281e5dd7070Spatrick // Exit the scope of this instantiation.
3282e5dd7070Spatrick SavedContext.pop();
3283e5dd7070Spatrick
3284e5dd7070Spatrick if (!Instantiation->isInvalidDecl()) {
3285e5dd7070Spatrick // Always emit the vtable for an explicit instantiation definition
3286e5dd7070Spatrick // of a polymorphic class template specialization. Otherwise, eagerly
3287e5dd7070Spatrick // instantiate only constexpr virtual functions in preparation for their use
3288e5dd7070Spatrick // in constant evaluation.
3289e5dd7070Spatrick if (TSK == TSK_ExplicitInstantiationDefinition)
3290e5dd7070Spatrick MarkVTableUsed(PointOfInstantiation, Instantiation, true);
3291e5dd7070Spatrick else if (MightHaveConstexprVirtualFunctions)
3292e5dd7070Spatrick MarkVirtualMembersReferenced(PointOfInstantiation, Instantiation,
3293e5dd7070Spatrick /*ConstexprOnly*/ true);
3294e5dd7070Spatrick }
3295e5dd7070Spatrick
3296a9ac8606Spatrick Consumer.HandleTagDeclDefinition(Instantiation);
3297a9ac8606Spatrick
3298e5dd7070Spatrick return Instantiation->isInvalidDecl();
3299e5dd7070Spatrick }
3300e5dd7070Spatrick
3301e5dd7070Spatrick /// Instantiate the definition of an enum from a given pattern.
3302e5dd7070Spatrick ///
3303e5dd7070Spatrick /// \param PointOfInstantiation The point of instantiation within the
3304e5dd7070Spatrick /// source code.
3305e5dd7070Spatrick /// \param Instantiation is the declaration whose definition is being
3306e5dd7070Spatrick /// instantiated. This will be a member enumeration of a class
3307e5dd7070Spatrick /// temploid specialization, or a local enumeration within a
3308e5dd7070Spatrick /// function temploid specialization.
3309e5dd7070Spatrick /// \param Pattern The templated declaration from which the instantiation
3310e5dd7070Spatrick /// occurs.
3311e5dd7070Spatrick /// \param TemplateArgs The template arguments to be substituted into
3312e5dd7070Spatrick /// the pattern.
3313e5dd7070Spatrick /// \param TSK The kind of implicit or explicit instantiation to perform.
3314e5dd7070Spatrick ///
3315e5dd7070Spatrick /// \return \c true if an error occurred, \c false otherwise.
InstantiateEnum(SourceLocation PointOfInstantiation,EnumDecl * Instantiation,EnumDecl * Pattern,const MultiLevelTemplateArgumentList & TemplateArgs,TemplateSpecializationKind TSK)3316e5dd7070Spatrick bool Sema::InstantiateEnum(SourceLocation PointOfInstantiation,
3317e5dd7070Spatrick EnumDecl *Instantiation, EnumDecl *Pattern,
3318e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs,
3319e5dd7070Spatrick TemplateSpecializationKind TSK) {
3320e5dd7070Spatrick EnumDecl *PatternDef = Pattern->getDefinition();
3321e5dd7070Spatrick if (DiagnoseUninstantiableTemplate(PointOfInstantiation, Instantiation,
3322e5dd7070Spatrick Instantiation->getInstantiatedFromMemberEnum(),
3323e5dd7070Spatrick Pattern, PatternDef, TSK,/*Complain*/true))
3324e5dd7070Spatrick return true;
3325e5dd7070Spatrick Pattern = PatternDef;
3326e5dd7070Spatrick
3327e5dd7070Spatrick // Record the point of instantiation.
3328e5dd7070Spatrick if (MemberSpecializationInfo *MSInfo
3329e5dd7070Spatrick = Instantiation->getMemberSpecializationInfo()) {
3330e5dd7070Spatrick MSInfo->setTemplateSpecializationKind(TSK);
3331e5dd7070Spatrick MSInfo->setPointOfInstantiation(PointOfInstantiation);
3332e5dd7070Spatrick }
3333e5dd7070Spatrick
3334e5dd7070Spatrick InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);
3335e5dd7070Spatrick if (Inst.isInvalid())
3336e5dd7070Spatrick return true;
3337e5dd7070Spatrick if (Inst.isAlreadyInstantiating())
3338e5dd7070Spatrick return false;
3339e5dd7070Spatrick PrettyDeclStackTraceEntry CrashInfo(Context, Instantiation, SourceLocation(),
3340e5dd7070Spatrick "instantiating enum definition");
3341e5dd7070Spatrick
3342e5dd7070Spatrick // The instantiation is visible here, even if it was first declared in an
3343e5dd7070Spatrick // unimported module.
3344e5dd7070Spatrick Instantiation->setVisibleDespiteOwningModule();
3345e5dd7070Spatrick
3346e5dd7070Spatrick // Enter the scope of this instantiation. We don't use
3347e5dd7070Spatrick // PushDeclContext because we don't have a scope.
3348e5dd7070Spatrick ContextRAII SavedContext(*this, Instantiation);
3349e5dd7070Spatrick EnterExpressionEvaluationContext EvalContext(
3350e5dd7070Spatrick *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
3351e5dd7070Spatrick
3352e5dd7070Spatrick LocalInstantiationScope Scope(*this, /*MergeWithParentScope*/true);
3353e5dd7070Spatrick
3354e5dd7070Spatrick // Pull attributes from the pattern onto the instantiation.
3355e5dd7070Spatrick InstantiateAttrs(TemplateArgs, Pattern, Instantiation);
3356e5dd7070Spatrick
3357e5dd7070Spatrick TemplateDeclInstantiator Instantiator(*this, Instantiation, TemplateArgs);
3358e5dd7070Spatrick Instantiator.InstantiateEnumDefinition(Instantiation, Pattern);
3359e5dd7070Spatrick
3360e5dd7070Spatrick // Exit the scope of this instantiation.
3361e5dd7070Spatrick SavedContext.pop();
3362e5dd7070Spatrick
3363e5dd7070Spatrick return Instantiation->isInvalidDecl();
3364e5dd7070Spatrick }
3365e5dd7070Spatrick
3366e5dd7070Spatrick
3367e5dd7070Spatrick /// Instantiate the definition of a field from the given pattern.
3368e5dd7070Spatrick ///
3369e5dd7070Spatrick /// \param PointOfInstantiation The point of instantiation within the
3370e5dd7070Spatrick /// source code.
3371e5dd7070Spatrick /// \param Instantiation is the declaration whose definition is being
3372e5dd7070Spatrick /// instantiated. This will be a class of a class temploid
3373e5dd7070Spatrick /// specialization, or a local enumeration within a function temploid
3374e5dd7070Spatrick /// specialization.
3375e5dd7070Spatrick /// \param Pattern The templated declaration from which the instantiation
3376e5dd7070Spatrick /// occurs.
3377e5dd7070Spatrick /// \param TemplateArgs The template arguments to be substituted into
3378e5dd7070Spatrick /// the pattern.
3379e5dd7070Spatrick ///
3380e5dd7070Spatrick /// \return \c true if an error occurred, \c false otherwise.
InstantiateInClassInitializer(SourceLocation PointOfInstantiation,FieldDecl * Instantiation,FieldDecl * Pattern,const MultiLevelTemplateArgumentList & TemplateArgs)3381e5dd7070Spatrick bool Sema::InstantiateInClassInitializer(
3382e5dd7070Spatrick SourceLocation PointOfInstantiation, FieldDecl *Instantiation,
3383e5dd7070Spatrick FieldDecl *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs) {
3384e5dd7070Spatrick // If there is no initializer, we don't need to do anything.
3385e5dd7070Spatrick if (!Pattern->hasInClassInitializer())
3386e5dd7070Spatrick return false;
3387e5dd7070Spatrick
3388e5dd7070Spatrick assert(Instantiation->getInClassInitStyle() ==
3389e5dd7070Spatrick Pattern->getInClassInitStyle() &&
3390e5dd7070Spatrick "pattern and instantiation disagree about init style");
3391e5dd7070Spatrick
3392e5dd7070Spatrick // Error out if we haven't parsed the initializer of the pattern yet because
3393e5dd7070Spatrick // we are waiting for the closing brace of the outer class.
3394e5dd7070Spatrick Expr *OldInit = Pattern->getInClassInitializer();
3395e5dd7070Spatrick if (!OldInit) {
3396e5dd7070Spatrick RecordDecl *PatternRD = Pattern->getParent();
3397e5dd7070Spatrick RecordDecl *OutermostClass = PatternRD->getOuterLexicalRecordContext();
3398e5dd7070Spatrick Diag(PointOfInstantiation,
3399a9ac8606Spatrick diag::err_default_member_initializer_not_yet_parsed)
3400e5dd7070Spatrick << OutermostClass << Pattern;
3401a9ac8606Spatrick Diag(Pattern->getEndLoc(),
3402a9ac8606Spatrick diag::note_default_member_initializer_not_yet_parsed);
3403e5dd7070Spatrick Instantiation->setInvalidDecl();
3404e5dd7070Spatrick return true;
3405e5dd7070Spatrick }
3406e5dd7070Spatrick
3407e5dd7070Spatrick InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);
3408e5dd7070Spatrick if (Inst.isInvalid())
3409e5dd7070Spatrick return true;
3410e5dd7070Spatrick if (Inst.isAlreadyInstantiating()) {
3411e5dd7070Spatrick // Error out if we hit an instantiation cycle for this initializer.
3412a9ac8606Spatrick Diag(PointOfInstantiation, diag::err_default_member_initializer_cycle)
3413e5dd7070Spatrick << Instantiation;
3414e5dd7070Spatrick return true;
3415e5dd7070Spatrick }
3416e5dd7070Spatrick PrettyDeclStackTraceEntry CrashInfo(Context, Instantiation, SourceLocation(),
3417e5dd7070Spatrick "instantiating default member init");
3418e5dd7070Spatrick
3419e5dd7070Spatrick // Enter the scope of this instantiation. We don't use PushDeclContext because
3420e5dd7070Spatrick // we don't have a scope.
3421e5dd7070Spatrick ContextRAII SavedContext(*this, Instantiation->getParent());
3422e5dd7070Spatrick EnterExpressionEvaluationContext EvalContext(
3423e5dd7070Spatrick *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
3424*12c85518Srobert ExprEvalContexts.back().DelayedDefaultInitializationContext = {
3425*12c85518Srobert PointOfInstantiation, Instantiation, CurContext};
3426e5dd7070Spatrick
3427e5dd7070Spatrick LocalInstantiationScope Scope(*this, true);
3428e5dd7070Spatrick
3429e5dd7070Spatrick // Instantiate the initializer.
3430e5dd7070Spatrick ActOnStartCXXInClassMemberInitializer();
3431e5dd7070Spatrick CXXThisScopeRAII ThisScope(*this, Instantiation->getParent(), Qualifiers());
3432e5dd7070Spatrick
3433e5dd7070Spatrick ExprResult NewInit = SubstInitializer(OldInit, TemplateArgs,
3434e5dd7070Spatrick /*CXXDirectInit=*/false);
3435e5dd7070Spatrick Expr *Init = NewInit.get();
3436e5dd7070Spatrick assert((!Init || !isa<ParenListExpr>(Init)) && "call-style init in class");
3437e5dd7070Spatrick ActOnFinishCXXInClassMemberInitializer(
3438e5dd7070Spatrick Instantiation, Init ? Init->getBeginLoc() : SourceLocation(), Init);
3439e5dd7070Spatrick
3440e5dd7070Spatrick if (auto *L = getASTMutationListener())
3441e5dd7070Spatrick L->DefaultMemberInitializerInstantiated(Instantiation);
3442e5dd7070Spatrick
3443e5dd7070Spatrick // Return true if the in-class initializer is still missing.
3444e5dd7070Spatrick return !Instantiation->getInClassInitializer();
3445e5dd7070Spatrick }
3446e5dd7070Spatrick
3447e5dd7070Spatrick namespace {
3448e5dd7070Spatrick /// A partial specialization whose template arguments have matched
3449e5dd7070Spatrick /// a given template-id.
3450e5dd7070Spatrick struct PartialSpecMatchResult {
3451e5dd7070Spatrick ClassTemplatePartialSpecializationDecl *Partial;
3452e5dd7070Spatrick TemplateArgumentList *Args;
3453e5dd7070Spatrick };
3454e5dd7070Spatrick }
3455e5dd7070Spatrick
usesPartialOrExplicitSpecialization(SourceLocation Loc,ClassTemplateSpecializationDecl * ClassTemplateSpec)3456e5dd7070Spatrick bool Sema::usesPartialOrExplicitSpecialization(
3457e5dd7070Spatrick SourceLocation Loc, ClassTemplateSpecializationDecl *ClassTemplateSpec) {
3458e5dd7070Spatrick if (ClassTemplateSpec->getTemplateSpecializationKind() ==
3459e5dd7070Spatrick TSK_ExplicitSpecialization)
3460e5dd7070Spatrick return true;
3461e5dd7070Spatrick
3462e5dd7070Spatrick SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs;
3463e5dd7070Spatrick ClassTemplateSpec->getSpecializedTemplate()
3464e5dd7070Spatrick ->getPartialSpecializations(PartialSpecs);
3465e5dd7070Spatrick for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I) {
3466e5dd7070Spatrick TemplateDeductionInfo Info(Loc);
3467e5dd7070Spatrick if (!DeduceTemplateArguments(PartialSpecs[I],
3468e5dd7070Spatrick ClassTemplateSpec->getTemplateArgs(), Info))
3469e5dd7070Spatrick return true;
3470e5dd7070Spatrick }
3471e5dd7070Spatrick
3472e5dd7070Spatrick return false;
3473e5dd7070Spatrick }
3474e5dd7070Spatrick
3475e5dd7070Spatrick /// Get the instantiation pattern to use to instantiate the definition of a
3476e5dd7070Spatrick /// given ClassTemplateSpecializationDecl (either the pattern of the primary
3477e5dd7070Spatrick /// template or of a partial specialization).
3478a9ac8606Spatrick static ActionResult<CXXRecordDecl *>
getPatternForClassTemplateSpecialization(Sema & S,SourceLocation PointOfInstantiation,ClassTemplateSpecializationDecl * ClassTemplateSpec,TemplateSpecializationKind TSK)3479e5dd7070Spatrick getPatternForClassTemplateSpecialization(
3480e5dd7070Spatrick Sema &S, SourceLocation PointOfInstantiation,
3481e5dd7070Spatrick ClassTemplateSpecializationDecl *ClassTemplateSpec,
3482a9ac8606Spatrick TemplateSpecializationKind TSK) {
3483e5dd7070Spatrick Sema::InstantiatingTemplate Inst(S, PointOfInstantiation, ClassTemplateSpec);
3484a9ac8606Spatrick if (Inst.isInvalid())
3485a9ac8606Spatrick return {/*Invalid=*/true};
3486a9ac8606Spatrick if (Inst.isAlreadyInstantiating())
3487a9ac8606Spatrick return {/*Invalid=*/false};
3488e5dd7070Spatrick
3489e5dd7070Spatrick llvm::PointerUnion<ClassTemplateDecl *,
3490e5dd7070Spatrick ClassTemplatePartialSpecializationDecl *>
3491e5dd7070Spatrick Specialized = ClassTemplateSpec->getSpecializedTemplateOrPartial();
3492e5dd7070Spatrick if (!Specialized.is<ClassTemplatePartialSpecializationDecl *>()) {
3493e5dd7070Spatrick // Find best matching specialization.
3494e5dd7070Spatrick ClassTemplateDecl *Template = ClassTemplateSpec->getSpecializedTemplate();
3495e5dd7070Spatrick
3496e5dd7070Spatrick // C++ [temp.class.spec.match]p1:
3497e5dd7070Spatrick // When a class template is used in a context that requires an
3498e5dd7070Spatrick // instantiation of the class, it is necessary to determine
3499e5dd7070Spatrick // whether the instantiation is to be generated using the primary
3500e5dd7070Spatrick // template or one of the partial specializations. This is done by
3501e5dd7070Spatrick // matching the template arguments of the class template
3502e5dd7070Spatrick // specialization with the template argument lists of the partial
3503e5dd7070Spatrick // specializations.
3504e5dd7070Spatrick typedef PartialSpecMatchResult MatchResult;
3505e5dd7070Spatrick SmallVector<MatchResult, 4> Matched;
3506e5dd7070Spatrick SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs;
3507e5dd7070Spatrick Template->getPartialSpecializations(PartialSpecs);
3508e5dd7070Spatrick TemplateSpecCandidateSet FailedCandidates(PointOfInstantiation);
3509e5dd7070Spatrick for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I) {
3510e5dd7070Spatrick ClassTemplatePartialSpecializationDecl *Partial = PartialSpecs[I];
3511e5dd7070Spatrick TemplateDeductionInfo Info(FailedCandidates.getLocation());
3512e5dd7070Spatrick if (Sema::TemplateDeductionResult Result = S.DeduceTemplateArguments(
3513e5dd7070Spatrick Partial, ClassTemplateSpec->getTemplateArgs(), Info)) {
3514e5dd7070Spatrick // Store the failed-deduction information for use in diagnostics, later.
3515e5dd7070Spatrick // TODO: Actually use the failed-deduction info?
3516e5dd7070Spatrick FailedCandidates.addCandidate().set(
3517e5dd7070Spatrick DeclAccessPair::make(Template, AS_public), Partial,
3518e5dd7070Spatrick MakeDeductionFailureInfo(S.Context, Result, Info));
3519e5dd7070Spatrick (void)Result;
3520e5dd7070Spatrick } else {
3521e5dd7070Spatrick Matched.push_back(PartialSpecMatchResult());
3522e5dd7070Spatrick Matched.back().Partial = Partial;
3523*12c85518Srobert Matched.back().Args = Info.takeCanonical();
3524e5dd7070Spatrick }
3525e5dd7070Spatrick }
3526e5dd7070Spatrick
3527e5dd7070Spatrick // If we're dealing with a member template where the template parameters
3528e5dd7070Spatrick // have been instantiated, this provides the original template parameters
3529e5dd7070Spatrick // from which the member template's parameters were instantiated.
3530e5dd7070Spatrick
3531e5dd7070Spatrick if (Matched.size() >= 1) {
3532e5dd7070Spatrick SmallVectorImpl<MatchResult>::iterator Best = Matched.begin();
3533e5dd7070Spatrick if (Matched.size() == 1) {
3534e5dd7070Spatrick // -- If exactly one matching specialization is found, the
3535e5dd7070Spatrick // instantiation is generated from that specialization.
3536e5dd7070Spatrick // We don't need to do anything for this.
3537e5dd7070Spatrick } else {
3538e5dd7070Spatrick // -- If more than one matching specialization is found, the
3539e5dd7070Spatrick // partial order rules (14.5.4.2) are used to determine
3540e5dd7070Spatrick // whether one of the specializations is more specialized
3541e5dd7070Spatrick // than the others. If none of the specializations is more
3542e5dd7070Spatrick // specialized than all of the other matching
3543e5dd7070Spatrick // specializations, then the use of the class template is
3544e5dd7070Spatrick // ambiguous and the program is ill-formed.
3545e5dd7070Spatrick for (SmallVectorImpl<MatchResult>::iterator P = Best + 1,
3546e5dd7070Spatrick PEnd = Matched.end();
3547e5dd7070Spatrick P != PEnd; ++P) {
3548e5dd7070Spatrick if (S.getMoreSpecializedPartialSpecialization(
3549e5dd7070Spatrick P->Partial, Best->Partial, PointOfInstantiation) ==
3550e5dd7070Spatrick P->Partial)
3551e5dd7070Spatrick Best = P;
3552e5dd7070Spatrick }
3553e5dd7070Spatrick
3554e5dd7070Spatrick // Determine if the best partial specialization is more specialized than
3555e5dd7070Spatrick // the others.
3556e5dd7070Spatrick bool Ambiguous = false;
3557e5dd7070Spatrick for (SmallVectorImpl<MatchResult>::iterator P = Matched.begin(),
3558e5dd7070Spatrick PEnd = Matched.end();
3559e5dd7070Spatrick P != PEnd; ++P) {
3560e5dd7070Spatrick if (P != Best && S.getMoreSpecializedPartialSpecialization(
3561e5dd7070Spatrick P->Partial, Best->Partial,
3562e5dd7070Spatrick PointOfInstantiation) != Best->Partial) {
3563e5dd7070Spatrick Ambiguous = true;
3564e5dd7070Spatrick break;
3565e5dd7070Spatrick }
3566e5dd7070Spatrick }
3567e5dd7070Spatrick
3568e5dd7070Spatrick if (Ambiguous) {
3569e5dd7070Spatrick // Partial ordering did not produce a clear winner. Complain.
3570e5dd7070Spatrick Inst.Clear();
3571e5dd7070Spatrick ClassTemplateSpec->setInvalidDecl();
3572e5dd7070Spatrick S.Diag(PointOfInstantiation,
3573e5dd7070Spatrick diag::err_partial_spec_ordering_ambiguous)
3574e5dd7070Spatrick << ClassTemplateSpec;
3575e5dd7070Spatrick
3576e5dd7070Spatrick // Print the matching partial specializations.
3577e5dd7070Spatrick for (SmallVectorImpl<MatchResult>::iterator P = Matched.begin(),
3578e5dd7070Spatrick PEnd = Matched.end();
3579e5dd7070Spatrick P != PEnd; ++P)
3580e5dd7070Spatrick S.Diag(P->Partial->getLocation(), diag::note_partial_spec_match)
3581e5dd7070Spatrick << S.getTemplateArgumentBindingsText(
3582e5dd7070Spatrick P->Partial->getTemplateParameters(), *P->Args);
3583e5dd7070Spatrick
3584a9ac8606Spatrick return {/*Invalid=*/true};
3585e5dd7070Spatrick }
3586e5dd7070Spatrick }
3587e5dd7070Spatrick
3588e5dd7070Spatrick ClassTemplateSpec->setInstantiationOf(Best->Partial, Best->Args);
3589e5dd7070Spatrick } else {
3590e5dd7070Spatrick // -- If no matches are found, the instantiation is generated
3591e5dd7070Spatrick // from the primary template.
3592e5dd7070Spatrick }
3593e5dd7070Spatrick }
3594e5dd7070Spatrick
3595e5dd7070Spatrick CXXRecordDecl *Pattern = nullptr;
3596e5dd7070Spatrick Specialized = ClassTemplateSpec->getSpecializedTemplateOrPartial();
3597e5dd7070Spatrick if (auto *PartialSpec =
3598e5dd7070Spatrick Specialized.dyn_cast<ClassTemplatePartialSpecializationDecl *>()) {
3599e5dd7070Spatrick // Instantiate using the best class template partial specialization.
3600e5dd7070Spatrick while (PartialSpec->getInstantiatedFromMember()) {
3601e5dd7070Spatrick // If we've found an explicit specialization of this class template,
3602e5dd7070Spatrick // stop here and use that as the pattern.
3603e5dd7070Spatrick if (PartialSpec->isMemberSpecialization())
3604e5dd7070Spatrick break;
3605e5dd7070Spatrick
3606e5dd7070Spatrick PartialSpec = PartialSpec->getInstantiatedFromMember();
3607e5dd7070Spatrick }
3608e5dd7070Spatrick Pattern = PartialSpec;
3609e5dd7070Spatrick } else {
3610e5dd7070Spatrick ClassTemplateDecl *Template = ClassTemplateSpec->getSpecializedTemplate();
3611e5dd7070Spatrick while (Template->getInstantiatedFromMemberTemplate()) {
3612e5dd7070Spatrick // If we've found an explicit specialization of this class template,
3613e5dd7070Spatrick // stop here and use that as the pattern.
3614e5dd7070Spatrick if (Template->isMemberSpecialization())
3615e5dd7070Spatrick break;
3616e5dd7070Spatrick
3617e5dd7070Spatrick Template = Template->getInstantiatedFromMemberTemplate();
3618e5dd7070Spatrick }
3619e5dd7070Spatrick Pattern = Template->getTemplatedDecl();
3620e5dd7070Spatrick }
3621e5dd7070Spatrick
3622e5dd7070Spatrick return Pattern;
3623e5dd7070Spatrick }
3624e5dd7070Spatrick
InstantiateClassTemplateSpecialization(SourceLocation PointOfInstantiation,ClassTemplateSpecializationDecl * ClassTemplateSpec,TemplateSpecializationKind TSK,bool Complain)3625e5dd7070Spatrick bool Sema::InstantiateClassTemplateSpecialization(
3626e5dd7070Spatrick SourceLocation PointOfInstantiation,
3627e5dd7070Spatrick ClassTemplateSpecializationDecl *ClassTemplateSpec,
3628e5dd7070Spatrick TemplateSpecializationKind TSK, bool Complain) {
3629e5dd7070Spatrick // Perform the actual instantiation on the canonical declaration.
3630e5dd7070Spatrick ClassTemplateSpec = cast<ClassTemplateSpecializationDecl>(
3631e5dd7070Spatrick ClassTemplateSpec->getCanonicalDecl());
3632e5dd7070Spatrick if (ClassTemplateSpec->isInvalidDecl())
3633e5dd7070Spatrick return true;
3634e5dd7070Spatrick
3635a9ac8606Spatrick ActionResult<CXXRecordDecl *> Pattern =
3636a9ac8606Spatrick getPatternForClassTemplateSpecialization(*this, PointOfInstantiation,
3637a9ac8606Spatrick ClassTemplateSpec, TSK);
3638a9ac8606Spatrick if (!Pattern.isUsable())
3639a9ac8606Spatrick return Pattern.isInvalid();
3640e5dd7070Spatrick
3641a9ac8606Spatrick return InstantiateClass(
3642a9ac8606Spatrick PointOfInstantiation, ClassTemplateSpec, Pattern.get(),
3643a9ac8606Spatrick getTemplateInstantiationArgs(ClassTemplateSpec), TSK, Complain);
3644e5dd7070Spatrick }
3645e5dd7070Spatrick
3646e5dd7070Spatrick /// Instantiates the definitions of all of the member
3647e5dd7070Spatrick /// of the given class, which is an instantiation of a class template
3648e5dd7070Spatrick /// or a member class of a template.
3649e5dd7070Spatrick void
InstantiateClassMembers(SourceLocation PointOfInstantiation,CXXRecordDecl * Instantiation,const MultiLevelTemplateArgumentList & TemplateArgs,TemplateSpecializationKind TSK)3650e5dd7070Spatrick Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
3651e5dd7070Spatrick CXXRecordDecl *Instantiation,
3652e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs,
3653e5dd7070Spatrick TemplateSpecializationKind TSK) {
3654e5dd7070Spatrick // FIXME: We need to notify the ASTMutationListener that we did all of these
3655e5dd7070Spatrick // things, in case we have an explicit instantiation definition in a PCM, a
3656e5dd7070Spatrick // module, or preamble, and the declaration is in an imported AST.
3657e5dd7070Spatrick assert(
3658e5dd7070Spatrick (TSK == TSK_ExplicitInstantiationDefinition ||
3659e5dd7070Spatrick TSK == TSK_ExplicitInstantiationDeclaration ||
3660e5dd7070Spatrick (TSK == TSK_ImplicitInstantiation && Instantiation->isLocalClass())) &&
3661e5dd7070Spatrick "Unexpected template specialization kind!");
3662e5dd7070Spatrick for (auto *D : Instantiation->decls()) {
3663e5dd7070Spatrick bool SuppressNew = false;
3664e5dd7070Spatrick if (auto *Function = dyn_cast<FunctionDecl>(D)) {
3665e5dd7070Spatrick if (FunctionDecl *Pattern =
3666e5dd7070Spatrick Function->getInstantiatedFromMemberFunction()) {
3667e5dd7070Spatrick
3668*12c85518Srobert if (Function->isIneligibleOrNotSelected())
3669*12c85518Srobert continue;
3670*12c85518Srobert
3671*12c85518Srobert if (Function->getTrailingRequiresClause()) {
3672*12c85518Srobert ConstraintSatisfaction Satisfaction;
3673*12c85518Srobert if (CheckFunctionConstraints(Function, Satisfaction) ||
3674*12c85518Srobert !Satisfaction.IsSatisfied) {
3675*12c85518Srobert continue;
3676*12c85518Srobert }
3677*12c85518Srobert }
3678*12c85518Srobert
3679e5dd7070Spatrick if (Function->hasAttr<ExcludeFromExplicitInstantiationAttr>())
3680e5dd7070Spatrick continue;
3681e5dd7070Spatrick
3682e5dd7070Spatrick MemberSpecializationInfo *MSInfo =
3683e5dd7070Spatrick Function->getMemberSpecializationInfo();
3684e5dd7070Spatrick assert(MSInfo && "No member specialization information?");
3685e5dd7070Spatrick if (MSInfo->getTemplateSpecializationKind()
3686e5dd7070Spatrick == TSK_ExplicitSpecialization)
3687e5dd7070Spatrick continue;
3688e5dd7070Spatrick
3689e5dd7070Spatrick if (CheckSpecializationInstantiationRedecl(PointOfInstantiation, TSK,
3690e5dd7070Spatrick Function,
3691e5dd7070Spatrick MSInfo->getTemplateSpecializationKind(),
3692e5dd7070Spatrick MSInfo->getPointOfInstantiation(),
3693e5dd7070Spatrick SuppressNew) ||
3694e5dd7070Spatrick SuppressNew)
3695e5dd7070Spatrick continue;
3696e5dd7070Spatrick
3697e5dd7070Spatrick // C++11 [temp.explicit]p8:
3698e5dd7070Spatrick // An explicit instantiation definition that names a class template
3699e5dd7070Spatrick // specialization explicitly instantiates the class template
3700e5dd7070Spatrick // specialization and is only an explicit instantiation definition
3701e5dd7070Spatrick // of members whose definition is visible at the point of
3702e5dd7070Spatrick // instantiation.
3703e5dd7070Spatrick if (TSK == TSK_ExplicitInstantiationDefinition && !Pattern->isDefined())
3704e5dd7070Spatrick continue;
3705e5dd7070Spatrick
3706e5dd7070Spatrick Function->setTemplateSpecializationKind(TSK, PointOfInstantiation);
3707e5dd7070Spatrick
3708e5dd7070Spatrick if (Function->isDefined()) {
3709e5dd7070Spatrick // Let the ASTConsumer know that this function has been explicitly
3710e5dd7070Spatrick // instantiated now, and its linkage might have changed.
3711e5dd7070Spatrick Consumer.HandleTopLevelDecl(DeclGroupRef(Function));
3712e5dd7070Spatrick } else if (TSK == TSK_ExplicitInstantiationDefinition) {
3713e5dd7070Spatrick InstantiateFunctionDefinition(PointOfInstantiation, Function);
3714e5dd7070Spatrick } else if (TSK == TSK_ImplicitInstantiation) {
3715e5dd7070Spatrick PendingLocalImplicitInstantiations.push_back(
3716e5dd7070Spatrick std::make_pair(Function, PointOfInstantiation));
3717e5dd7070Spatrick }
3718e5dd7070Spatrick }
3719e5dd7070Spatrick } else if (auto *Var = dyn_cast<VarDecl>(D)) {
3720e5dd7070Spatrick if (isa<VarTemplateSpecializationDecl>(Var))
3721e5dd7070Spatrick continue;
3722e5dd7070Spatrick
3723e5dd7070Spatrick if (Var->isStaticDataMember()) {
3724e5dd7070Spatrick if (Var->hasAttr<ExcludeFromExplicitInstantiationAttr>())
3725e5dd7070Spatrick continue;
3726e5dd7070Spatrick
3727e5dd7070Spatrick MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo();
3728e5dd7070Spatrick assert(MSInfo && "No member specialization information?");
3729e5dd7070Spatrick if (MSInfo->getTemplateSpecializationKind()
3730e5dd7070Spatrick == TSK_ExplicitSpecialization)
3731e5dd7070Spatrick continue;
3732e5dd7070Spatrick
3733e5dd7070Spatrick if (CheckSpecializationInstantiationRedecl(PointOfInstantiation, TSK,
3734e5dd7070Spatrick Var,
3735e5dd7070Spatrick MSInfo->getTemplateSpecializationKind(),
3736e5dd7070Spatrick MSInfo->getPointOfInstantiation(),
3737e5dd7070Spatrick SuppressNew) ||
3738e5dd7070Spatrick SuppressNew)
3739e5dd7070Spatrick continue;
3740e5dd7070Spatrick
3741e5dd7070Spatrick if (TSK == TSK_ExplicitInstantiationDefinition) {
3742e5dd7070Spatrick // C++0x [temp.explicit]p8:
3743e5dd7070Spatrick // An explicit instantiation definition that names a class template
3744e5dd7070Spatrick // specialization explicitly instantiates the class template
3745e5dd7070Spatrick // specialization and is only an explicit instantiation definition
3746e5dd7070Spatrick // of members whose definition is visible at the point of
3747e5dd7070Spatrick // instantiation.
3748e5dd7070Spatrick if (!Var->getInstantiatedFromStaticDataMember()->getDefinition())
3749e5dd7070Spatrick continue;
3750e5dd7070Spatrick
3751e5dd7070Spatrick Var->setTemplateSpecializationKind(TSK, PointOfInstantiation);
3752e5dd7070Spatrick InstantiateVariableDefinition(PointOfInstantiation, Var);
3753e5dd7070Spatrick } else {
3754e5dd7070Spatrick Var->setTemplateSpecializationKind(TSK, PointOfInstantiation);
3755e5dd7070Spatrick }
3756e5dd7070Spatrick }
3757e5dd7070Spatrick } else if (auto *Record = dyn_cast<CXXRecordDecl>(D)) {
3758e5dd7070Spatrick if (Record->hasAttr<ExcludeFromExplicitInstantiationAttr>())
3759e5dd7070Spatrick continue;
3760e5dd7070Spatrick
3761e5dd7070Spatrick // Always skip the injected-class-name, along with any
3762e5dd7070Spatrick // redeclarations of nested classes, since both would cause us
3763e5dd7070Spatrick // to try to instantiate the members of a class twice.
3764e5dd7070Spatrick // Skip closure types; they'll get instantiated when we instantiate
3765e5dd7070Spatrick // the corresponding lambda-expression.
3766e5dd7070Spatrick if (Record->isInjectedClassName() || Record->getPreviousDecl() ||
3767e5dd7070Spatrick Record->isLambda())
3768e5dd7070Spatrick continue;
3769e5dd7070Spatrick
3770e5dd7070Spatrick MemberSpecializationInfo *MSInfo = Record->getMemberSpecializationInfo();
3771e5dd7070Spatrick assert(MSInfo && "No member specialization information?");
3772e5dd7070Spatrick
3773e5dd7070Spatrick if (MSInfo->getTemplateSpecializationKind()
3774e5dd7070Spatrick == TSK_ExplicitSpecialization)
3775e5dd7070Spatrick continue;
3776e5dd7070Spatrick
3777e5dd7070Spatrick if (Context.getTargetInfo().getTriple().isOSWindows() &&
3778e5dd7070Spatrick TSK == TSK_ExplicitInstantiationDeclaration) {
3779e5dd7070Spatrick // On Windows, explicit instantiation decl of the outer class doesn't
3780e5dd7070Spatrick // affect the inner class. Typically extern template declarations are
3781e5dd7070Spatrick // used in combination with dll import/export annotations, but those
3782e5dd7070Spatrick // are not propagated from the outer class templates to inner classes.
3783e5dd7070Spatrick // Therefore, do not instantiate inner classes on this platform, so
3784e5dd7070Spatrick // that users don't end up with undefined symbols during linking.
3785e5dd7070Spatrick continue;
3786e5dd7070Spatrick }
3787e5dd7070Spatrick
3788e5dd7070Spatrick if (CheckSpecializationInstantiationRedecl(PointOfInstantiation, TSK,
3789e5dd7070Spatrick Record,
3790e5dd7070Spatrick MSInfo->getTemplateSpecializationKind(),
3791e5dd7070Spatrick MSInfo->getPointOfInstantiation(),
3792e5dd7070Spatrick SuppressNew) ||
3793e5dd7070Spatrick SuppressNew)
3794e5dd7070Spatrick continue;
3795e5dd7070Spatrick
3796e5dd7070Spatrick CXXRecordDecl *Pattern = Record->getInstantiatedFromMemberClass();
3797e5dd7070Spatrick assert(Pattern && "Missing instantiated-from-template information");
3798e5dd7070Spatrick
3799e5dd7070Spatrick if (!Record->getDefinition()) {
3800e5dd7070Spatrick if (!Pattern->getDefinition()) {
3801e5dd7070Spatrick // C++0x [temp.explicit]p8:
3802e5dd7070Spatrick // An explicit instantiation definition that names a class template
3803e5dd7070Spatrick // specialization explicitly instantiates the class template
3804e5dd7070Spatrick // specialization and is only an explicit instantiation definition
3805e5dd7070Spatrick // of members whose definition is visible at the point of
3806e5dd7070Spatrick // instantiation.
3807e5dd7070Spatrick if (TSK == TSK_ExplicitInstantiationDeclaration) {
3808e5dd7070Spatrick MSInfo->setTemplateSpecializationKind(TSK);
3809e5dd7070Spatrick MSInfo->setPointOfInstantiation(PointOfInstantiation);
3810e5dd7070Spatrick }
3811e5dd7070Spatrick
3812e5dd7070Spatrick continue;
3813e5dd7070Spatrick }
3814e5dd7070Spatrick
3815e5dd7070Spatrick InstantiateClass(PointOfInstantiation, Record, Pattern,
3816e5dd7070Spatrick TemplateArgs,
3817e5dd7070Spatrick TSK);
3818e5dd7070Spatrick } else {
3819e5dd7070Spatrick if (TSK == TSK_ExplicitInstantiationDefinition &&
3820e5dd7070Spatrick Record->getTemplateSpecializationKind() ==
3821e5dd7070Spatrick TSK_ExplicitInstantiationDeclaration) {
3822e5dd7070Spatrick Record->setTemplateSpecializationKind(TSK);
3823e5dd7070Spatrick MarkVTableUsed(PointOfInstantiation, Record, true);
3824e5dd7070Spatrick }
3825e5dd7070Spatrick }
3826e5dd7070Spatrick
3827e5dd7070Spatrick Pattern = cast_or_null<CXXRecordDecl>(Record->getDefinition());
3828e5dd7070Spatrick if (Pattern)
3829e5dd7070Spatrick InstantiateClassMembers(PointOfInstantiation, Pattern, TemplateArgs,
3830e5dd7070Spatrick TSK);
3831e5dd7070Spatrick } else if (auto *Enum = dyn_cast<EnumDecl>(D)) {
3832e5dd7070Spatrick MemberSpecializationInfo *MSInfo = Enum->getMemberSpecializationInfo();
3833e5dd7070Spatrick assert(MSInfo && "No member specialization information?");
3834e5dd7070Spatrick
3835e5dd7070Spatrick if (MSInfo->getTemplateSpecializationKind()
3836e5dd7070Spatrick == TSK_ExplicitSpecialization)
3837e5dd7070Spatrick continue;
3838e5dd7070Spatrick
3839e5dd7070Spatrick if (CheckSpecializationInstantiationRedecl(
3840e5dd7070Spatrick PointOfInstantiation, TSK, Enum,
3841e5dd7070Spatrick MSInfo->getTemplateSpecializationKind(),
3842e5dd7070Spatrick MSInfo->getPointOfInstantiation(), SuppressNew) ||
3843e5dd7070Spatrick SuppressNew)
3844e5dd7070Spatrick continue;
3845e5dd7070Spatrick
3846e5dd7070Spatrick if (Enum->getDefinition())
3847e5dd7070Spatrick continue;
3848e5dd7070Spatrick
3849e5dd7070Spatrick EnumDecl *Pattern = Enum->getTemplateInstantiationPattern();
3850e5dd7070Spatrick assert(Pattern && "Missing instantiated-from-template information");
3851e5dd7070Spatrick
3852e5dd7070Spatrick if (TSK == TSK_ExplicitInstantiationDefinition) {
3853e5dd7070Spatrick if (!Pattern->getDefinition())
3854e5dd7070Spatrick continue;
3855e5dd7070Spatrick
3856e5dd7070Spatrick InstantiateEnum(PointOfInstantiation, Enum, Pattern, TemplateArgs, TSK);
3857e5dd7070Spatrick } else {
3858e5dd7070Spatrick MSInfo->setTemplateSpecializationKind(TSK);
3859e5dd7070Spatrick MSInfo->setPointOfInstantiation(PointOfInstantiation);
3860e5dd7070Spatrick }
3861e5dd7070Spatrick } else if (auto *Field = dyn_cast<FieldDecl>(D)) {
3862e5dd7070Spatrick // No need to instantiate in-class initializers during explicit
3863e5dd7070Spatrick // instantiation.
3864e5dd7070Spatrick if (Field->hasInClassInitializer() && TSK == TSK_ImplicitInstantiation) {
3865e5dd7070Spatrick CXXRecordDecl *ClassPattern =
3866e5dd7070Spatrick Instantiation->getTemplateInstantiationPattern();
3867e5dd7070Spatrick DeclContext::lookup_result Lookup =
3868e5dd7070Spatrick ClassPattern->lookup(Field->getDeclName());
3869a9ac8606Spatrick FieldDecl *Pattern = Lookup.find_first<FieldDecl>();
3870a9ac8606Spatrick assert(Pattern);
3871e5dd7070Spatrick InstantiateInClassInitializer(PointOfInstantiation, Field, Pattern,
3872e5dd7070Spatrick TemplateArgs);
3873e5dd7070Spatrick }
3874e5dd7070Spatrick }
3875e5dd7070Spatrick }
3876e5dd7070Spatrick }
3877e5dd7070Spatrick
3878e5dd7070Spatrick /// Instantiate the definitions of all of the members of the
3879e5dd7070Spatrick /// given class template specialization, which was named as part of an
3880e5dd7070Spatrick /// explicit instantiation.
3881e5dd7070Spatrick void
InstantiateClassTemplateSpecializationMembers(SourceLocation PointOfInstantiation,ClassTemplateSpecializationDecl * ClassTemplateSpec,TemplateSpecializationKind TSK)3882e5dd7070Spatrick Sema::InstantiateClassTemplateSpecializationMembers(
3883e5dd7070Spatrick SourceLocation PointOfInstantiation,
3884e5dd7070Spatrick ClassTemplateSpecializationDecl *ClassTemplateSpec,
3885e5dd7070Spatrick TemplateSpecializationKind TSK) {
3886e5dd7070Spatrick // C++0x [temp.explicit]p7:
3887e5dd7070Spatrick // An explicit instantiation that names a class template
3888e5dd7070Spatrick // specialization is an explicit instantion of the same kind
3889e5dd7070Spatrick // (declaration or definition) of each of its members (not
3890e5dd7070Spatrick // including members inherited from base classes) that has not
3891e5dd7070Spatrick // been previously explicitly specialized in the translation unit
3892e5dd7070Spatrick // containing the explicit instantiation, except as described
3893e5dd7070Spatrick // below.
3894e5dd7070Spatrick InstantiateClassMembers(PointOfInstantiation, ClassTemplateSpec,
3895e5dd7070Spatrick getTemplateInstantiationArgs(ClassTemplateSpec),
3896e5dd7070Spatrick TSK);
3897e5dd7070Spatrick }
3898e5dd7070Spatrick
3899e5dd7070Spatrick StmtResult
SubstStmt(Stmt * S,const MultiLevelTemplateArgumentList & TemplateArgs)3900e5dd7070Spatrick Sema::SubstStmt(Stmt *S, const MultiLevelTemplateArgumentList &TemplateArgs) {
3901e5dd7070Spatrick if (!S)
3902e5dd7070Spatrick return S;
3903e5dd7070Spatrick
3904e5dd7070Spatrick TemplateInstantiator Instantiator(*this, TemplateArgs,
3905e5dd7070Spatrick SourceLocation(),
3906e5dd7070Spatrick DeclarationName());
3907e5dd7070Spatrick return Instantiator.TransformStmt(S);
3908e5dd7070Spatrick }
3909e5dd7070Spatrick
SubstTemplateArguments(ArrayRef<TemplateArgumentLoc> Args,const MultiLevelTemplateArgumentList & TemplateArgs,TemplateArgumentListInfo & Out)3910e5dd7070Spatrick bool Sema::SubstTemplateArguments(
3911e5dd7070Spatrick ArrayRef<TemplateArgumentLoc> Args,
3912e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs,
3913e5dd7070Spatrick TemplateArgumentListInfo &Out) {
3914*12c85518Srobert TemplateInstantiator Instantiator(*this, TemplateArgs, SourceLocation(),
3915e5dd7070Spatrick DeclarationName());
3916*12c85518Srobert return Instantiator.TransformTemplateArguments(Args.begin(), Args.end(), Out);
3917e5dd7070Spatrick }
3918e5dd7070Spatrick
3919e5dd7070Spatrick ExprResult
SubstExpr(Expr * E,const MultiLevelTemplateArgumentList & TemplateArgs)3920e5dd7070Spatrick Sema::SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs) {
3921e5dd7070Spatrick if (!E)
3922e5dd7070Spatrick return E;
3923e5dd7070Spatrick
3924e5dd7070Spatrick TemplateInstantiator Instantiator(*this, TemplateArgs,
3925e5dd7070Spatrick SourceLocation(),
3926e5dd7070Spatrick DeclarationName());
3927e5dd7070Spatrick return Instantiator.TransformExpr(E);
3928e5dd7070Spatrick }
3929e5dd7070Spatrick
3930*12c85518Srobert ExprResult
SubstConstraintExpr(Expr * E,const MultiLevelTemplateArgumentList & TemplateArgs)3931*12c85518Srobert Sema::SubstConstraintExpr(Expr *E,
3932*12c85518Srobert const MultiLevelTemplateArgumentList &TemplateArgs) {
3933*12c85518Srobert if (!E)
3934*12c85518Srobert return E;
3935*12c85518Srobert
3936*12c85518Srobert // This is where we need to make sure we 'know' constraint checking needs to
3937*12c85518Srobert // happen.
3938*12c85518Srobert TemplateInstantiator Instantiator(*this, TemplateArgs, SourceLocation(),
3939*12c85518Srobert DeclarationName());
3940*12c85518Srobert return Instantiator.TransformExpr(E);
3941*12c85518Srobert }
3942*12c85518Srobert
SubstInitializer(Expr * Init,const MultiLevelTemplateArgumentList & TemplateArgs,bool CXXDirectInit)3943e5dd7070Spatrick ExprResult Sema::SubstInitializer(Expr *Init,
3944e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs,
3945e5dd7070Spatrick bool CXXDirectInit) {
3946*12c85518Srobert TemplateInstantiator Instantiator(*this, TemplateArgs, SourceLocation(),
3947e5dd7070Spatrick DeclarationName());
3948e5dd7070Spatrick return Instantiator.TransformInitializer(Init, CXXDirectInit);
3949e5dd7070Spatrick }
3950e5dd7070Spatrick
SubstExprs(ArrayRef<Expr * > Exprs,bool IsCall,const MultiLevelTemplateArgumentList & TemplateArgs,SmallVectorImpl<Expr * > & Outputs)3951e5dd7070Spatrick bool Sema::SubstExprs(ArrayRef<Expr *> Exprs, bool IsCall,
3952e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs,
3953e5dd7070Spatrick SmallVectorImpl<Expr *> &Outputs) {
3954e5dd7070Spatrick if (Exprs.empty())
3955e5dd7070Spatrick return false;
3956e5dd7070Spatrick
3957e5dd7070Spatrick TemplateInstantiator Instantiator(*this, TemplateArgs,
3958e5dd7070Spatrick SourceLocation(),
3959e5dd7070Spatrick DeclarationName());
3960e5dd7070Spatrick return Instantiator.TransformExprs(Exprs.data(), Exprs.size(),
3961e5dd7070Spatrick IsCall, Outputs);
3962e5dd7070Spatrick }
3963e5dd7070Spatrick
3964e5dd7070Spatrick NestedNameSpecifierLoc
SubstNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,const MultiLevelTemplateArgumentList & TemplateArgs)3965e5dd7070Spatrick Sema::SubstNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
3966e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs) {
3967e5dd7070Spatrick if (!NNS)
3968e5dd7070Spatrick return NestedNameSpecifierLoc();
3969e5dd7070Spatrick
3970e5dd7070Spatrick TemplateInstantiator Instantiator(*this, TemplateArgs, NNS.getBeginLoc(),
3971e5dd7070Spatrick DeclarationName());
3972e5dd7070Spatrick return Instantiator.TransformNestedNameSpecifierLoc(NNS);
3973e5dd7070Spatrick }
3974e5dd7070Spatrick
3975e5dd7070Spatrick /// Do template substitution on declaration name info.
3976e5dd7070Spatrick DeclarationNameInfo
SubstDeclarationNameInfo(const DeclarationNameInfo & NameInfo,const MultiLevelTemplateArgumentList & TemplateArgs)3977e5dd7070Spatrick Sema::SubstDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
3978e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs) {
3979e5dd7070Spatrick TemplateInstantiator Instantiator(*this, TemplateArgs, NameInfo.getLoc(),
3980e5dd7070Spatrick NameInfo.getName());
3981e5dd7070Spatrick return Instantiator.TransformDeclarationNameInfo(NameInfo);
3982e5dd7070Spatrick }
3983e5dd7070Spatrick
3984e5dd7070Spatrick TemplateName
SubstTemplateName(NestedNameSpecifierLoc QualifierLoc,TemplateName Name,SourceLocation Loc,const MultiLevelTemplateArgumentList & TemplateArgs)3985e5dd7070Spatrick Sema::SubstTemplateName(NestedNameSpecifierLoc QualifierLoc,
3986e5dd7070Spatrick TemplateName Name, SourceLocation Loc,
3987e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs) {
3988e5dd7070Spatrick TemplateInstantiator Instantiator(*this, TemplateArgs, Loc,
3989e5dd7070Spatrick DeclarationName());
3990e5dd7070Spatrick CXXScopeSpec SS;
3991e5dd7070Spatrick SS.Adopt(QualifierLoc);
3992e5dd7070Spatrick return Instantiator.TransformTemplateName(SS, Name, Loc);
3993e5dd7070Spatrick }
3994e5dd7070Spatrick
getCanonicalParmVarDecl(const Decl * D)3995e5dd7070Spatrick static const Decl *getCanonicalParmVarDecl(const Decl *D) {
3996e5dd7070Spatrick // When storing ParmVarDecls in the local instantiation scope, we always
3997e5dd7070Spatrick // want to use the ParmVarDecl from the canonical function declaration,
3998e5dd7070Spatrick // since the map is then valid for any redeclaration or definition of that
3999e5dd7070Spatrick // function.
4000e5dd7070Spatrick if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(D)) {
4001e5dd7070Spatrick if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
4002e5dd7070Spatrick unsigned i = PV->getFunctionScopeIndex();
4003e5dd7070Spatrick // This parameter might be from a freestanding function type within the
4004e5dd7070Spatrick // function and isn't necessarily referring to one of FD's parameters.
4005e5dd7070Spatrick if (i < FD->getNumParams() && FD->getParamDecl(i) == PV)
4006e5dd7070Spatrick return FD->getCanonicalDecl()->getParamDecl(i);
4007e5dd7070Spatrick }
4008e5dd7070Spatrick }
4009e5dd7070Spatrick return D;
4010e5dd7070Spatrick }
4011e5dd7070Spatrick
4012e5dd7070Spatrick
4013e5dd7070Spatrick llvm::PointerUnion<Decl *, LocalInstantiationScope::DeclArgumentPack *> *
findInstantiationOf(const Decl * D)4014e5dd7070Spatrick LocalInstantiationScope::findInstantiationOf(const Decl *D) {
4015e5dd7070Spatrick D = getCanonicalParmVarDecl(D);
4016e5dd7070Spatrick for (LocalInstantiationScope *Current = this; Current;
4017e5dd7070Spatrick Current = Current->Outer) {
4018e5dd7070Spatrick
4019e5dd7070Spatrick // Check if we found something within this scope.
4020e5dd7070Spatrick const Decl *CheckD = D;
4021e5dd7070Spatrick do {
4022e5dd7070Spatrick LocalDeclsMap::iterator Found = Current->LocalDecls.find(CheckD);
4023e5dd7070Spatrick if (Found != Current->LocalDecls.end())
4024e5dd7070Spatrick return &Found->second;
4025e5dd7070Spatrick
4026e5dd7070Spatrick // If this is a tag declaration, it's possible that we need to look for
4027e5dd7070Spatrick // a previous declaration.
4028e5dd7070Spatrick if (const TagDecl *Tag = dyn_cast<TagDecl>(CheckD))
4029e5dd7070Spatrick CheckD = Tag->getPreviousDecl();
4030e5dd7070Spatrick else
4031e5dd7070Spatrick CheckD = nullptr;
4032e5dd7070Spatrick } while (CheckD);
4033e5dd7070Spatrick
4034e5dd7070Spatrick // If we aren't combined with our outer scope, we're done.
4035e5dd7070Spatrick if (!Current->CombineWithOuterScope)
4036e5dd7070Spatrick break;
4037e5dd7070Spatrick }
4038e5dd7070Spatrick
4039e5dd7070Spatrick // If we're performing a partial substitution during template argument
4040e5dd7070Spatrick // deduction, we may not have values for template parameters yet.
4041e5dd7070Spatrick if (isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D) ||
4042e5dd7070Spatrick isa<TemplateTemplateParmDecl>(D))
4043e5dd7070Spatrick return nullptr;
4044e5dd7070Spatrick
4045e5dd7070Spatrick // Local types referenced prior to definition may require instantiation.
4046e5dd7070Spatrick if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
4047e5dd7070Spatrick if (RD->isLocalClass())
4048e5dd7070Spatrick return nullptr;
4049e5dd7070Spatrick
4050e5dd7070Spatrick // Enumeration types referenced prior to definition may appear as a result of
4051e5dd7070Spatrick // error recovery.
4052e5dd7070Spatrick if (isa<EnumDecl>(D))
4053e5dd7070Spatrick return nullptr;
4054e5dd7070Spatrick
4055ec727ea7Spatrick // Materialized typedefs/type alias for implicit deduction guides may require
4056ec727ea7Spatrick // instantiation.
4057ec727ea7Spatrick if (isa<TypedefNameDecl>(D) &&
4058ec727ea7Spatrick isa<CXXDeductionGuideDecl>(D->getDeclContext()))
4059ec727ea7Spatrick return nullptr;
4060ec727ea7Spatrick
4061e5dd7070Spatrick // If we didn't find the decl, then we either have a sema bug, or we have a
4062e5dd7070Spatrick // forward reference to a label declaration. Return null to indicate that
4063e5dd7070Spatrick // we have an uninstantiated label.
4064e5dd7070Spatrick assert(isa<LabelDecl>(D) && "declaration not instantiated in this scope");
4065e5dd7070Spatrick return nullptr;
4066e5dd7070Spatrick }
4067e5dd7070Spatrick
InstantiatedLocal(const Decl * D,Decl * Inst)4068e5dd7070Spatrick void LocalInstantiationScope::InstantiatedLocal(const Decl *D, Decl *Inst) {
4069e5dd7070Spatrick D = getCanonicalParmVarDecl(D);
4070e5dd7070Spatrick llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored = LocalDecls[D];
4071e5dd7070Spatrick if (Stored.isNull()) {
4072e5dd7070Spatrick #ifndef NDEBUG
4073e5dd7070Spatrick // It should not be present in any surrounding scope either.
4074e5dd7070Spatrick LocalInstantiationScope *Current = this;
4075e5dd7070Spatrick while (Current->CombineWithOuterScope && Current->Outer) {
4076e5dd7070Spatrick Current = Current->Outer;
4077e5dd7070Spatrick assert(Current->LocalDecls.find(D) == Current->LocalDecls.end() &&
4078e5dd7070Spatrick "Instantiated local in inner and outer scopes");
4079e5dd7070Spatrick }
4080e5dd7070Spatrick #endif
4081e5dd7070Spatrick Stored = Inst;
4082e5dd7070Spatrick } else if (DeclArgumentPack *Pack = Stored.dyn_cast<DeclArgumentPack *>()) {
4083e5dd7070Spatrick Pack->push_back(cast<VarDecl>(Inst));
4084e5dd7070Spatrick } else {
4085e5dd7070Spatrick assert(Stored.get<Decl *>() == Inst && "Already instantiated this local");
4086e5dd7070Spatrick }
4087e5dd7070Spatrick }
4088e5dd7070Spatrick
InstantiatedLocalPackArg(const Decl * D,VarDecl * Inst)4089e5dd7070Spatrick void LocalInstantiationScope::InstantiatedLocalPackArg(const Decl *D,
4090e5dd7070Spatrick VarDecl *Inst) {
4091e5dd7070Spatrick D = getCanonicalParmVarDecl(D);
4092e5dd7070Spatrick DeclArgumentPack *Pack = LocalDecls[D].get<DeclArgumentPack *>();
4093e5dd7070Spatrick Pack->push_back(Inst);
4094e5dd7070Spatrick }
4095e5dd7070Spatrick
MakeInstantiatedLocalArgPack(const Decl * D)4096e5dd7070Spatrick void LocalInstantiationScope::MakeInstantiatedLocalArgPack(const Decl *D) {
4097e5dd7070Spatrick #ifndef NDEBUG
4098e5dd7070Spatrick // This should be the first time we've been told about this decl.
4099e5dd7070Spatrick for (LocalInstantiationScope *Current = this;
4100e5dd7070Spatrick Current && Current->CombineWithOuterScope; Current = Current->Outer)
4101e5dd7070Spatrick assert(Current->LocalDecls.find(D) == Current->LocalDecls.end() &&
4102e5dd7070Spatrick "Creating local pack after instantiation of local");
4103e5dd7070Spatrick #endif
4104e5dd7070Spatrick
4105e5dd7070Spatrick D = getCanonicalParmVarDecl(D);
4106e5dd7070Spatrick llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored = LocalDecls[D];
4107e5dd7070Spatrick DeclArgumentPack *Pack = new DeclArgumentPack;
4108e5dd7070Spatrick Stored = Pack;
4109e5dd7070Spatrick ArgumentPacks.push_back(Pack);
4110e5dd7070Spatrick }
4111e5dd7070Spatrick
isLocalPackExpansion(const Decl * D)4112ec727ea7Spatrick bool LocalInstantiationScope::isLocalPackExpansion(const Decl *D) {
4113ec727ea7Spatrick for (DeclArgumentPack *Pack : ArgumentPacks)
4114*12c85518Srobert if (llvm::is_contained(*Pack, D))
4115ec727ea7Spatrick return true;
4116ec727ea7Spatrick return false;
4117ec727ea7Spatrick }
4118ec727ea7Spatrick
SetPartiallySubstitutedPack(NamedDecl * Pack,const TemplateArgument * ExplicitArgs,unsigned NumExplicitArgs)4119e5dd7070Spatrick void LocalInstantiationScope::SetPartiallySubstitutedPack(NamedDecl *Pack,
4120e5dd7070Spatrick const TemplateArgument *ExplicitArgs,
4121e5dd7070Spatrick unsigned NumExplicitArgs) {
4122e5dd7070Spatrick assert((!PartiallySubstitutedPack || PartiallySubstitutedPack == Pack) &&
4123e5dd7070Spatrick "Already have a partially-substituted pack");
4124e5dd7070Spatrick assert((!PartiallySubstitutedPack
4125e5dd7070Spatrick || NumArgsInPartiallySubstitutedPack == NumExplicitArgs) &&
4126e5dd7070Spatrick "Wrong number of arguments in partially-substituted pack");
4127e5dd7070Spatrick PartiallySubstitutedPack = Pack;
4128e5dd7070Spatrick ArgsInPartiallySubstitutedPack = ExplicitArgs;
4129e5dd7070Spatrick NumArgsInPartiallySubstitutedPack = NumExplicitArgs;
4130e5dd7070Spatrick }
4131e5dd7070Spatrick
getPartiallySubstitutedPack(const TemplateArgument ** ExplicitArgs,unsigned * NumExplicitArgs) const4132e5dd7070Spatrick NamedDecl *LocalInstantiationScope::getPartiallySubstitutedPack(
4133e5dd7070Spatrick const TemplateArgument **ExplicitArgs,
4134e5dd7070Spatrick unsigned *NumExplicitArgs) const {
4135e5dd7070Spatrick if (ExplicitArgs)
4136e5dd7070Spatrick *ExplicitArgs = nullptr;
4137e5dd7070Spatrick if (NumExplicitArgs)
4138e5dd7070Spatrick *NumExplicitArgs = 0;
4139e5dd7070Spatrick
4140e5dd7070Spatrick for (const LocalInstantiationScope *Current = this; Current;
4141e5dd7070Spatrick Current = Current->Outer) {
4142e5dd7070Spatrick if (Current->PartiallySubstitutedPack) {
4143e5dd7070Spatrick if (ExplicitArgs)
4144e5dd7070Spatrick *ExplicitArgs = Current->ArgsInPartiallySubstitutedPack;
4145e5dd7070Spatrick if (NumExplicitArgs)
4146e5dd7070Spatrick *NumExplicitArgs = Current->NumArgsInPartiallySubstitutedPack;
4147e5dd7070Spatrick
4148e5dd7070Spatrick return Current->PartiallySubstitutedPack;
4149e5dd7070Spatrick }
4150e5dd7070Spatrick
4151e5dd7070Spatrick if (!Current->CombineWithOuterScope)
4152e5dd7070Spatrick break;
4153e5dd7070Spatrick }
4154e5dd7070Spatrick
4155e5dd7070Spatrick return nullptr;
4156e5dd7070Spatrick }
4157