1e5dd7070Spatrick //===--- SemaTemplateInstantiateDecl.cpp - C++ Template Decl 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 for declarations.
9e5dd7070Spatrick //
10e5dd7070Spatrick //===----------------------------------------------------------------------===/
11ec727ea7Spatrick
12a9ac8606Spatrick #include "TreeTransform.h"
13e5dd7070Spatrick #include "clang/AST/ASTConsumer.h"
14e5dd7070Spatrick #include "clang/AST/ASTContext.h"
15e5dd7070Spatrick #include "clang/AST/ASTMutationListener.h"
16e5dd7070Spatrick #include "clang/AST/DeclTemplate.h"
17e5dd7070Spatrick #include "clang/AST/DeclVisitor.h"
18e5dd7070Spatrick #include "clang/AST/DependentDiagnostic.h"
19e5dd7070Spatrick #include "clang/AST/Expr.h"
20e5dd7070Spatrick #include "clang/AST/ExprCXX.h"
21e5dd7070Spatrick #include "clang/AST/PrettyDeclStackTrace.h"
22e5dd7070Spatrick #include "clang/AST/TypeLoc.h"
23ec727ea7Spatrick #include "clang/Basic/SourceManager.h"
24ec727ea7Spatrick #include "clang/Basic/TargetInfo.h"
25e5dd7070Spatrick #include "clang/Sema/Initialization.h"
26e5dd7070Spatrick #include "clang/Sema/Lookup.h"
27a9ac8606Spatrick #include "clang/Sema/ScopeInfo.h"
28ec727ea7Spatrick #include "clang/Sema/SemaInternal.h"
29e5dd7070Spatrick #include "clang/Sema/Template.h"
30e5dd7070Spatrick #include "clang/Sema/TemplateInstCallback.h"
31e5dd7070Spatrick #include "llvm/Support/TimeProfiler.h"
32*12c85518Srobert #include <optional>
33e5dd7070Spatrick
34e5dd7070Spatrick using namespace clang;
35e5dd7070Spatrick
isDeclWithinFunction(const Decl * D)36e5dd7070Spatrick static bool isDeclWithinFunction(const Decl *D) {
37e5dd7070Spatrick const DeclContext *DC = D->getDeclContext();
38e5dd7070Spatrick if (DC->isFunctionOrMethod())
39e5dd7070Spatrick return true;
40e5dd7070Spatrick
41e5dd7070Spatrick if (DC->isRecord())
42e5dd7070Spatrick return cast<CXXRecordDecl>(DC)->isLocalClass();
43e5dd7070Spatrick
44e5dd7070Spatrick return false;
45e5dd7070Spatrick }
46e5dd7070Spatrick
47e5dd7070Spatrick template<typename DeclT>
SubstQualifier(Sema & SemaRef,const DeclT * OldDecl,DeclT * NewDecl,const MultiLevelTemplateArgumentList & TemplateArgs)48e5dd7070Spatrick static bool SubstQualifier(Sema &SemaRef, const DeclT *OldDecl, DeclT *NewDecl,
49e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs) {
50e5dd7070Spatrick if (!OldDecl->getQualifierLoc())
51e5dd7070Spatrick return false;
52e5dd7070Spatrick
53e5dd7070Spatrick assert((NewDecl->getFriendObjectKind() ||
54e5dd7070Spatrick !OldDecl->getLexicalDeclContext()->isDependentContext()) &&
55e5dd7070Spatrick "non-friend with qualified name defined in dependent context");
56e5dd7070Spatrick Sema::ContextRAII SavedContext(
57e5dd7070Spatrick SemaRef,
58e5dd7070Spatrick const_cast<DeclContext *>(NewDecl->getFriendObjectKind()
59e5dd7070Spatrick ? NewDecl->getLexicalDeclContext()
60e5dd7070Spatrick : OldDecl->getLexicalDeclContext()));
61e5dd7070Spatrick
62e5dd7070Spatrick NestedNameSpecifierLoc NewQualifierLoc
63e5dd7070Spatrick = SemaRef.SubstNestedNameSpecifierLoc(OldDecl->getQualifierLoc(),
64e5dd7070Spatrick TemplateArgs);
65e5dd7070Spatrick
66e5dd7070Spatrick if (!NewQualifierLoc)
67e5dd7070Spatrick return true;
68e5dd7070Spatrick
69e5dd7070Spatrick NewDecl->setQualifierInfo(NewQualifierLoc);
70e5dd7070Spatrick return false;
71e5dd7070Spatrick }
72e5dd7070Spatrick
SubstQualifier(const DeclaratorDecl * OldDecl,DeclaratorDecl * NewDecl)73e5dd7070Spatrick bool TemplateDeclInstantiator::SubstQualifier(const DeclaratorDecl *OldDecl,
74e5dd7070Spatrick DeclaratorDecl *NewDecl) {
75e5dd7070Spatrick return ::SubstQualifier(SemaRef, OldDecl, NewDecl, TemplateArgs);
76e5dd7070Spatrick }
77e5dd7070Spatrick
SubstQualifier(const TagDecl * OldDecl,TagDecl * NewDecl)78e5dd7070Spatrick bool TemplateDeclInstantiator::SubstQualifier(const TagDecl *OldDecl,
79e5dd7070Spatrick TagDecl *NewDecl) {
80e5dd7070Spatrick return ::SubstQualifier(SemaRef, OldDecl, NewDecl, TemplateArgs);
81e5dd7070Spatrick }
82e5dd7070Spatrick
83e5dd7070Spatrick // Include attribute instantiation code.
84e5dd7070Spatrick #include "clang/Sema/AttrTemplateInstantiate.inc"
85e5dd7070Spatrick
instantiateDependentAlignedAttr(Sema & S,const MultiLevelTemplateArgumentList & TemplateArgs,const AlignedAttr * Aligned,Decl * New,bool IsPackExpansion)86e5dd7070Spatrick static void instantiateDependentAlignedAttr(
87e5dd7070Spatrick Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
88e5dd7070Spatrick const AlignedAttr *Aligned, Decl *New, bool IsPackExpansion) {
89e5dd7070Spatrick if (Aligned->isAlignmentExpr()) {
90e5dd7070Spatrick // The alignment expression is a constant expression.
91e5dd7070Spatrick EnterExpressionEvaluationContext Unevaluated(
92e5dd7070Spatrick S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
93e5dd7070Spatrick ExprResult Result = S.SubstExpr(Aligned->getAlignmentExpr(), TemplateArgs);
94e5dd7070Spatrick if (!Result.isInvalid())
95e5dd7070Spatrick S.AddAlignedAttr(New, *Aligned, Result.getAs<Expr>(), IsPackExpansion);
96e5dd7070Spatrick } else {
97e5dd7070Spatrick TypeSourceInfo *Result = S.SubstType(Aligned->getAlignmentType(),
98e5dd7070Spatrick TemplateArgs, Aligned->getLocation(),
99e5dd7070Spatrick DeclarationName());
100e5dd7070Spatrick if (Result)
101e5dd7070Spatrick S.AddAlignedAttr(New, *Aligned, Result, IsPackExpansion);
102e5dd7070Spatrick }
103e5dd7070Spatrick }
104e5dd7070Spatrick
instantiateDependentAlignedAttr(Sema & S,const MultiLevelTemplateArgumentList & TemplateArgs,const AlignedAttr * Aligned,Decl * New)105e5dd7070Spatrick static void instantiateDependentAlignedAttr(
106e5dd7070Spatrick Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
107e5dd7070Spatrick const AlignedAttr *Aligned, Decl *New) {
108e5dd7070Spatrick if (!Aligned->isPackExpansion()) {
109e5dd7070Spatrick instantiateDependentAlignedAttr(S, TemplateArgs, Aligned, New, false);
110e5dd7070Spatrick return;
111e5dd7070Spatrick }
112e5dd7070Spatrick
113e5dd7070Spatrick SmallVector<UnexpandedParameterPack, 2> Unexpanded;
114e5dd7070Spatrick if (Aligned->isAlignmentExpr())
115e5dd7070Spatrick S.collectUnexpandedParameterPacks(Aligned->getAlignmentExpr(),
116e5dd7070Spatrick Unexpanded);
117e5dd7070Spatrick else
118e5dd7070Spatrick S.collectUnexpandedParameterPacks(Aligned->getAlignmentType()->getTypeLoc(),
119e5dd7070Spatrick Unexpanded);
120e5dd7070Spatrick assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
121e5dd7070Spatrick
122e5dd7070Spatrick // Determine whether we can expand this attribute pack yet.
123e5dd7070Spatrick bool Expand = true, RetainExpansion = false;
124*12c85518Srobert std::optional<unsigned> NumExpansions;
125e5dd7070Spatrick // FIXME: Use the actual location of the ellipsis.
126e5dd7070Spatrick SourceLocation EllipsisLoc = Aligned->getLocation();
127e5dd7070Spatrick if (S.CheckParameterPacksForExpansion(EllipsisLoc, Aligned->getRange(),
128e5dd7070Spatrick Unexpanded, TemplateArgs, Expand,
129e5dd7070Spatrick RetainExpansion, NumExpansions))
130e5dd7070Spatrick return;
131e5dd7070Spatrick
132e5dd7070Spatrick if (!Expand) {
133e5dd7070Spatrick Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(S, -1);
134e5dd7070Spatrick instantiateDependentAlignedAttr(S, TemplateArgs, Aligned, New, true);
135e5dd7070Spatrick } else {
136e5dd7070Spatrick for (unsigned I = 0; I != *NumExpansions; ++I) {
137e5dd7070Spatrick Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(S, I);
138e5dd7070Spatrick instantiateDependentAlignedAttr(S, TemplateArgs, Aligned, New, false);
139e5dd7070Spatrick }
140e5dd7070Spatrick }
141e5dd7070Spatrick }
142e5dd7070Spatrick
instantiateDependentAssumeAlignedAttr(Sema & S,const MultiLevelTemplateArgumentList & TemplateArgs,const AssumeAlignedAttr * Aligned,Decl * New)143e5dd7070Spatrick static void instantiateDependentAssumeAlignedAttr(
144e5dd7070Spatrick Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
145e5dd7070Spatrick const AssumeAlignedAttr *Aligned, Decl *New) {
146e5dd7070Spatrick // The alignment expression is a constant expression.
147e5dd7070Spatrick EnterExpressionEvaluationContext Unevaluated(
148e5dd7070Spatrick S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
149e5dd7070Spatrick
150e5dd7070Spatrick Expr *E, *OE = nullptr;
151e5dd7070Spatrick ExprResult Result = S.SubstExpr(Aligned->getAlignment(), TemplateArgs);
152e5dd7070Spatrick if (Result.isInvalid())
153e5dd7070Spatrick return;
154e5dd7070Spatrick E = Result.getAs<Expr>();
155e5dd7070Spatrick
156e5dd7070Spatrick if (Aligned->getOffset()) {
157e5dd7070Spatrick Result = S.SubstExpr(Aligned->getOffset(), TemplateArgs);
158e5dd7070Spatrick if (Result.isInvalid())
159e5dd7070Spatrick return;
160e5dd7070Spatrick OE = Result.getAs<Expr>();
161e5dd7070Spatrick }
162e5dd7070Spatrick
163e5dd7070Spatrick S.AddAssumeAlignedAttr(New, *Aligned, E, OE);
164e5dd7070Spatrick }
165e5dd7070Spatrick
instantiateDependentAlignValueAttr(Sema & S,const MultiLevelTemplateArgumentList & TemplateArgs,const AlignValueAttr * Aligned,Decl * New)166e5dd7070Spatrick static void instantiateDependentAlignValueAttr(
167e5dd7070Spatrick Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
168e5dd7070Spatrick const AlignValueAttr *Aligned, Decl *New) {
169e5dd7070Spatrick // The alignment expression is a constant expression.
170e5dd7070Spatrick EnterExpressionEvaluationContext Unevaluated(
171e5dd7070Spatrick S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
172e5dd7070Spatrick ExprResult Result = S.SubstExpr(Aligned->getAlignment(), TemplateArgs);
173e5dd7070Spatrick if (!Result.isInvalid())
174e5dd7070Spatrick S.AddAlignValueAttr(New, *Aligned, Result.getAs<Expr>());
175e5dd7070Spatrick }
176e5dd7070Spatrick
instantiateDependentAllocAlignAttr(Sema & S,const MultiLevelTemplateArgumentList & TemplateArgs,const AllocAlignAttr * Align,Decl * New)177e5dd7070Spatrick static void instantiateDependentAllocAlignAttr(
178e5dd7070Spatrick Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
179e5dd7070Spatrick const AllocAlignAttr *Align, Decl *New) {
180e5dd7070Spatrick Expr *Param = IntegerLiteral::Create(
181e5dd7070Spatrick S.getASTContext(),
182e5dd7070Spatrick llvm::APInt(64, Align->getParamIndex().getSourceIndex()),
183e5dd7070Spatrick S.getASTContext().UnsignedLongLongTy, Align->getLocation());
184e5dd7070Spatrick S.AddAllocAlignAttr(New, *Align, Param);
185e5dd7070Spatrick }
186e5dd7070Spatrick
instantiateDependentAnnotationAttr(Sema & S,const MultiLevelTemplateArgumentList & TemplateArgs,const AnnotateAttr * Attr,Decl * New)187a9ac8606Spatrick static void instantiateDependentAnnotationAttr(
188a9ac8606Spatrick Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
189a9ac8606Spatrick const AnnotateAttr *Attr, Decl *New) {
190a9ac8606Spatrick EnterExpressionEvaluationContext Unevaluated(
191a9ac8606Spatrick S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
192*12c85518Srobert
193*12c85518Srobert // If the attribute has delayed arguments it will have to instantiate those
194*12c85518Srobert // and handle them as new arguments for the attribute.
195*12c85518Srobert bool HasDelayedArgs = Attr->delayedArgs_size();
196*12c85518Srobert
197*12c85518Srobert ArrayRef<Expr *> ArgsToInstantiate =
198*12c85518Srobert HasDelayedArgs
199*12c85518Srobert ? ArrayRef<Expr *>{Attr->delayedArgs_begin(), Attr->delayedArgs_end()}
200*12c85518Srobert : ArrayRef<Expr *>{Attr->args_begin(), Attr->args_end()};
201*12c85518Srobert
202a9ac8606Spatrick SmallVector<Expr *, 4> Args;
203*12c85518Srobert if (S.SubstExprs(ArgsToInstantiate,
204*12c85518Srobert /*IsCall=*/false, TemplateArgs, Args))
205a9ac8606Spatrick return;
206*12c85518Srobert
207*12c85518Srobert StringRef Str = Attr->getAnnotation();
208*12c85518Srobert if (HasDelayedArgs) {
209*12c85518Srobert if (Args.size() < 1) {
210*12c85518Srobert S.Diag(Attr->getLoc(), diag::err_attribute_too_few_arguments)
211*12c85518Srobert << Attr << 1;
212*12c85518Srobert return;
213a9ac8606Spatrick }
214*12c85518Srobert
215*12c85518Srobert if (!S.checkStringLiteralArgumentAttr(*Attr, Args[0], Str))
216*12c85518Srobert return;
217*12c85518Srobert
218*12c85518Srobert llvm::SmallVector<Expr *, 4> ActualArgs;
219*12c85518Srobert ActualArgs.insert(ActualArgs.begin(), Args.begin() + 1, Args.end());
220*12c85518Srobert std::swap(Args, ActualArgs);
221*12c85518Srobert }
222*12c85518Srobert S.AddAnnotationAttr(New, *Attr, Str, Args);
223a9ac8606Spatrick }
224a9ac8606Spatrick
instantiateDependentFunctionAttrCondition(Sema & S,const MultiLevelTemplateArgumentList & TemplateArgs,const Attr * A,Expr * OldCond,const Decl * Tmpl,FunctionDecl * New)225e5dd7070Spatrick static Expr *instantiateDependentFunctionAttrCondition(
226e5dd7070Spatrick Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
227e5dd7070Spatrick const Attr *A, Expr *OldCond, const Decl *Tmpl, FunctionDecl *New) {
228e5dd7070Spatrick Expr *Cond = nullptr;
229e5dd7070Spatrick {
230e5dd7070Spatrick Sema::ContextRAII SwitchContext(S, New);
231e5dd7070Spatrick EnterExpressionEvaluationContext Unevaluated(
232e5dd7070Spatrick S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
233e5dd7070Spatrick ExprResult Result = S.SubstExpr(OldCond, TemplateArgs);
234e5dd7070Spatrick if (Result.isInvalid())
235e5dd7070Spatrick return nullptr;
236e5dd7070Spatrick Cond = Result.getAs<Expr>();
237e5dd7070Spatrick }
238e5dd7070Spatrick if (!Cond->isTypeDependent()) {
239e5dd7070Spatrick ExprResult Converted = S.PerformContextuallyConvertToBool(Cond);
240e5dd7070Spatrick if (Converted.isInvalid())
241e5dd7070Spatrick return nullptr;
242e5dd7070Spatrick Cond = Converted.get();
243e5dd7070Spatrick }
244e5dd7070Spatrick
245e5dd7070Spatrick SmallVector<PartialDiagnosticAt, 8> Diags;
246e5dd7070Spatrick if (OldCond->isValueDependent() && !Cond->isValueDependent() &&
247e5dd7070Spatrick !Expr::isPotentialConstantExprUnevaluated(Cond, New, Diags)) {
248e5dd7070Spatrick S.Diag(A->getLocation(), diag::err_attr_cond_never_constant_expr) << A;
249e5dd7070Spatrick for (const auto &P : Diags)
250e5dd7070Spatrick S.Diag(P.first, P.second);
251e5dd7070Spatrick return nullptr;
252e5dd7070Spatrick }
253e5dd7070Spatrick return Cond;
254e5dd7070Spatrick }
255e5dd7070Spatrick
instantiateDependentEnableIfAttr(Sema & S,const MultiLevelTemplateArgumentList & TemplateArgs,const EnableIfAttr * EIA,const Decl * Tmpl,FunctionDecl * New)256e5dd7070Spatrick static void instantiateDependentEnableIfAttr(
257e5dd7070Spatrick Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
258e5dd7070Spatrick const EnableIfAttr *EIA, const Decl *Tmpl, FunctionDecl *New) {
259e5dd7070Spatrick Expr *Cond = instantiateDependentFunctionAttrCondition(
260e5dd7070Spatrick S, TemplateArgs, EIA, EIA->getCond(), Tmpl, New);
261e5dd7070Spatrick
262e5dd7070Spatrick if (Cond)
263e5dd7070Spatrick New->addAttr(new (S.getASTContext()) EnableIfAttr(S.getASTContext(), *EIA,
264e5dd7070Spatrick Cond, EIA->getMessage()));
265e5dd7070Spatrick }
266e5dd7070Spatrick
instantiateDependentDiagnoseIfAttr(Sema & S,const MultiLevelTemplateArgumentList & TemplateArgs,const DiagnoseIfAttr * DIA,const Decl * Tmpl,FunctionDecl * New)267e5dd7070Spatrick static void instantiateDependentDiagnoseIfAttr(
268e5dd7070Spatrick Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
269e5dd7070Spatrick const DiagnoseIfAttr *DIA, const Decl *Tmpl, FunctionDecl *New) {
270e5dd7070Spatrick Expr *Cond = instantiateDependentFunctionAttrCondition(
271e5dd7070Spatrick S, TemplateArgs, DIA, DIA->getCond(), Tmpl, New);
272e5dd7070Spatrick
273e5dd7070Spatrick if (Cond)
274e5dd7070Spatrick New->addAttr(new (S.getASTContext()) DiagnoseIfAttr(
275e5dd7070Spatrick S.getASTContext(), *DIA, Cond, DIA->getMessage(),
276e5dd7070Spatrick DIA->getDiagnosticType(), DIA->getArgDependent(), New));
277e5dd7070Spatrick }
278e5dd7070Spatrick
279e5dd7070Spatrick // Constructs and adds to New a new instance of CUDALaunchBoundsAttr using
280e5dd7070Spatrick // template A as the base and arguments from TemplateArgs.
instantiateDependentCUDALaunchBoundsAttr(Sema & S,const MultiLevelTemplateArgumentList & TemplateArgs,const CUDALaunchBoundsAttr & Attr,Decl * New)281e5dd7070Spatrick static void instantiateDependentCUDALaunchBoundsAttr(
282e5dd7070Spatrick Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
283e5dd7070Spatrick const CUDALaunchBoundsAttr &Attr, Decl *New) {
284e5dd7070Spatrick // The alignment expression is a constant expression.
285e5dd7070Spatrick EnterExpressionEvaluationContext Unevaluated(
286e5dd7070Spatrick S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
287e5dd7070Spatrick
288e5dd7070Spatrick ExprResult Result = S.SubstExpr(Attr.getMaxThreads(), TemplateArgs);
289e5dd7070Spatrick if (Result.isInvalid())
290e5dd7070Spatrick return;
291e5dd7070Spatrick Expr *MaxThreads = Result.getAs<Expr>();
292e5dd7070Spatrick
293e5dd7070Spatrick Expr *MinBlocks = nullptr;
294e5dd7070Spatrick if (Attr.getMinBlocks()) {
295e5dd7070Spatrick Result = S.SubstExpr(Attr.getMinBlocks(), TemplateArgs);
296e5dd7070Spatrick if (Result.isInvalid())
297e5dd7070Spatrick return;
298e5dd7070Spatrick MinBlocks = Result.getAs<Expr>();
299e5dd7070Spatrick }
300e5dd7070Spatrick
301e5dd7070Spatrick S.AddLaunchBoundsAttr(New, Attr, MaxThreads, MinBlocks);
302e5dd7070Spatrick }
303e5dd7070Spatrick
304e5dd7070Spatrick static void
instantiateDependentModeAttr(Sema & S,const MultiLevelTemplateArgumentList & TemplateArgs,const ModeAttr & Attr,Decl * New)305e5dd7070Spatrick instantiateDependentModeAttr(Sema &S,
306e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs,
307e5dd7070Spatrick const ModeAttr &Attr, Decl *New) {
308e5dd7070Spatrick S.AddModeAttr(New, Attr, Attr.getMode(),
309e5dd7070Spatrick /*InInstantiation=*/true);
310e5dd7070Spatrick }
311e5dd7070Spatrick
312e5dd7070Spatrick /// Instantiation of 'declare simd' attribute and its arguments.
instantiateOMPDeclareSimdDeclAttr(Sema & S,const MultiLevelTemplateArgumentList & TemplateArgs,const OMPDeclareSimdDeclAttr & Attr,Decl * New)313e5dd7070Spatrick static void instantiateOMPDeclareSimdDeclAttr(
314e5dd7070Spatrick Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
315e5dd7070Spatrick const OMPDeclareSimdDeclAttr &Attr, Decl *New) {
316e5dd7070Spatrick // Allow 'this' in clauses with varlists.
317e5dd7070Spatrick if (auto *FTD = dyn_cast<FunctionTemplateDecl>(New))
318e5dd7070Spatrick New = FTD->getTemplatedDecl();
319e5dd7070Spatrick auto *FD = cast<FunctionDecl>(New);
320e5dd7070Spatrick auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(FD->getDeclContext());
321e5dd7070Spatrick SmallVector<Expr *, 4> Uniforms, Aligneds, Alignments, Linears, Steps;
322e5dd7070Spatrick SmallVector<unsigned, 4> LinModifiers;
323e5dd7070Spatrick
324e5dd7070Spatrick auto SubstExpr = [&](Expr *E) -> ExprResult {
325e5dd7070Spatrick if (auto *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))
326e5dd7070Spatrick if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
327e5dd7070Spatrick Sema::ContextRAII SavedContext(S, FD);
328e5dd7070Spatrick LocalInstantiationScope Local(S);
329e5dd7070Spatrick if (FD->getNumParams() > PVD->getFunctionScopeIndex())
330e5dd7070Spatrick Local.InstantiatedLocal(
331e5dd7070Spatrick PVD, FD->getParamDecl(PVD->getFunctionScopeIndex()));
332e5dd7070Spatrick return S.SubstExpr(E, TemplateArgs);
333e5dd7070Spatrick }
334e5dd7070Spatrick Sema::CXXThisScopeRAII ThisScope(S, ThisContext, Qualifiers(),
335e5dd7070Spatrick FD->isCXXInstanceMember());
336e5dd7070Spatrick return S.SubstExpr(E, TemplateArgs);
337e5dd7070Spatrick };
338e5dd7070Spatrick
339e5dd7070Spatrick // Substitute a single OpenMP clause, which is a potentially-evaluated
340e5dd7070Spatrick // full-expression.
341e5dd7070Spatrick auto Subst = [&](Expr *E) -> ExprResult {
342e5dd7070Spatrick EnterExpressionEvaluationContext Evaluated(
343e5dd7070Spatrick S, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
344e5dd7070Spatrick ExprResult Res = SubstExpr(E);
345e5dd7070Spatrick if (Res.isInvalid())
346e5dd7070Spatrick return Res;
347e5dd7070Spatrick return S.ActOnFinishFullExpr(Res.get(), false);
348e5dd7070Spatrick };
349e5dd7070Spatrick
350e5dd7070Spatrick ExprResult Simdlen;
351e5dd7070Spatrick if (auto *E = Attr.getSimdlen())
352e5dd7070Spatrick Simdlen = Subst(E);
353e5dd7070Spatrick
354e5dd7070Spatrick if (Attr.uniforms_size() > 0) {
355e5dd7070Spatrick for(auto *E : Attr.uniforms()) {
356e5dd7070Spatrick ExprResult Inst = Subst(E);
357e5dd7070Spatrick if (Inst.isInvalid())
358e5dd7070Spatrick continue;
359e5dd7070Spatrick Uniforms.push_back(Inst.get());
360e5dd7070Spatrick }
361e5dd7070Spatrick }
362e5dd7070Spatrick
363e5dd7070Spatrick auto AI = Attr.alignments_begin();
364e5dd7070Spatrick for (auto *E : Attr.aligneds()) {
365e5dd7070Spatrick ExprResult Inst = Subst(E);
366e5dd7070Spatrick if (Inst.isInvalid())
367e5dd7070Spatrick continue;
368e5dd7070Spatrick Aligneds.push_back(Inst.get());
369e5dd7070Spatrick Inst = ExprEmpty();
370e5dd7070Spatrick if (*AI)
371e5dd7070Spatrick Inst = S.SubstExpr(*AI, TemplateArgs);
372e5dd7070Spatrick Alignments.push_back(Inst.get());
373e5dd7070Spatrick ++AI;
374e5dd7070Spatrick }
375e5dd7070Spatrick
376e5dd7070Spatrick auto SI = Attr.steps_begin();
377e5dd7070Spatrick for (auto *E : Attr.linears()) {
378e5dd7070Spatrick ExprResult Inst = Subst(E);
379e5dd7070Spatrick if (Inst.isInvalid())
380e5dd7070Spatrick continue;
381e5dd7070Spatrick Linears.push_back(Inst.get());
382e5dd7070Spatrick Inst = ExprEmpty();
383e5dd7070Spatrick if (*SI)
384e5dd7070Spatrick Inst = S.SubstExpr(*SI, TemplateArgs);
385e5dd7070Spatrick Steps.push_back(Inst.get());
386e5dd7070Spatrick ++SI;
387e5dd7070Spatrick }
388e5dd7070Spatrick LinModifiers.append(Attr.modifiers_begin(), Attr.modifiers_end());
389e5dd7070Spatrick (void)S.ActOnOpenMPDeclareSimdDirective(
390e5dd7070Spatrick S.ConvertDeclToDeclGroup(New), Attr.getBranchState(), Simdlen.get(),
391e5dd7070Spatrick Uniforms, Aligneds, Alignments, Linears, LinModifiers, Steps,
392e5dd7070Spatrick Attr.getRange());
393e5dd7070Spatrick }
394e5dd7070Spatrick
395e5dd7070Spatrick /// Instantiation of 'declare variant' attribute and its arguments.
instantiateOMPDeclareVariantAttr(Sema & S,const MultiLevelTemplateArgumentList & TemplateArgs,const OMPDeclareVariantAttr & Attr,Decl * New)396e5dd7070Spatrick static void instantiateOMPDeclareVariantAttr(
397e5dd7070Spatrick Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
398e5dd7070Spatrick const OMPDeclareVariantAttr &Attr, Decl *New) {
399e5dd7070Spatrick // Allow 'this' in clauses with varlists.
400e5dd7070Spatrick if (auto *FTD = dyn_cast<FunctionTemplateDecl>(New))
401e5dd7070Spatrick New = FTD->getTemplatedDecl();
402e5dd7070Spatrick auto *FD = cast<FunctionDecl>(New);
403e5dd7070Spatrick auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(FD->getDeclContext());
404e5dd7070Spatrick
405e5dd7070Spatrick auto &&SubstExpr = [FD, ThisContext, &S, &TemplateArgs](Expr *E) {
406e5dd7070Spatrick if (auto *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))
407e5dd7070Spatrick if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
408e5dd7070Spatrick Sema::ContextRAII SavedContext(S, FD);
409e5dd7070Spatrick LocalInstantiationScope Local(S);
410e5dd7070Spatrick if (FD->getNumParams() > PVD->getFunctionScopeIndex())
411e5dd7070Spatrick Local.InstantiatedLocal(
412e5dd7070Spatrick PVD, FD->getParamDecl(PVD->getFunctionScopeIndex()));
413e5dd7070Spatrick return S.SubstExpr(E, TemplateArgs);
414e5dd7070Spatrick }
415e5dd7070Spatrick Sema::CXXThisScopeRAII ThisScope(S, ThisContext, Qualifiers(),
416e5dd7070Spatrick FD->isCXXInstanceMember());
417e5dd7070Spatrick return S.SubstExpr(E, TemplateArgs);
418e5dd7070Spatrick };
419e5dd7070Spatrick
420e5dd7070Spatrick // Substitute a single OpenMP clause, which is a potentially-evaluated
421e5dd7070Spatrick // full-expression.
422e5dd7070Spatrick auto &&Subst = [&SubstExpr, &S](Expr *E) {
423e5dd7070Spatrick EnterExpressionEvaluationContext Evaluated(
424e5dd7070Spatrick S, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
425e5dd7070Spatrick ExprResult Res = SubstExpr(E);
426e5dd7070Spatrick if (Res.isInvalid())
427e5dd7070Spatrick return Res;
428e5dd7070Spatrick return S.ActOnFinishFullExpr(Res.get(), false);
429e5dd7070Spatrick };
430e5dd7070Spatrick
431e5dd7070Spatrick ExprResult VariantFuncRef;
432e5dd7070Spatrick if (Expr *E = Attr.getVariantFuncRef()) {
433e5dd7070Spatrick // Do not mark function as is used to prevent its emission if this is the
434e5dd7070Spatrick // only place where it is used.
435e5dd7070Spatrick EnterExpressionEvaluationContext Unevaluated(
436e5dd7070Spatrick S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
437e5dd7070Spatrick VariantFuncRef = Subst(E);
438e5dd7070Spatrick }
439e5dd7070Spatrick
440ec727ea7Spatrick // Copy the template version of the OMPTraitInfo and run substitute on all
441ec727ea7Spatrick // score and condition expressiosn.
442ec727ea7Spatrick OMPTraitInfo &TI = S.getASTContext().getNewOMPTraitInfo();
443ec727ea7Spatrick TI = *Attr.getTraitInfos();
444ec727ea7Spatrick
445ec727ea7Spatrick // Try to substitute template parameters in score and condition expressions.
446ec727ea7Spatrick auto SubstScoreOrConditionExpr = [&S, Subst](Expr *&E, bool) {
447ec727ea7Spatrick if (E) {
448ec727ea7Spatrick EnterExpressionEvaluationContext Unevaluated(
449ec727ea7Spatrick S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
450ec727ea7Spatrick ExprResult ER = Subst(E);
451ec727ea7Spatrick if (ER.isUsable())
452ec727ea7Spatrick E = ER.get();
453ec727ea7Spatrick else
454ec727ea7Spatrick return true;
455ec727ea7Spatrick }
456ec727ea7Spatrick return false;
457ec727ea7Spatrick };
458ec727ea7Spatrick if (TI.anyScoreOrCondition(SubstScoreOrConditionExpr))
459ec727ea7Spatrick return;
460ec727ea7Spatrick
461a9ac8606Spatrick Expr *E = VariantFuncRef.get();
462*12c85518Srobert
463a9ac8606Spatrick // Check function/variant ref for `omp declare variant` but not for `omp
464a9ac8606Spatrick // begin declare variant` (which use implicit attributes).
465*12c85518Srobert std::optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
466*12c85518Srobert S.checkOpenMPDeclareVariantFunction(S.ConvertDeclToDeclGroup(New), E, TI,
467*12c85518Srobert Attr.appendArgs_size(),
468ec727ea7Spatrick Attr.getRange());
469ec727ea7Spatrick
470e5dd7070Spatrick if (!DeclVarData)
471e5dd7070Spatrick return;
472ec727ea7Spatrick
473*12c85518Srobert E = DeclVarData->second;
474*12c85518Srobert FD = DeclVarData->first;
475a9ac8606Spatrick
476a9ac8606Spatrick if (auto *VariantDRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts())) {
477a9ac8606Spatrick if (auto *VariantFD = dyn_cast<FunctionDecl>(VariantDRE->getDecl())) {
478a9ac8606Spatrick if (auto *VariantFTD = VariantFD->getDescribedFunctionTemplate()) {
479a9ac8606Spatrick if (!VariantFTD->isThisDeclarationADefinition())
480a9ac8606Spatrick return;
481a9ac8606Spatrick Sema::TentativeAnalysisScope Trap(S);
482a9ac8606Spatrick const TemplateArgumentList *TAL = TemplateArgumentList::CreateCopy(
483a9ac8606Spatrick S.Context, TemplateArgs.getInnermost());
484a9ac8606Spatrick
485a9ac8606Spatrick auto *SubstFD = S.InstantiateFunctionDeclaration(VariantFTD, TAL,
486a9ac8606Spatrick New->getLocation());
487a9ac8606Spatrick if (!SubstFD)
488a9ac8606Spatrick return;
489a9ac8606Spatrick QualType NewType = S.Context.mergeFunctionTypes(
490a9ac8606Spatrick SubstFD->getType(), FD->getType(),
491a9ac8606Spatrick /* OfBlockPointer */ false,
492a9ac8606Spatrick /* Unqualified */ false, /* AllowCXX */ true);
493a9ac8606Spatrick if (NewType.isNull())
494a9ac8606Spatrick return;
495a9ac8606Spatrick S.InstantiateFunctionDefinition(
496a9ac8606Spatrick New->getLocation(), SubstFD, /* Recursive */ true,
497a9ac8606Spatrick /* DefinitionRequired */ false, /* AtEndOfTU */ false);
498a9ac8606Spatrick SubstFD->setInstantiationIsPending(!SubstFD->isDefined());
499a9ac8606Spatrick E = DeclRefExpr::Create(S.Context, NestedNameSpecifierLoc(),
500a9ac8606Spatrick SourceLocation(), SubstFD,
501a9ac8606Spatrick /* RefersToEnclosingVariableOrCapture */ false,
502a9ac8606Spatrick /* NameLoc */ SubstFD->getLocation(),
503a9ac8606Spatrick SubstFD->getType(), ExprValueKind::VK_PRValue);
504a9ac8606Spatrick }
505a9ac8606Spatrick }
506a9ac8606Spatrick }
507a9ac8606Spatrick
508*12c85518Srobert SmallVector<Expr *, 8> NothingExprs;
509*12c85518Srobert SmallVector<Expr *, 8> NeedDevicePtrExprs;
510*12c85518Srobert SmallVector<OMPInteropInfo, 4> AppendArgs;
511*12c85518Srobert
512*12c85518Srobert for (Expr *E : Attr.adjustArgsNothing()) {
513*12c85518Srobert ExprResult ER = Subst(E);
514*12c85518Srobert if (ER.isInvalid())
515*12c85518Srobert continue;
516*12c85518Srobert NothingExprs.push_back(ER.get());
517*12c85518Srobert }
518*12c85518Srobert for (Expr *E : Attr.adjustArgsNeedDevicePtr()) {
519*12c85518Srobert ExprResult ER = Subst(E);
520*12c85518Srobert if (ER.isInvalid())
521*12c85518Srobert continue;
522*12c85518Srobert NeedDevicePtrExprs.push_back(ER.get());
523*12c85518Srobert }
524*12c85518Srobert for (OMPInteropInfo &II : Attr.appendArgs()) {
525*12c85518Srobert // When prefer_type is implemented for append_args handle them here too.
526*12c85518Srobert AppendArgs.emplace_back(II.IsTarget, II.IsTargetSync);
527*12c85518Srobert }
528*12c85518Srobert
529*12c85518Srobert S.ActOnOpenMPDeclareVariantDirective(
530*12c85518Srobert FD, E, TI, NothingExprs, NeedDevicePtrExprs, AppendArgs, SourceLocation(),
531*12c85518Srobert SourceLocation(), Attr.getRange());
532e5dd7070Spatrick }
533e5dd7070Spatrick
instantiateDependentAMDGPUFlatWorkGroupSizeAttr(Sema & S,const MultiLevelTemplateArgumentList & TemplateArgs,const AMDGPUFlatWorkGroupSizeAttr & Attr,Decl * New)534e5dd7070Spatrick static void instantiateDependentAMDGPUFlatWorkGroupSizeAttr(
535e5dd7070Spatrick Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
536e5dd7070Spatrick const AMDGPUFlatWorkGroupSizeAttr &Attr, Decl *New) {
537e5dd7070Spatrick // Both min and max expression are constant expressions.
538e5dd7070Spatrick EnterExpressionEvaluationContext Unevaluated(
539e5dd7070Spatrick S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
540e5dd7070Spatrick
541e5dd7070Spatrick ExprResult Result = S.SubstExpr(Attr.getMin(), TemplateArgs);
542e5dd7070Spatrick if (Result.isInvalid())
543e5dd7070Spatrick return;
544e5dd7070Spatrick Expr *MinExpr = Result.getAs<Expr>();
545e5dd7070Spatrick
546e5dd7070Spatrick Result = S.SubstExpr(Attr.getMax(), TemplateArgs);
547e5dd7070Spatrick if (Result.isInvalid())
548e5dd7070Spatrick return;
549e5dd7070Spatrick Expr *MaxExpr = Result.getAs<Expr>();
550e5dd7070Spatrick
551e5dd7070Spatrick S.addAMDGPUFlatWorkGroupSizeAttr(New, Attr, MinExpr, MaxExpr);
552e5dd7070Spatrick }
553e5dd7070Spatrick
554e5dd7070Spatrick static ExplicitSpecifier
instantiateExplicitSpecifier(Sema & S,const MultiLevelTemplateArgumentList & TemplateArgs,ExplicitSpecifier ES,FunctionDecl * New)555e5dd7070Spatrick instantiateExplicitSpecifier(Sema &S,
556e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs,
557e5dd7070Spatrick ExplicitSpecifier ES, FunctionDecl *New) {
558e5dd7070Spatrick if (!ES.getExpr())
559e5dd7070Spatrick return ES;
560e5dd7070Spatrick Expr *OldCond = ES.getExpr();
561e5dd7070Spatrick Expr *Cond = nullptr;
562e5dd7070Spatrick {
563e5dd7070Spatrick EnterExpressionEvaluationContext Unevaluated(
564e5dd7070Spatrick S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
565e5dd7070Spatrick ExprResult SubstResult = S.SubstExpr(OldCond, TemplateArgs);
566e5dd7070Spatrick if (SubstResult.isInvalid()) {
567e5dd7070Spatrick return ExplicitSpecifier::Invalid();
568e5dd7070Spatrick }
569e5dd7070Spatrick Cond = SubstResult.get();
570e5dd7070Spatrick }
571e5dd7070Spatrick ExplicitSpecifier Result(Cond, ES.getKind());
572e5dd7070Spatrick if (!Cond->isTypeDependent())
573e5dd7070Spatrick S.tryResolveExplicitSpecifier(Result);
574e5dd7070Spatrick return Result;
575e5dd7070Spatrick }
576e5dd7070Spatrick
instantiateDependentAMDGPUWavesPerEUAttr(Sema & S,const MultiLevelTemplateArgumentList & TemplateArgs,const AMDGPUWavesPerEUAttr & Attr,Decl * New)577e5dd7070Spatrick static void instantiateDependentAMDGPUWavesPerEUAttr(
578e5dd7070Spatrick Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
579e5dd7070Spatrick const AMDGPUWavesPerEUAttr &Attr, Decl *New) {
580e5dd7070Spatrick // Both min and max expression are constant expressions.
581e5dd7070Spatrick EnterExpressionEvaluationContext Unevaluated(
582e5dd7070Spatrick S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
583e5dd7070Spatrick
584e5dd7070Spatrick ExprResult Result = S.SubstExpr(Attr.getMin(), TemplateArgs);
585e5dd7070Spatrick if (Result.isInvalid())
586e5dd7070Spatrick return;
587e5dd7070Spatrick Expr *MinExpr = Result.getAs<Expr>();
588e5dd7070Spatrick
589e5dd7070Spatrick Expr *MaxExpr = nullptr;
590e5dd7070Spatrick if (auto Max = Attr.getMax()) {
591e5dd7070Spatrick Result = S.SubstExpr(Max, TemplateArgs);
592e5dd7070Spatrick if (Result.isInvalid())
593e5dd7070Spatrick return;
594e5dd7070Spatrick MaxExpr = Result.getAs<Expr>();
595e5dd7070Spatrick }
596e5dd7070Spatrick
597e5dd7070Spatrick S.addAMDGPUWavesPerEUAttr(New, Attr, MinExpr, MaxExpr);
598e5dd7070Spatrick }
599e5dd7070Spatrick
600a9ac8606Spatrick // This doesn't take any template parameters, but we have a custom action that
601a9ac8606Spatrick // needs to happen when the kernel itself is instantiated. We need to run the
602a9ac8606Spatrick // ItaniumMangler to mark the names required to name this kernel.
instantiateDependentSYCLKernelAttr(Sema & S,const MultiLevelTemplateArgumentList & TemplateArgs,const SYCLKernelAttr & Attr,Decl * New)603a9ac8606Spatrick static void instantiateDependentSYCLKernelAttr(
604a9ac8606Spatrick Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
605a9ac8606Spatrick const SYCLKernelAttr &Attr, Decl *New) {
606a9ac8606Spatrick New->addAttr(Attr.clone(S.getASTContext()));
607a9ac8606Spatrick }
608a9ac8606Spatrick
609*12c85518Srobert /// Determine whether the attribute A might be relevant to the declaration D.
610a9ac8606Spatrick /// If not, we can skip instantiating it. The attribute may or may not have
611a9ac8606Spatrick /// been instantiated yet.
isRelevantAttr(Sema & S,const Decl * D,const Attr * A)612a9ac8606Spatrick static bool isRelevantAttr(Sema &S, const Decl *D, const Attr *A) {
613a9ac8606Spatrick // 'preferred_name' is only relevant to the matching specialization of the
614a9ac8606Spatrick // template.
615a9ac8606Spatrick if (const auto *PNA = dyn_cast<PreferredNameAttr>(A)) {
616a9ac8606Spatrick QualType T = PNA->getTypedefType();
617a9ac8606Spatrick const auto *RD = cast<CXXRecordDecl>(D);
618a9ac8606Spatrick if (!T->isDependentType() && !RD->isDependentContext() &&
619a9ac8606Spatrick !declaresSameEntity(T->getAsCXXRecordDecl(), RD))
620a9ac8606Spatrick return false;
621a9ac8606Spatrick for (const auto *ExistingPNA : D->specific_attrs<PreferredNameAttr>())
622a9ac8606Spatrick if (S.Context.hasSameType(ExistingPNA->getTypedefType(),
623a9ac8606Spatrick PNA->getTypedefType()))
624a9ac8606Spatrick return false;
625a9ac8606Spatrick return true;
626a9ac8606Spatrick }
627a9ac8606Spatrick
628*12c85518Srobert if (const auto *BA = dyn_cast<BuiltinAttr>(A)) {
629*12c85518Srobert const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
630*12c85518Srobert switch (BA->getID()) {
631*12c85518Srobert case Builtin::BIforward:
632*12c85518Srobert // Do not treat 'std::forward' as a builtin if it takes an rvalue reference
633*12c85518Srobert // type and returns an lvalue reference type. The library implementation
634*12c85518Srobert // will produce an error in this case; don't get in its way.
635*12c85518Srobert if (FD && FD->getNumParams() >= 1 &&
636*12c85518Srobert FD->getParamDecl(0)->getType()->isRValueReferenceType() &&
637*12c85518Srobert FD->getReturnType()->isLValueReferenceType()) {
638*12c85518Srobert return false;
639*12c85518Srobert }
640*12c85518Srobert [[fallthrough]];
641*12c85518Srobert case Builtin::BImove:
642*12c85518Srobert case Builtin::BImove_if_noexcept:
643*12c85518Srobert // HACK: Super-old versions of libc++ (3.1 and earlier) provide
644*12c85518Srobert // std::forward and std::move overloads that sometimes return by value
645*12c85518Srobert // instead of by reference when building in C++98 mode. Don't treat such
646*12c85518Srobert // cases as builtins.
647*12c85518Srobert if (FD && !FD->getReturnType()->isReferenceType())
648*12c85518Srobert return false;
649*12c85518Srobert break;
650*12c85518Srobert }
651*12c85518Srobert }
652*12c85518Srobert
653a9ac8606Spatrick return true;
654a9ac8606Spatrick }
655a9ac8606Spatrick
InstantiateAttrsForDecl(const MultiLevelTemplateArgumentList & TemplateArgs,const Decl * Tmpl,Decl * New,LateInstantiatedAttrVec * LateAttrs,LocalInstantiationScope * OuterMostScope)656e5dd7070Spatrick void Sema::InstantiateAttrsForDecl(
657e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs, const Decl *Tmpl,
658e5dd7070Spatrick Decl *New, LateInstantiatedAttrVec *LateAttrs,
659e5dd7070Spatrick LocalInstantiationScope *OuterMostScope) {
660e5dd7070Spatrick if (NamedDecl *ND = dyn_cast<NamedDecl>(New)) {
661a9ac8606Spatrick // FIXME: This function is called multiple times for the same template
662a9ac8606Spatrick // specialization. We should only instantiate attributes that were added
663a9ac8606Spatrick // since the previous instantiation.
664e5dd7070Spatrick for (const auto *TmplAttr : Tmpl->attrs()) {
665a9ac8606Spatrick if (!isRelevantAttr(*this, New, TmplAttr))
666a9ac8606Spatrick continue;
667a9ac8606Spatrick
668e5dd7070Spatrick // FIXME: If any of the special case versions from InstantiateAttrs become
669e5dd7070Spatrick // applicable to template declaration, we'll need to add them here.
670e5dd7070Spatrick CXXThisScopeRAII ThisScope(
671e5dd7070Spatrick *this, dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext()),
672e5dd7070Spatrick Qualifiers(), ND->isCXXInstanceMember());
673e5dd7070Spatrick
674e5dd7070Spatrick Attr *NewAttr = sema::instantiateTemplateAttributeForDecl(
675e5dd7070Spatrick TmplAttr, Context, *this, TemplateArgs);
676a9ac8606Spatrick if (NewAttr && isRelevantAttr(*this, New, NewAttr))
677e5dd7070Spatrick New->addAttr(NewAttr);
678e5dd7070Spatrick }
679e5dd7070Spatrick }
680e5dd7070Spatrick }
681e5dd7070Spatrick
682e5dd7070Spatrick static Sema::RetainOwnershipKind
attrToRetainOwnershipKind(const Attr * A)683e5dd7070Spatrick attrToRetainOwnershipKind(const Attr *A) {
684e5dd7070Spatrick switch (A->getKind()) {
685e5dd7070Spatrick case clang::attr::CFConsumed:
686e5dd7070Spatrick return Sema::RetainOwnershipKind::CF;
687e5dd7070Spatrick case clang::attr::OSConsumed:
688e5dd7070Spatrick return Sema::RetainOwnershipKind::OS;
689e5dd7070Spatrick case clang::attr::NSConsumed:
690e5dd7070Spatrick return Sema::RetainOwnershipKind::NS;
691e5dd7070Spatrick default:
692e5dd7070Spatrick llvm_unreachable("Wrong argument supplied");
693e5dd7070Spatrick }
694e5dd7070Spatrick }
695e5dd7070Spatrick
InstantiateAttrs(const MultiLevelTemplateArgumentList & TemplateArgs,const Decl * Tmpl,Decl * New,LateInstantiatedAttrVec * LateAttrs,LocalInstantiationScope * OuterMostScope)696e5dd7070Spatrick void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
697e5dd7070Spatrick const Decl *Tmpl, Decl *New,
698e5dd7070Spatrick LateInstantiatedAttrVec *LateAttrs,
699e5dd7070Spatrick LocalInstantiationScope *OuterMostScope) {
700e5dd7070Spatrick for (const auto *TmplAttr : Tmpl->attrs()) {
701a9ac8606Spatrick if (!isRelevantAttr(*this, New, TmplAttr))
702a9ac8606Spatrick continue;
703a9ac8606Spatrick
704e5dd7070Spatrick // FIXME: This should be generalized to more than just the AlignedAttr.
705e5dd7070Spatrick const AlignedAttr *Aligned = dyn_cast<AlignedAttr>(TmplAttr);
706e5dd7070Spatrick if (Aligned && Aligned->isAlignmentDependent()) {
707e5dd7070Spatrick instantiateDependentAlignedAttr(*this, TemplateArgs, Aligned, New);
708e5dd7070Spatrick continue;
709e5dd7070Spatrick }
710e5dd7070Spatrick
711e5dd7070Spatrick if (const auto *AssumeAligned = dyn_cast<AssumeAlignedAttr>(TmplAttr)) {
712e5dd7070Spatrick instantiateDependentAssumeAlignedAttr(*this, TemplateArgs, AssumeAligned, New);
713e5dd7070Spatrick continue;
714e5dd7070Spatrick }
715e5dd7070Spatrick
716e5dd7070Spatrick if (const auto *AlignValue = dyn_cast<AlignValueAttr>(TmplAttr)) {
717e5dd7070Spatrick instantiateDependentAlignValueAttr(*this, TemplateArgs, AlignValue, New);
718e5dd7070Spatrick continue;
719e5dd7070Spatrick }
720e5dd7070Spatrick
721e5dd7070Spatrick if (const auto *AllocAlign = dyn_cast<AllocAlignAttr>(TmplAttr)) {
722e5dd7070Spatrick instantiateDependentAllocAlignAttr(*this, TemplateArgs, AllocAlign, New);
723e5dd7070Spatrick continue;
724e5dd7070Spatrick }
725e5dd7070Spatrick
726a9ac8606Spatrick if (const auto *Annotate = dyn_cast<AnnotateAttr>(TmplAttr)) {
727a9ac8606Spatrick instantiateDependentAnnotationAttr(*this, TemplateArgs, Annotate, New);
728a9ac8606Spatrick continue;
729a9ac8606Spatrick }
730e5dd7070Spatrick
731e5dd7070Spatrick if (const auto *EnableIf = dyn_cast<EnableIfAttr>(TmplAttr)) {
732e5dd7070Spatrick instantiateDependentEnableIfAttr(*this, TemplateArgs, EnableIf, Tmpl,
733e5dd7070Spatrick cast<FunctionDecl>(New));
734e5dd7070Spatrick continue;
735e5dd7070Spatrick }
736e5dd7070Spatrick
737e5dd7070Spatrick if (const auto *DiagnoseIf = dyn_cast<DiagnoseIfAttr>(TmplAttr)) {
738e5dd7070Spatrick instantiateDependentDiagnoseIfAttr(*this, TemplateArgs, DiagnoseIf, Tmpl,
739e5dd7070Spatrick cast<FunctionDecl>(New));
740e5dd7070Spatrick continue;
741e5dd7070Spatrick }
742e5dd7070Spatrick
743e5dd7070Spatrick if (const auto *CUDALaunchBounds =
744e5dd7070Spatrick dyn_cast<CUDALaunchBoundsAttr>(TmplAttr)) {
745e5dd7070Spatrick instantiateDependentCUDALaunchBoundsAttr(*this, TemplateArgs,
746e5dd7070Spatrick *CUDALaunchBounds, New);
747e5dd7070Spatrick continue;
748e5dd7070Spatrick }
749e5dd7070Spatrick
750e5dd7070Spatrick if (const auto *Mode = dyn_cast<ModeAttr>(TmplAttr)) {
751e5dd7070Spatrick instantiateDependentModeAttr(*this, TemplateArgs, *Mode, New);
752e5dd7070Spatrick continue;
753e5dd7070Spatrick }
754e5dd7070Spatrick
755e5dd7070Spatrick if (const auto *OMPAttr = dyn_cast<OMPDeclareSimdDeclAttr>(TmplAttr)) {
756e5dd7070Spatrick instantiateOMPDeclareSimdDeclAttr(*this, TemplateArgs, *OMPAttr, New);
757e5dd7070Spatrick continue;
758e5dd7070Spatrick }
759e5dd7070Spatrick
760e5dd7070Spatrick if (const auto *OMPAttr = dyn_cast<OMPDeclareVariantAttr>(TmplAttr)) {
761e5dd7070Spatrick instantiateOMPDeclareVariantAttr(*this, TemplateArgs, *OMPAttr, New);
762e5dd7070Spatrick continue;
763e5dd7070Spatrick }
764e5dd7070Spatrick
765e5dd7070Spatrick if (const auto *AMDGPUFlatWorkGroupSize =
766e5dd7070Spatrick dyn_cast<AMDGPUFlatWorkGroupSizeAttr>(TmplAttr)) {
767e5dd7070Spatrick instantiateDependentAMDGPUFlatWorkGroupSizeAttr(
768e5dd7070Spatrick *this, TemplateArgs, *AMDGPUFlatWorkGroupSize, New);
769e5dd7070Spatrick }
770e5dd7070Spatrick
771e5dd7070Spatrick if (const auto *AMDGPUFlatWorkGroupSize =
772e5dd7070Spatrick dyn_cast<AMDGPUWavesPerEUAttr>(TmplAttr)) {
773e5dd7070Spatrick instantiateDependentAMDGPUWavesPerEUAttr(*this, TemplateArgs,
774e5dd7070Spatrick *AMDGPUFlatWorkGroupSize, New);
775e5dd7070Spatrick }
776e5dd7070Spatrick
777e5dd7070Spatrick // Existing DLL attribute on the instantiation takes precedence.
778e5dd7070Spatrick if (TmplAttr->getKind() == attr::DLLExport ||
779e5dd7070Spatrick TmplAttr->getKind() == attr::DLLImport) {
780e5dd7070Spatrick if (New->hasAttr<DLLExportAttr>() || New->hasAttr<DLLImportAttr>()) {
781e5dd7070Spatrick continue;
782e5dd7070Spatrick }
783e5dd7070Spatrick }
784e5dd7070Spatrick
785e5dd7070Spatrick if (const auto *ABIAttr = dyn_cast<ParameterABIAttr>(TmplAttr)) {
786e5dd7070Spatrick AddParameterABIAttr(New, *ABIAttr, ABIAttr->getABI());
787e5dd7070Spatrick continue;
788e5dd7070Spatrick }
789e5dd7070Spatrick
790e5dd7070Spatrick if (isa<NSConsumedAttr>(TmplAttr) || isa<OSConsumedAttr>(TmplAttr) ||
791e5dd7070Spatrick isa<CFConsumedAttr>(TmplAttr)) {
792e5dd7070Spatrick AddXConsumedAttr(New, *TmplAttr, attrToRetainOwnershipKind(TmplAttr),
793e5dd7070Spatrick /*template instantiation=*/true);
794e5dd7070Spatrick continue;
795e5dd7070Spatrick }
796e5dd7070Spatrick
797e5dd7070Spatrick if (auto *A = dyn_cast<PointerAttr>(TmplAttr)) {
798e5dd7070Spatrick if (!New->hasAttr<PointerAttr>())
799e5dd7070Spatrick New->addAttr(A->clone(Context));
800e5dd7070Spatrick continue;
801e5dd7070Spatrick }
802e5dd7070Spatrick
803e5dd7070Spatrick if (auto *A = dyn_cast<OwnerAttr>(TmplAttr)) {
804e5dd7070Spatrick if (!New->hasAttr<OwnerAttr>())
805e5dd7070Spatrick New->addAttr(A->clone(Context));
806e5dd7070Spatrick continue;
807e5dd7070Spatrick }
808e5dd7070Spatrick
809a9ac8606Spatrick if (auto *A = dyn_cast<SYCLKernelAttr>(TmplAttr)) {
810a9ac8606Spatrick instantiateDependentSYCLKernelAttr(*this, TemplateArgs, *A, New);
811a9ac8606Spatrick continue;
812a9ac8606Spatrick }
813a9ac8606Spatrick
814e5dd7070Spatrick assert(!TmplAttr->isPackExpansion());
815e5dd7070Spatrick if (TmplAttr->isLateParsed() && LateAttrs) {
816e5dd7070Spatrick // Late parsed attributes must be instantiated and attached after the
817e5dd7070Spatrick // enclosing class has been instantiated. See Sema::InstantiateClass.
818e5dd7070Spatrick LocalInstantiationScope *Saved = nullptr;
819e5dd7070Spatrick if (CurrentInstantiationScope)
820e5dd7070Spatrick Saved = CurrentInstantiationScope->cloneScopes(OuterMostScope);
821e5dd7070Spatrick LateAttrs->push_back(LateInstantiatedAttribute(TmplAttr, Saved, New));
822e5dd7070Spatrick } else {
823e5dd7070Spatrick // Allow 'this' within late-parsed attributes.
824e5dd7070Spatrick auto *ND = cast<NamedDecl>(New);
825e5dd7070Spatrick auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext());
826e5dd7070Spatrick CXXThisScopeRAII ThisScope(*this, ThisContext, Qualifiers(),
827e5dd7070Spatrick ND->isCXXInstanceMember());
828e5dd7070Spatrick
829e5dd7070Spatrick Attr *NewAttr = sema::instantiateTemplateAttribute(TmplAttr, Context,
830e5dd7070Spatrick *this, TemplateArgs);
831a9ac8606Spatrick if (NewAttr && isRelevantAttr(*this, New, TmplAttr))
832e5dd7070Spatrick New->addAttr(NewAttr);
833e5dd7070Spatrick }
834e5dd7070Spatrick }
835e5dd7070Spatrick }
836e5dd7070Spatrick
837a9ac8606Spatrick /// In the MS ABI, we need to instantiate default arguments of dllexported
838a9ac8606Spatrick /// default constructors along with the constructor definition. This allows IR
839a9ac8606Spatrick /// gen to emit a constructor closure which calls the default constructor with
840a9ac8606Spatrick /// its default arguments.
InstantiateDefaultCtorDefaultArgs(CXXConstructorDecl * Ctor)841a9ac8606Spatrick void Sema::InstantiateDefaultCtorDefaultArgs(CXXConstructorDecl *Ctor) {
842a9ac8606Spatrick assert(Context.getTargetInfo().getCXXABI().isMicrosoft() &&
843a9ac8606Spatrick Ctor->isDefaultConstructor());
844a9ac8606Spatrick unsigned NumParams = Ctor->getNumParams();
845a9ac8606Spatrick if (NumParams == 0)
846a9ac8606Spatrick return;
847a9ac8606Spatrick DLLExportAttr *Attr = Ctor->getAttr<DLLExportAttr>();
848a9ac8606Spatrick if (!Attr)
849a9ac8606Spatrick return;
850a9ac8606Spatrick for (unsigned I = 0; I != NumParams; ++I) {
851a9ac8606Spatrick (void)CheckCXXDefaultArgExpr(Attr->getLocation(), Ctor,
852a9ac8606Spatrick Ctor->getParamDecl(I));
853*12c85518Srobert CleanupVarDeclMarking();
854a9ac8606Spatrick }
855a9ac8606Spatrick }
856a9ac8606Spatrick
857e5dd7070Spatrick /// Get the previous declaration of a declaration for the purposes of template
858e5dd7070Spatrick /// instantiation. If this finds a previous declaration, then the previous
859e5dd7070Spatrick /// declaration of the instantiation of D should be an instantiation of the
860e5dd7070Spatrick /// result of this function.
861e5dd7070Spatrick template<typename DeclT>
getPreviousDeclForInstantiation(DeclT * D)862e5dd7070Spatrick static DeclT *getPreviousDeclForInstantiation(DeclT *D) {
863e5dd7070Spatrick DeclT *Result = D->getPreviousDecl();
864e5dd7070Spatrick
865e5dd7070Spatrick // If the declaration is within a class, and the previous declaration was
866e5dd7070Spatrick // merged from a different definition of that class, then we don't have a
867e5dd7070Spatrick // previous declaration for the purpose of template instantiation.
868e5dd7070Spatrick if (Result && isa<CXXRecordDecl>(D->getDeclContext()) &&
869e5dd7070Spatrick D->getLexicalDeclContext() != Result->getLexicalDeclContext())
870e5dd7070Spatrick return nullptr;
871e5dd7070Spatrick
872e5dd7070Spatrick return Result;
873e5dd7070Spatrick }
874e5dd7070Spatrick
875e5dd7070Spatrick Decl *
VisitTranslationUnitDecl(TranslationUnitDecl * D)876e5dd7070Spatrick TemplateDeclInstantiator::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
877e5dd7070Spatrick llvm_unreachable("Translation units cannot be instantiated");
878e5dd7070Spatrick }
879e5dd7070Spatrick
VisitHLSLBufferDecl(HLSLBufferDecl * Decl)880*12c85518Srobert Decl *TemplateDeclInstantiator::VisitHLSLBufferDecl(HLSLBufferDecl *Decl) {
881*12c85518Srobert llvm_unreachable("HLSL buffer declarations cannot be instantiated");
882*12c85518Srobert }
883*12c85518Srobert
884e5dd7070Spatrick Decl *
VisitPragmaCommentDecl(PragmaCommentDecl * D)885e5dd7070Spatrick TemplateDeclInstantiator::VisitPragmaCommentDecl(PragmaCommentDecl *D) {
886e5dd7070Spatrick llvm_unreachable("pragma comment cannot be instantiated");
887e5dd7070Spatrick }
888e5dd7070Spatrick
VisitPragmaDetectMismatchDecl(PragmaDetectMismatchDecl * D)889e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitPragmaDetectMismatchDecl(
890e5dd7070Spatrick PragmaDetectMismatchDecl *D) {
891e5dd7070Spatrick llvm_unreachable("pragma comment cannot be instantiated");
892e5dd7070Spatrick }
893e5dd7070Spatrick
894e5dd7070Spatrick Decl *
VisitExternCContextDecl(ExternCContextDecl * D)895e5dd7070Spatrick TemplateDeclInstantiator::VisitExternCContextDecl(ExternCContextDecl *D) {
896e5dd7070Spatrick llvm_unreachable("extern \"C\" context cannot be instantiated");
897e5dd7070Spatrick }
898e5dd7070Spatrick
VisitMSGuidDecl(MSGuidDecl * D)899ec727ea7Spatrick Decl *TemplateDeclInstantiator::VisitMSGuidDecl(MSGuidDecl *D) {
900ec727ea7Spatrick llvm_unreachable("GUID declaration cannot be instantiated");
901ec727ea7Spatrick }
902ec727ea7Spatrick
VisitUnnamedGlobalConstantDecl(UnnamedGlobalConstantDecl * D)903*12c85518Srobert Decl *TemplateDeclInstantiator::VisitUnnamedGlobalConstantDecl(
904*12c85518Srobert UnnamedGlobalConstantDecl *D) {
905*12c85518Srobert llvm_unreachable("UnnamedGlobalConstantDecl cannot be instantiated");
906*12c85518Srobert }
907*12c85518Srobert
VisitTemplateParamObjectDecl(TemplateParamObjectDecl * D)908a9ac8606Spatrick Decl *TemplateDeclInstantiator::VisitTemplateParamObjectDecl(
909a9ac8606Spatrick TemplateParamObjectDecl *D) {
910a9ac8606Spatrick llvm_unreachable("template parameter objects cannot be instantiated");
911a9ac8606Spatrick }
912a9ac8606Spatrick
913e5dd7070Spatrick Decl *
VisitLabelDecl(LabelDecl * D)914e5dd7070Spatrick TemplateDeclInstantiator::VisitLabelDecl(LabelDecl *D) {
915e5dd7070Spatrick LabelDecl *Inst = LabelDecl::Create(SemaRef.Context, Owner, D->getLocation(),
916e5dd7070Spatrick D->getIdentifier());
917e5dd7070Spatrick Owner->addDecl(Inst);
918e5dd7070Spatrick return Inst;
919e5dd7070Spatrick }
920e5dd7070Spatrick
921e5dd7070Spatrick Decl *
VisitNamespaceDecl(NamespaceDecl * D)922e5dd7070Spatrick TemplateDeclInstantiator::VisitNamespaceDecl(NamespaceDecl *D) {
923e5dd7070Spatrick llvm_unreachable("Namespaces cannot be instantiated");
924e5dd7070Spatrick }
925e5dd7070Spatrick
926e5dd7070Spatrick Decl *
VisitNamespaceAliasDecl(NamespaceAliasDecl * D)927e5dd7070Spatrick TemplateDeclInstantiator::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
928e5dd7070Spatrick NamespaceAliasDecl *Inst
929e5dd7070Spatrick = NamespaceAliasDecl::Create(SemaRef.Context, Owner,
930e5dd7070Spatrick D->getNamespaceLoc(),
931e5dd7070Spatrick D->getAliasLoc(),
932e5dd7070Spatrick D->getIdentifier(),
933e5dd7070Spatrick D->getQualifierLoc(),
934e5dd7070Spatrick D->getTargetNameLoc(),
935e5dd7070Spatrick D->getNamespace());
936e5dd7070Spatrick Owner->addDecl(Inst);
937e5dd7070Spatrick return Inst;
938e5dd7070Spatrick }
939e5dd7070Spatrick
InstantiateTypedefNameDecl(TypedefNameDecl * D,bool IsTypeAlias)940e5dd7070Spatrick Decl *TemplateDeclInstantiator::InstantiateTypedefNameDecl(TypedefNameDecl *D,
941e5dd7070Spatrick bool IsTypeAlias) {
942e5dd7070Spatrick bool Invalid = false;
943e5dd7070Spatrick TypeSourceInfo *DI = D->getTypeSourceInfo();
944e5dd7070Spatrick if (DI->getType()->isInstantiationDependentType() ||
945e5dd7070Spatrick DI->getType()->isVariablyModifiedType()) {
946e5dd7070Spatrick DI = SemaRef.SubstType(DI, TemplateArgs,
947e5dd7070Spatrick D->getLocation(), D->getDeclName());
948e5dd7070Spatrick if (!DI) {
949e5dd7070Spatrick Invalid = true;
950e5dd7070Spatrick DI = SemaRef.Context.getTrivialTypeSourceInfo(SemaRef.Context.IntTy);
951e5dd7070Spatrick }
952e5dd7070Spatrick } else {
953e5dd7070Spatrick SemaRef.MarkDeclarationsReferencedInType(D->getLocation(), DI->getType());
954e5dd7070Spatrick }
955e5dd7070Spatrick
956a9ac8606Spatrick // HACK: 2012-10-23 g++ has a bug where it gets the value kind of ?: wrong.
957a9ac8606Spatrick // libstdc++ relies upon this bug in its implementation of common_type. If we
958a9ac8606Spatrick // happen to be processing that implementation, fake up the g++ ?:
959a9ac8606Spatrick // semantics. See LWG issue 2141 for more information on the bug. The bugs
960a9ac8606Spatrick // are fixed in g++ and libstdc++ 4.9.0 (2014-04-22).
961e5dd7070Spatrick const DecltypeType *DT = DI->getType()->getAs<DecltypeType>();
962e5dd7070Spatrick CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D->getDeclContext());
963e5dd7070Spatrick if (DT && RD && isa<ConditionalOperator>(DT->getUnderlyingExpr()) &&
964e5dd7070Spatrick DT->isReferenceType() &&
965e5dd7070Spatrick RD->getEnclosingNamespaceContext() == SemaRef.getStdNamespace() &&
966e5dd7070Spatrick RD->getIdentifier() && RD->getIdentifier()->isStr("common_type") &&
967e5dd7070Spatrick D->getIdentifier() && D->getIdentifier()->isStr("type") &&
968e5dd7070Spatrick SemaRef.getSourceManager().isInSystemHeader(D->getBeginLoc()))
969e5dd7070Spatrick // Fold it to the (non-reference) type which g++ would have produced.
970e5dd7070Spatrick DI = SemaRef.Context.getTrivialTypeSourceInfo(
971e5dd7070Spatrick DI->getType().getNonReferenceType());
972e5dd7070Spatrick
973e5dd7070Spatrick // Create the new typedef
974e5dd7070Spatrick TypedefNameDecl *Typedef;
975e5dd7070Spatrick if (IsTypeAlias)
976e5dd7070Spatrick Typedef = TypeAliasDecl::Create(SemaRef.Context, Owner, D->getBeginLoc(),
977e5dd7070Spatrick D->getLocation(), D->getIdentifier(), DI);
978e5dd7070Spatrick else
979e5dd7070Spatrick Typedef = TypedefDecl::Create(SemaRef.Context, Owner, D->getBeginLoc(),
980e5dd7070Spatrick D->getLocation(), D->getIdentifier(), DI);
981e5dd7070Spatrick if (Invalid)
982e5dd7070Spatrick Typedef->setInvalidDecl();
983e5dd7070Spatrick
984e5dd7070Spatrick // If the old typedef was the name for linkage purposes of an anonymous
985e5dd7070Spatrick // tag decl, re-establish that relationship for the new typedef.
986e5dd7070Spatrick if (const TagType *oldTagType = D->getUnderlyingType()->getAs<TagType>()) {
987e5dd7070Spatrick TagDecl *oldTag = oldTagType->getDecl();
988e5dd7070Spatrick if (oldTag->getTypedefNameForAnonDecl() == D && !Invalid) {
989e5dd7070Spatrick TagDecl *newTag = DI->getType()->castAs<TagType>()->getDecl();
990e5dd7070Spatrick assert(!newTag->hasNameForLinkage());
991e5dd7070Spatrick newTag->setTypedefNameForAnonDecl(Typedef);
992e5dd7070Spatrick }
993e5dd7070Spatrick }
994e5dd7070Spatrick
995e5dd7070Spatrick if (TypedefNameDecl *Prev = getPreviousDeclForInstantiation(D)) {
996e5dd7070Spatrick NamedDecl *InstPrev = SemaRef.FindInstantiatedDecl(D->getLocation(), Prev,
997e5dd7070Spatrick TemplateArgs);
998e5dd7070Spatrick if (!InstPrev)
999e5dd7070Spatrick return nullptr;
1000e5dd7070Spatrick
1001e5dd7070Spatrick TypedefNameDecl *InstPrevTypedef = cast<TypedefNameDecl>(InstPrev);
1002e5dd7070Spatrick
1003e5dd7070Spatrick // If the typedef types are not identical, reject them.
1004e5dd7070Spatrick SemaRef.isIncompatibleTypedef(InstPrevTypedef, Typedef);
1005e5dd7070Spatrick
1006e5dd7070Spatrick Typedef->setPreviousDecl(InstPrevTypedef);
1007e5dd7070Spatrick }
1008e5dd7070Spatrick
1009e5dd7070Spatrick SemaRef.InstantiateAttrs(TemplateArgs, D, Typedef);
1010e5dd7070Spatrick
1011e5dd7070Spatrick if (D->getUnderlyingType()->getAs<DependentNameType>())
1012e5dd7070Spatrick SemaRef.inferGslPointerAttribute(Typedef);
1013e5dd7070Spatrick
1014e5dd7070Spatrick Typedef->setAccess(D->getAccess());
1015*12c85518Srobert Typedef->setReferenced(D->isReferenced());
1016e5dd7070Spatrick
1017e5dd7070Spatrick return Typedef;
1018e5dd7070Spatrick }
1019e5dd7070Spatrick
VisitTypedefDecl(TypedefDecl * D)1020e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {
1021e5dd7070Spatrick Decl *Typedef = InstantiateTypedefNameDecl(D, /*IsTypeAlias=*/false);
1022e5dd7070Spatrick if (Typedef)
1023e5dd7070Spatrick Owner->addDecl(Typedef);
1024e5dd7070Spatrick return Typedef;
1025e5dd7070Spatrick }
1026e5dd7070Spatrick
VisitTypeAliasDecl(TypeAliasDecl * D)1027e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitTypeAliasDecl(TypeAliasDecl *D) {
1028e5dd7070Spatrick Decl *Typedef = InstantiateTypedefNameDecl(D, /*IsTypeAlias=*/true);
1029e5dd7070Spatrick if (Typedef)
1030e5dd7070Spatrick Owner->addDecl(Typedef);
1031e5dd7070Spatrick return Typedef;
1032e5dd7070Spatrick }
1033e5dd7070Spatrick
1034e5dd7070Spatrick Decl *
VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl * D)1035e5dd7070Spatrick TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
1036e5dd7070Spatrick // Create a local instantiation scope for this type alias template, which
1037e5dd7070Spatrick // will contain the instantiations of the template parameters.
1038e5dd7070Spatrick LocalInstantiationScope Scope(SemaRef);
1039e5dd7070Spatrick
1040e5dd7070Spatrick TemplateParameterList *TempParams = D->getTemplateParameters();
1041e5dd7070Spatrick TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
1042e5dd7070Spatrick if (!InstParams)
1043e5dd7070Spatrick return nullptr;
1044e5dd7070Spatrick
1045e5dd7070Spatrick TypeAliasDecl *Pattern = D->getTemplatedDecl();
1046e5dd7070Spatrick
1047e5dd7070Spatrick TypeAliasTemplateDecl *PrevAliasTemplate = nullptr;
1048e5dd7070Spatrick if (getPreviousDeclForInstantiation<TypedefNameDecl>(Pattern)) {
1049e5dd7070Spatrick DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName());
1050e5dd7070Spatrick if (!Found.empty()) {
1051e5dd7070Spatrick PrevAliasTemplate = dyn_cast<TypeAliasTemplateDecl>(Found.front());
1052e5dd7070Spatrick }
1053e5dd7070Spatrick }
1054e5dd7070Spatrick
1055e5dd7070Spatrick TypeAliasDecl *AliasInst = cast_or_null<TypeAliasDecl>(
1056e5dd7070Spatrick InstantiateTypedefNameDecl(Pattern, /*IsTypeAlias=*/true));
1057e5dd7070Spatrick if (!AliasInst)
1058e5dd7070Spatrick return nullptr;
1059e5dd7070Spatrick
1060e5dd7070Spatrick TypeAliasTemplateDecl *Inst
1061e5dd7070Spatrick = TypeAliasTemplateDecl::Create(SemaRef.Context, Owner, D->getLocation(),
1062e5dd7070Spatrick D->getDeclName(), InstParams, AliasInst);
1063e5dd7070Spatrick AliasInst->setDescribedAliasTemplate(Inst);
1064e5dd7070Spatrick if (PrevAliasTemplate)
1065e5dd7070Spatrick Inst->setPreviousDecl(PrevAliasTemplate);
1066e5dd7070Spatrick
1067e5dd7070Spatrick Inst->setAccess(D->getAccess());
1068e5dd7070Spatrick
1069e5dd7070Spatrick if (!PrevAliasTemplate)
1070e5dd7070Spatrick Inst->setInstantiatedFromMemberTemplate(D);
1071e5dd7070Spatrick
1072e5dd7070Spatrick Owner->addDecl(Inst);
1073e5dd7070Spatrick
1074e5dd7070Spatrick return Inst;
1075e5dd7070Spatrick }
1076e5dd7070Spatrick
VisitBindingDecl(BindingDecl * D)1077e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitBindingDecl(BindingDecl *D) {
1078e5dd7070Spatrick auto *NewBD = BindingDecl::Create(SemaRef.Context, Owner, D->getLocation(),
1079e5dd7070Spatrick D->getIdentifier());
1080e5dd7070Spatrick NewBD->setReferenced(D->isReferenced());
1081e5dd7070Spatrick SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewBD);
1082e5dd7070Spatrick return NewBD;
1083e5dd7070Spatrick }
1084e5dd7070Spatrick
VisitDecompositionDecl(DecompositionDecl * D)1085e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitDecompositionDecl(DecompositionDecl *D) {
1086e5dd7070Spatrick // Transform the bindings first.
1087e5dd7070Spatrick SmallVector<BindingDecl*, 16> NewBindings;
1088e5dd7070Spatrick for (auto *OldBD : D->bindings())
1089e5dd7070Spatrick NewBindings.push_back(cast<BindingDecl>(VisitBindingDecl(OldBD)));
1090e5dd7070Spatrick ArrayRef<BindingDecl*> NewBindingArray = NewBindings;
1091e5dd7070Spatrick
1092e5dd7070Spatrick auto *NewDD = cast_or_null<DecompositionDecl>(
1093e5dd7070Spatrick VisitVarDecl(D, /*InstantiatingVarTemplate=*/false, &NewBindingArray));
1094e5dd7070Spatrick
1095e5dd7070Spatrick if (!NewDD || NewDD->isInvalidDecl())
1096e5dd7070Spatrick for (auto *NewBD : NewBindings)
1097e5dd7070Spatrick NewBD->setInvalidDecl();
1098e5dd7070Spatrick
1099e5dd7070Spatrick return NewDD;
1100e5dd7070Spatrick }
1101e5dd7070Spatrick
VisitVarDecl(VarDecl * D)1102e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
1103e5dd7070Spatrick return VisitVarDecl(D, /*InstantiatingVarTemplate=*/false);
1104e5dd7070Spatrick }
1105e5dd7070Spatrick
VisitVarDecl(VarDecl * D,bool InstantiatingVarTemplate,ArrayRef<BindingDecl * > * Bindings)1106e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D,
1107e5dd7070Spatrick bool InstantiatingVarTemplate,
1108e5dd7070Spatrick ArrayRef<BindingDecl*> *Bindings) {
1109e5dd7070Spatrick
1110e5dd7070Spatrick // Do substitution on the type of the declaration
1111e5dd7070Spatrick TypeSourceInfo *DI = SemaRef.SubstType(
1112e5dd7070Spatrick D->getTypeSourceInfo(), TemplateArgs, D->getTypeSpecStartLoc(),
1113e5dd7070Spatrick D->getDeclName(), /*AllowDeducedTST*/true);
1114e5dd7070Spatrick if (!DI)
1115e5dd7070Spatrick return nullptr;
1116e5dd7070Spatrick
1117e5dd7070Spatrick if (DI->getType()->isFunctionType()) {
1118e5dd7070Spatrick SemaRef.Diag(D->getLocation(), diag::err_variable_instantiates_to_function)
1119e5dd7070Spatrick << D->isStaticDataMember() << DI->getType();
1120e5dd7070Spatrick return nullptr;
1121e5dd7070Spatrick }
1122e5dd7070Spatrick
1123e5dd7070Spatrick DeclContext *DC = Owner;
1124e5dd7070Spatrick if (D->isLocalExternDecl())
1125e5dd7070Spatrick SemaRef.adjustContextForLocalExternDecl(DC);
1126e5dd7070Spatrick
1127e5dd7070Spatrick // Build the instantiated declaration.
1128e5dd7070Spatrick VarDecl *Var;
1129e5dd7070Spatrick if (Bindings)
1130e5dd7070Spatrick Var = DecompositionDecl::Create(SemaRef.Context, DC, D->getInnerLocStart(),
1131e5dd7070Spatrick D->getLocation(), DI->getType(), DI,
1132e5dd7070Spatrick D->getStorageClass(), *Bindings);
1133e5dd7070Spatrick else
1134e5dd7070Spatrick Var = VarDecl::Create(SemaRef.Context, DC, D->getInnerLocStart(),
1135e5dd7070Spatrick D->getLocation(), D->getIdentifier(), DI->getType(),
1136e5dd7070Spatrick DI, D->getStorageClass());
1137e5dd7070Spatrick
1138e5dd7070Spatrick // In ARC, infer 'retaining' for variables of retainable type.
1139e5dd7070Spatrick if (SemaRef.getLangOpts().ObjCAutoRefCount &&
1140e5dd7070Spatrick SemaRef.inferObjCARCLifetime(Var))
1141e5dd7070Spatrick Var->setInvalidDecl();
1142e5dd7070Spatrick
1143e5dd7070Spatrick if (SemaRef.getLangOpts().OpenCL)
1144e5dd7070Spatrick SemaRef.deduceOpenCLAddressSpace(Var);
1145e5dd7070Spatrick
1146e5dd7070Spatrick // Substitute the nested name specifier, if any.
1147e5dd7070Spatrick if (SubstQualifier(D, Var))
1148e5dd7070Spatrick return nullptr;
1149e5dd7070Spatrick
1150e5dd7070Spatrick SemaRef.BuildVariableInstantiation(Var, D, TemplateArgs, LateAttrs, Owner,
1151e5dd7070Spatrick StartingScope, InstantiatingVarTemplate);
1152a9ac8606Spatrick if (D->isNRVOVariable() && !Var->isInvalidDecl()) {
1153a9ac8606Spatrick QualType RT;
1154a9ac8606Spatrick if (auto *F = dyn_cast<FunctionDecl>(DC))
1155a9ac8606Spatrick RT = F->getReturnType();
1156a9ac8606Spatrick else if (isa<BlockDecl>(DC))
1157a9ac8606Spatrick RT = cast<FunctionType>(SemaRef.getCurBlock()->FunctionType)
1158a9ac8606Spatrick ->getReturnType();
1159a9ac8606Spatrick else
1160a9ac8606Spatrick llvm_unreachable("Unknown context type");
1161e5dd7070Spatrick
1162a9ac8606Spatrick // This is the last chance we have of checking copy elision eligibility
1163a9ac8606Spatrick // for functions in dependent contexts. The sema actions for building
1164a9ac8606Spatrick // the return statement during template instantiation will have no effect
1165a9ac8606Spatrick // regarding copy elision, since NRVO propagation runs on the scope exit
1166a9ac8606Spatrick // actions, and these are not run on instantiation.
1167a9ac8606Spatrick // This might run through some VarDecls which were returned from non-taken
1168a9ac8606Spatrick // 'if constexpr' branches, and these will end up being constructed on the
1169a9ac8606Spatrick // return slot even if they will never be returned, as a sort of accidental
1170a9ac8606Spatrick // 'optimization'. Notably, functions with 'auto' return types won't have it
1171a9ac8606Spatrick // deduced by this point. Coupled with the limitation described
1172a9ac8606Spatrick // previously, this makes it very hard to support copy elision for these.
1173a9ac8606Spatrick Sema::NamedReturnInfo Info = SemaRef.getNamedReturnInfo(Var);
1174a9ac8606Spatrick bool NRVO = SemaRef.getCopyElisionCandidate(Info, RT) != nullptr;
1175a9ac8606Spatrick Var->setNRVOVariable(NRVO);
1176e5dd7070Spatrick }
1177e5dd7070Spatrick
1178e5dd7070Spatrick Var->setImplicit(D->isImplicit());
1179e5dd7070Spatrick
1180e5dd7070Spatrick if (Var->isStaticLocal())
1181e5dd7070Spatrick SemaRef.CheckStaticLocalForDllExport(Var);
1182e5dd7070Spatrick
1183*12c85518Srobert if (Var->getTLSKind())
1184*12c85518Srobert SemaRef.CheckThreadLocalForLargeAlignment(Var);
1185*12c85518Srobert
1186e5dd7070Spatrick return Var;
1187e5dd7070Spatrick }
1188e5dd7070Spatrick
VisitAccessSpecDecl(AccessSpecDecl * D)1189e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitAccessSpecDecl(AccessSpecDecl *D) {
1190e5dd7070Spatrick AccessSpecDecl* AD
1191e5dd7070Spatrick = AccessSpecDecl::Create(SemaRef.Context, D->getAccess(), Owner,
1192e5dd7070Spatrick D->getAccessSpecifierLoc(), D->getColonLoc());
1193e5dd7070Spatrick Owner->addHiddenDecl(AD);
1194e5dd7070Spatrick return AD;
1195e5dd7070Spatrick }
1196e5dd7070Spatrick
VisitFieldDecl(FieldDecl * D)1197e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
1198e5dd7070Spatrick bool Invalid = false;
1199e5dd7070Spatrick TypeSourceInfo *DI = D->getTypeSourceInfo();
1200e5dd7070Spatrick if (DI->getType()->isInstantiationDependentType() ||
1201e5dd7070Spatrick DI->getType()->isVariablyModifiedType()) {
1202e5dd7070Spatrick DI = SemaRef.SubstType(DI, TemplateArgs,
1203e5dd7070Spatrick D->getLocation(), D->getDeclName());
1204e5dd7070Spatrick if (!DI) {
1205e5dd7070Spatrick DI = D->getTypeSourceInfo();
1206e5dd7070Spatrick Invalid = true;
1207e5dd7070Spatrick } else if (DI->getType()->isFunctionType()) {
1208e5dd7070Spatrick // C++ [temp.arg.type]p3:
1209e5dd7070Spatrick // If a declaration acquires a function type through a type
1210e5dd7070Spatrick // dependent on a template-parameter and this causes a
1211e5dd7070Spatrick // declaration that does not use the syntactic form of a
1212e5dd7070Spatrick // function declarator to have function type, the program is
1213e5dd7070Spatrick // ill-formed.
1214e5dd7070Spatrick SemaRef.Diag(D->getLocation(), diag::err_field_instantiates_to_function)
1215e5dd7070Spatrick << DI->getType();
1216e5dd7070Spatrick Invalid = true;
1217e5dd7070Spatrick }
1218e5dd7070Spatrick } else {
1219e5dd7070Spatrick SemaRef.MarkDeclarationsReferencedInType(D->getLocation(), DI->getType());
1220e5dd7070Spatrick }
1221e5dd7070Spatrick
1222e5dd7070Spatrick Expr *BitWidth = D->getBitWidth();
1223e5dd7070Spatrick if (Invalid)
1224e5dd7070Spatrick BitWidth = nullptr;
1225e5dd7070Spatrick else if (BitWidth) {
1226e5dd7070Spatrick // The bit-width expression is a constant expression.
1227e5dd7070Spatrick EnterExpressionEvaluationContext Unevaluated(
1228e5dd7070Spatrick SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
1229e5dd7070Spatrick
1230e5dd7070Spatrick ExprResult InstantiatedBitWidth
1231e5dd7070Spatrick = SemaRef.SubstExpr(BitWidth, TemplateArgs);
1232e5dd7070Spatrick if (InstantiatedBitWidth.isInvalid()) {
1233e5dd7070Spatrick Invalid = true;
1234e5dd7070Spatrick BitWidth = nullptr;
1235e5dd7070Spatrick } else
1236e5dd7070Spatrick BitWidth = InstantiatedBitWidth.getAs<Expr>();
1237e5dd7070Spatrick }
1238e5dd7070Spatrick
1239e5dd7070Spatrick FieldDecl *Field = SemaRef.CheckFieldDecl(D->getDeclName(),
1240e5dd7070Spatrick DI->getType(), DI,
1241e5dd7070Spatrick cast<RecordDecl>(Owner),
1242e5dd7070Spatrick D->getLocation(),
1243e5dd7070Spatrick D->isMutable(),
1244e5dd7070Spatrick BitWidth,
1245e5dd7070Spatrick D->getInClassInitStyle(),
1246e5dd7070Spatrick D->getInnerLocStart(),
1247e5dd7070Spatrick D->getAccess(),
1248e5dd7070Spatrick nullptr);
1249e5dd7070Spatrick if (!Field) {
1250e5dd7070Spatrick cast<Decl>(Owner)->setInvalidDecl();
1251e5dd7070Spatrick return nullptr;
1252e5dd7070Spatrick }
1253e5dd7070Spatrick
1254e5dd7070Spatrick SemaRef.InstantiateAttrs(TemplateArgs, D, Field, LateAttrs, StartingScope);
1255e5dd7070Spatrick
1256e5dd7070Spatrick if (Field->hasAttrs())
1257e5dd7070Spatrick SemaRef.CheckAlignasUnderalignment(Field);
1258e5dd7070Spatrick
1259e5dd7070Spatrick if (Invalid)
1260e5dd7070Spatrick Field->setInvalidDecl();
1261e5dd7070Spatrick
1262e5dd7070Spatrick if (!Field->getDeclName()) {
1263e5dd7070Spatrick // Keep track of where this decl came from.
1264e5dd7070Spatrick SemaRef.Context.setInstantiatedFromUnnamedFieldDecl(Field, D);
1265e5dd7070Spatrick }
1266e5dd7070Spatrick if (CXXRecordDecl *Parent= dyn_cast<CXXRecordDecl>(Field->getDeclContext())) {
1267e5dd7070Spatrick if (Parent->isAnonymousStructOrUnion() &&
1268e5dd7070Spatrick Parent->getRedeclContext()->isFunctionOrMethod())
1269e5dd7070Spatrick SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Field);
1270e5dd7070Spatrick }
1271e5dd7070Spatrick
1272e5dd7070Spatrick Field->setImplicit(D->isImplicit());
1273e5dd7070Spatrick Field->setAccess(D->getAccess());
1274e5dd7070Spatrick Owner->addDecl(Field);
1275e5dd7070Spatrick
1276e5dd7070Spatrick return Field;
1277e5dd7070Spatrick }
1278e5dd7070Spatrick
VisitMSPropertyDecl(MSPropertyDecl * D)1279e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitMSPropertyDecl(MSPropertyDecl *D) {
1280e5dd7070Spatrick bool Invalid = false;
1281e5dd7070Spatrick TypeSourceInfo *DI = D->getTypeSourceInfo();
1282e5dd7070Spatrick
1283e5dd7070Spatrick if (DI->getType()->isVariablyModifiedType()) {
1284e5dd7070Spatrick SemaRef.Diag(D->getLocation(), diag::err_property_is_variably_modified)
1285e5dd7070Spatrick << D;
1286e5dd7070Spatrick Invalid = true;
1287e5dd7070Spatrick } else if (DI->getType()->isInstantiationDependentType()) {
1288e5dd7070Spatrick DI = SemaRef.SubstType(DI, TemplateArgs,
1289e5dd7070Spatrick D->getLocation(), D->getDeclName());
1290e5dd7070Spatrick if (!DI) {
1291e5dd7070Spatrick DI = D->getTypeSourceInfo();
1292e5dd7070Spatrick Invalid = true;
1293e5dd7070Spatrick } else if (DI->getType()->isFunctionType()) {
1294e5dd7070Spatrick // C++ [temp.arg.type]p3:
1295e5dd7070Spatrick // If a declaration acquires a function type through a type
1296e5dd7070Spatrick // dependent on a template-parameter and this causes a
1297e5dd7070Spatrick // declaration that does not use the syntactic form of a
1298e5dd7070Spatrick // function declarator to have function type, the program is
1299e5dd7070Spatrick // ill-formed.
1300e5dd7070Spatrick SemaRef.Diag(D->getLocation(), diag::err_field_instantiates_to_function)
1301e5dd7070Spatrick << DI->getType();
1302e5dd7070Spatrick Invalid = true;
1303e5dd7070Spatrick }
1304e5dd7070Spatrick } else {
1305e5dd7070Spatrick SemaRef.MarkDeclarationsReferencedInType(D->getLocation(), DI->getType());
1306e5dd7070Spatrick }
1307e5dd7070Spatrick
1308e5dd7070Spatrick MSPropertyDecl *Property = MSPropertyDecl::Create(
1309e5dd7070Spatrick SemaRef.Context, Owner, D->getLocation(), D->getDeclName(), DI->getType(),
1310e5dd7070Spatrick DI, D->getBeginLoc(), D->getGetterId(), D->getSetterId());
1311e5dd7070Spatrick
1312e5dd7070Spatrick SemaRef.InstantiateAttrs(TemplateArgs, D, Property, LateAttrs,
1313e5dd7070Spatrick StartingScope);
1314e5dd7070Spatrick
1315e5dd7070Spatrick if (Invalid)
1316e5dd7070Spatrick Property->setInvalidDecl();
1317e5dd7070Spatrick
1318e5dd7070Spatrick Property->setAccess(D->getAccess());
1319e5dd7070Spatrick Owner->addDecl(Property);
1320e5dd7070Spatrick
1321e5dd7070Spatrick return Property;
1322e5dd7070Spatrick }
1323e5dd7070Spatrick
VisitIndirectFieldDecl(IndirectFieldDecl * D)1324e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
1325e5dd7070Spatrick NamedDecl **NamedChain =
1326e5dd7070Spatrick new (SemaRef.Context)NamedDecl*[D->getChainingSize()];
1327e5dd7070Spatrick
1328e5dd7070Spatrick int i = 0;
1329e5dd7070Spatrick for (auto *PI : D->chain()) {
1330e5dd7070Spatrick NamedDecl *Next = SemaRef.FindInstantiatedDecl(D->getLocation(), PI,
1331e5dd7070Spatrick TemplateArgs);
1332e5dd7070Spatrick if (!Next)
1333e5dd7070Spatrick return nullptr;
1334e5dd7070Spatrick
1335e5dd7070Spatrick NamedChain[i++] = Next;
1336e5dd7070Spatrick }
1337e5dd7070Spatrick
1338e5dd7070Spatrick QualType T = cast<FieldDecl>(NamedChain[i-1])->getType();
1339e5dd7070Spatrick IndirectFieldDecl *IndirectField = IndirectFieldDecl::Create(
1340e5dd7070Spatrick SemaRef.Context, Owner, D->getLocation(), D->getIdentifier(), T,
1341e5dd7070Spatrick {NamedChain, D->getChainingSize()});
1342e5dd7070Spatrick
1343e5dd7070Spatrick for (const auto *Attr : D->attrs())
1344e5dd7070Spatrick IndirectField->addAttr(Attr->clone(SemaRef.Context));
1345e5dd7070Spatrick
1346e5dd7070Spatrick IndirectField->setImplicit(D->isImplicit());
1347e5dd7070Spatrick IndirectField->setAccess(D->getAccess());
1348e5dd7070Spatrick Owner->addDecl(IndirectField);
1349e5dd7070Spatrick return IndirectField;
1350e5dd7070Spatrick }
1351e5dd7070Spatrick
VisitFriendDecl(FriendDecl * D)1352e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitFriendDecl(FriendDecl *D) {
1353e5dd7070Spatrick // Handle friend type expressions by simply substituting template
1354e5dd7070Spatrick // parameters into the pattern type and checking the result.
1355e5dd7070Spatrick if (TypeSourceInfo *Ty = D->getFriendType()) {
1356e5dd7070Spatrick TypeSourceInfo *InstTy;
1357e5dd7070Spatrick // If this is an unsupported friend, don't bother substituting template
1358e5dd7070Spatrick // arguments into it. The actual type referred to won't be used by any
1359e5dd7070Spatrick // parts of Clang, and may not be valid for instantiating. Just use the
1360e5dd7070Spatrick // same info for the instantiated friend.
1361e5dd7070Spatrick if (D->isUnsupportedFriend()) {
1362e5dd7070Spatrick InstTy = Ty;
1363e5dd7070Spatrick } else {
1364e5dd7070Spatrick InstTy = SemaRef.SubstType(Ty, TemplateArgs,
1365e5dd7070Spatrick D->getLocation(), DeclarationName());
1366e5dd7070Spatrick }
1367e5dd7070Spatrick if (!InstTy)
1368e5dd7070Spatrick return nullptr;
1369e5dd7070Spatrick
1370e5dd7070Spatrick FriendDecl *FD = SemaRef.CheckFriendTypeDecl(D->getBeginLoc(),
1371e5dd7070Spatrick D->getFriendLoc(), InstTy);
1372e5dd7070Spatrick if (!FD)
1373e5dd7070Spatrick return nullptr;
1374e5dd7070Spatrick
1375e5dd7070Spatrick FD->setAccess(AS_public);
1376e5dd7070Spatrick FD->setUnsupportedFriend(D->isUnsupportedFriend());
1377e5dd7070Spatrick Owner->addDecl(FD);
1378e5dd7070Spatrick return FD;
1379e5dd7070Spatrick }
1380e5dd7070Spatrick
1381e5dd7070Spatrick NamedDecl *ND = D->getFriendDecl();
1382e5dd7070Spatrick assert(ND && "friend decl must be a decl or a type!");
1383e5dd7070Spatrick
1384e5dd7070Spatrick // All of the Visit implementations for the various potential friend
1385e5dd7070Spatrick // declarations have to be carefully written to work for friend
1386e5dd7070Spatrick // objects, with the most important detail being that the target
1387e5dd7070Spatrick // decl should almost certainly not be placed in Owner.
1388e5dd7070Spatrick Decl *NewND = Visit(ND);
1389e5dd7070Spatrick if (!NewND) return nullptr;
1390e5dd7070Spatrick
1391e5dd7070Spatrick FriendDecl *FD =
1392e5dd7070Spatrick FriendDecl::Create(SemaRef.Context, Owner, D->getLocation(),
1393e5dd7070Spatrick cast<NamedDecl>(NewND), D->getFriendLoc());
1394e5dd7070Spatrick FD->setAccess(AS_public);
1395e5dd7070Spatrick FD->setUnsupportedFriend(D->isUnsupportedFriend());
1396e5dd7070Spatrick Owner->addDecl(FD);
1397e5dd7070Spatrick return FD;
1398e5dd7070Spatrick }
1399e5dd7070Spatrick
VisitStaticAssertDecl(StaticAssertDecl * D)1400e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitStaticAssertDecl(StaticAssertDecl *D) {
1401e5dd7070Spatrick Expr *AssertExpr = D->getAssertExpr();
1402e5dd7070Spatrick
1403e5dd7070Spatrick // The expression in a static assertion is a constant expression.
1404e5dd7070Spatrick EnterExpressionEvaluationContext Unevaluated(
1405e5dd7070Spatrick SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
1406e5dd7070Spatrick
1407e5dd7070Spatrick ExprResult InstantiatedAssertExpr
1408e5dd7070Spatrick = SemaRef.SubstExpr(AssertExpr, TemplateArgs);
1409e5dd7070Spatrick if (InstantiatedAssertExpr.isInvalid())
1410e5dd7070Spatrick return nullptr;
1411e5dd7070Spatrick
1412e5dd7070Spatrick return SemaRef.BuildStaticAssertDeclaration(D->getLocation(),
1413e5dd7070Spatrick InstantiatedAssertExpr.get(),
1414e5dd7070Spatrick D->getMessage(),
1415e5dd7070Spatrick D->getRParenLoc(),
1416e5dd7070Spatrick D->isFailed());
1417e5dd7070Spatrick }
1418e5dd7070Spatrick
VisitEnumDecl(EnumDecl * D)1419e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
1420e5dd7070Spatrick EnumDecl *PrevDecl = nullptr;
1421e5dd7070Spatrick if (EnumDecl *PatternPrev = getPreviousDeclForInstantiation(D)) {
1422e5dd7070Spatrick NamedDecl *Prev = SemaRef.FindInstantiatedDecl(D->getLocation(),
1423e5dd7070Spatrick PatternPrev,
1424e5dd7070Spatrick TemplateArgs);
1425e5dd7070Spatrick if (!Prev) return nullptr;
1426e5dd7070Spatrick PrevDecl = cast<EnumDecl>(Prev);
1427e5dd7070Spatrick }
1428e5dd7070Spatrick
1429e5dd7070Spatrick EnumDecl *Enum =
1430e5dd7070Spatrick EnumDecl::Create(SemaRef.Context, Owner, D->getBeginLoc(),
1431e5dd7070Spatrick D->getLocation(), D->getIdentifier(), PrevDecl,
1432e5dd7070Spatrick D->isScoped(), D->isScopedUsingClassTag(), D->isFixed());
1433e5dd7070Spatrick if (D->isFixed()) {
1434e5dd7070Spatrick if (TypeSourceInfo *TI = D->getIntegerTypeSourceInfo()) {
1435e5dd7070Spatrick // If we have type source information for the underlying type, it means it
1436e5dd7070Spatrick // has been explicitly set by the user. Perform substitution on it before
1437e5dd7070Spatrick // moving on.
1438e5dd7070Spatrick SourceLocation UnderlyingLoc = TI->getTypeLoc().getBeginLoc();
1439e5dd7070Spatrick TypeSourceInfo *NewTI = SemaRef.SubstType(TI, TemplateArgs, UnderlyingLoc,
1440e5dd7070Spatrick DeclarationName());
1441e5dd7070Spatrick if (!NewTI || SemaRef.CheckEnumUnderlyingType(NewTI))
1442e5dd7070Spatrick Enum->setIntegerType(SemaRef.Context.IntTy);
1443e5dd7070Spatrick else
1444e5dd7070Spatrick Enum->setIntegerTypeSourceInfo(NewTI);
1445e5dd7070Spatrick } else {
1446e5dd7070Spatrick assert(!D->getIntegerType()->isDependentType()
1447e5dd7070Spatrick && "Dependent type without type source info");
1448e5dd7070Spatrick Enum->setIntegerType(D->getIntegerType());
1449e5dd7070Spatrick }
1450e5dd7070Spatrick }
1451e5dd7070Spatrick
1452e5dd7070Spatrick SemaRef.InstantiateAttrs(TemplateArgs, D, Enum);
1453e5dd7070Spatrick
1454e5dd7070Spatrick Enum->setInstantiationOfMemberEnum(D, TSK_ImplicitInstantiation);
1455e5dd7070Spatrick Enum->setAccess(D->getAccess());
1456e5dd7070Spatrick // Forward the mangling number from the template to the instantiated decl.
1457e5dd7070Spatrick SemaRef.Context.setManglingNumber(Enum, SemaRef.Context.getManglingNumber(D));
1458e5dd7070Spatrick // See if the old tag was defined along with a declarator.
1459e5dd7070Spatrick // If it did, mark the new tag as being associated with that declarator.
1460e5dd7070Spatrick if (DeclaratorDecl *DD = SemaRef.Context.getDeclaratorForUnnamedTagDecl(D))
1461e5dd7070Spatrick SemaRef.Context.addDeclaratorForUnnamedTagDecl(Enum, DD);
1462e5dd7070Spatrick // See if the old tag was defined along with a typedef.
1463e5dd7070Spatrick // If it did, mark the new tag as being associated with that typedef.
1464e5dd7070Spatrick if (TypedefNameDecl *TND = SemaRef.Context.getTypedefNameForUnnamedTagDecl(D))
1465e5dd7070Spatrick SemaRef.Context.addTypedefNameForUnnamedTagDecl(Enum, TND);
1466e5dd7070Spatrick if (SubstQualifier(D, Enum)) return nullptr;
1467e5dd7070Spatrick Owner->addDecl(Enum);
1468e5dd7070Spatrick
1469e5dd7070Spatrick EnumDecl *Def = D->getDefinition();
1470e5dd7070Spatrick if (Def && Def != D) {
1471e5dd7070Spatrick // If this is an out-of-line definition of an enum member template, check
1472e5dd7070Spatrick // that the underlying types match in the instantiation of both
1473e5dd7070Spatrick // declarations.
1474e5dd7070Spatrick if (TypeSourceInfo *TI = Def->getIntegerTypeSourceInfo()) {
1475e5dd7070Spatrick SourceLocation UnderlyingLoc = TI->getTypeLoc().getBeginLoc();
1476e5dd7070Spatrick QualType DefnUnderlying =
1477e5dd7070Spatrick SemaRef.SubstType(TI->getType(), TemplateArgs,
1478e5dd7070Spatrick UnderlyingLoc, DeclarationName());
1479e5dd7070Spatrick SemaRef.CheckEnumRedeclaration(Def->getLocation(), Def->isScoped(),
1480e5dd7070Spatrick DefnUnderlying, /*IsFixed=*/true, Enum);
1481e5dd7070Spatrick }
1482e5dd7070Spatrick }
1483e5dd7070Spatrick
1484e5dd7070Spatrick // C++11 [temp.inst]p1: The implicit instantiation of a class template
1485e5dd7070Spatrick // specialization causes the implicit instantiation of the declarations, but
1486e5dd7070Spatrick // not the definitions of scoped member enumerations.
1487e5dd7070Spatrick //
1488e5dd7070Spatrick // DR1484 clarifies that enumeration definitions inside of a template
1489e5dd7070Spatrick // declaration aren't considered entities that can be separately instantiated
1490e5dd7070Spatrick // from the rest of the entity they are declared inside of.
1491e5dd7070Spatrick if (isDeclWithinFunction(D) ? D == Def : Def && !Enum->isScoped()) {
1492e5dd7070Spatrick SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Enum);
1493e5dd7070Spatrick InstantiateEnumDefinition(Enum, Def);
1494e5dd7070Spatrick }
1495e5dd7070Spatrick
1496e5dd7070Spatrick return Enum;
1497e5dd7070Spatrick }
1498e5dd7070Spatrick
InstantiateEnumDefinition(EnumDecl * Enum,EnumDecl * Pattern)1499e5dd7070Spatrick void TemplateDeclInstantiator::InstantiateEnumDefinition(
1500e5dd7070Spatrick EnumDecl *Enum, EnumDecl *Pattern) {
1501e5dd7070Spatrick Enum->startDefinition();
1502e5dd7070Spatrick
1503e5dd7070Spatrick // Update the location to refer to the definition.
1504e5dd7070Spatrick Enum->setLocation(Pattern->getLocation());
1505e5dd7070Spatrick
1506e5dd7070Spatrick SmallVector<Decl*, 4> Enumerators;
1507e5dd7070Spatrick
1508e5dd7070Spatrick EnumConstantDecl *LastEnumConst = nullptr;
1509e5dd7070Spatrick for (auto *EC : Pattern->enumerators()) {
1510e5dd7070Spatrick // The specified value for the enumerator.
1511e5dd7070Spatrick ExprResult Value((Expr *)nullptr);
1512e5dd7070Spatrick if (Expr *UninstValue = EC->getInitExpr()) {
1513e5dd7070Spatrick // The enumerator's value expression is a constant expression.
1514e5dd7070Spatrick EnterExpressionEvaluationContext Unevaluated(
1515e5dd7070Spatrick SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
1516e5dd7070Spatrick
1517e5dd7070Spatrick Value = SemaRef.SubstExpr(UninstValue, TemplateArgs);
1518e5dd7070Spatrick }
1519e5dd7070Spatrick
1520e5dd7070Spatrick // Drop the initial value and continue.
1521e5dd7070Spatrick bool isInvalid = false;
1522e5dd7070Spatrick if (Value.isInvalid()) {
1523e5dd7070Spatrick Value = nullptr;
1524e5dd7070Spatrick isInvalid = true;
1525e5dd7070Spatrick }
1526e5dd7070Spatrick
1527e5dd7070Spatrick EnumConstantDecl *EnumConst
1528e5dd7070Spatrick = SemaRef.CheckEnumConstant(Enum, LastEnumConst,
1529e5dd7070Spatrick EC->getLocation(), EC->getIdentifier(),
1530e5dd7070Spatrick Value.get());
1531e5dd7070Spatrick
1532e5dd7070Spatrick if (isInvalid) {
1533e5dd7070Spatrick if (EnumConst)
1534e5dd7070Spatrick EnumConst->setInvalidDecl();
1535e5dd7070Spatrick Enum->setInvalidDecl();
1536e5dd7070Spatrick }
1537e5dd7070Spatrick
1538e5dd7070Spatrick if (EnumConst) {
1539e5dd7070Spatrick SemaRef.InstantiateAttrs(TemplateArgs, EC, EnumConst);
1540e5dd7070Spatrick
1541e5dd7070Spatrick EnumConst->setAccess(Enum->getAccess());
1542e5dd7070Spatrick Enum->addDecl(EnumConst);
1543e5dd7070Spatrick Enumerators.push_back(EnumConst);
1544e5dd7070Spatrick LastEnumConst = EnumConst;
1545e5dd7070Spatrick
1546e5dd7070Spatrick if (Pattern->getDeclContext()->isFunctionOrMethod() &&
1547e5dd7070Spatrick !Enum->isScoped()) {
1548e5dd7070Spatrick // If the enumeration is within a function or method, record the enum
1549e5dd7070Spatrick // constant as a local.
1550e5dd7070Spatrick SemaRef.CurrentInstantiationScope->InstantiatedLocal(EC, EnumConst);
1551e5dd7070Spatrick }
1552e5dd7070Spatrick }
1553e5dd7070Spatrick }
1554e5dd7070Spatrick
1555e5dd7070Spatrick SemaRef.ActOnEnumBody(Enum->getLocation(), Enum->getBraceRange(), Enum,
1556e5dd7070Spatrick Enumerators, nullptr, ParsedAttributesView());
1557e5dd7070Spatrick }
1558e5dd7070Spatrick
VisitEnumConstantDecl(EnumConstantDecl * D)1559e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitEnumConstantDecl(EnumConstantDecl *D) {
1560e5dd7070Spatrick llvm_unreachable("EnumConstantDecls can only occur within EnumDecls.");
1561e5dd7070Spatrick }
1562e5dd7070Spatrick
1563e5dd7070Spatrick Decl *
VisitBuiltinTemplateDecl(BuiltinTemplateDecl * D)1564e5dd7070Spatrick TemplateDeclInstantiator::VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D) {
1565e5dd7070Spatrick llvm_unreachable("BuiltinTemplateDecls cannot be instantiated.");
1566e5dd7070Spatrick }
1567e5dd7070Spatrick
VisitClassTemplateDecl(ClassTemplateDecl * D)1568e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
1569e5dd7070Spatrick bool isFriend = (D->getFriendObjectKind() != Decl::FOK_None);
1570e5dd7070Spatrick
1571e5dd7070Spatrick // Create a local instantiation scope for this class template, which
1572e5dd7070Spatrick // will contain the instantiations of the template parameters.
1573e5dd7070Spatrick LocalInstantiationScope Scope(SemaRef);
1574e5dd7070Spatrick TemplateParameterList *TempParams = D->getTemplateParameters();
1575e5dd7070Spatrick TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
1576e5dd7070Spatrick if (!InstParams)
1577e5dd7070Spatrick return nullptr;
1578e5dd7070Spatrick
1579e5dd7070Spatrick CXXRecordDecl *Pattern = D->getTemplatedDecl();
1580e5dd7070Spatrick
1581e5dd7070Spatrick // Instantiate the qualifier. We have to do this first in case
1582e5dd7070Spatrick // we're a friend declaration, because if we are then we need to put
1583e5dd7070Spatrick // the new declaration in the appropriate context.
1584e5dd7070Spatrick NestedNameSpecifierLoc QualifierLoc = Pattern->getQualifierLoc();
1585e5dd7070Spatrick if (QualifierLoc) {
1586e5dd7070Spatrick QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc,
1587e5dd7070Spatrick TemplateArgs);
1588e5dd7070Spatrick if (!QualifierLoc)
1589e5dd7070Spatrick return nullptr;
1590e5dd7070Spatrick }
1591e5dd7070Spatrick
1592e5dd7070Spatrick CXXRecordDecl *PrevDecl = nullptr;
1593e5dd7070Spatrick ClassTemplateDecl *PrevClassTemplate = nullptr;
1594e5dd7070Spatrick
1595e5dd7070Spatrick if (!isFriend && getPreviousDeclForInstantiation(Pattern)) {
1596e5dd7070Spatrick DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName());
1597e5dd7070Spatrick if (!Found.empty()) {
1598e5dd7070Spatrick PrevClassTemplate = dyn_cast<ClassTemplateDecl>(Found.front());
1599e5dd7070Spatrick if (PrevClassTemplate)
1600e5dd7070Spatrick PrevDecl = PrevClassTemplate->getTemplatedDecl();
1601e5dd7070Spatrick }
1602e5dd7070Spatrick }
1603e5dd7070Spatrick
1604e5dd7070Spatrick // If this isn't a friend, then it's a member template, in which
1605e5dd7070Spatrick // case we just want to build the instantiation in the
1606e5dd7070Spatrick // specialization. If it is a friend, we want to build it in
1607e5dd7070Spatrick // the appropriate context.
1608e5dd7070Spatrick DeclContext *DC = Owner;
1609e5dd7070Spatrick if (isFriend) {
1610e5dd7070Spatrick if (QualifierLoc) {
1611e5dd7070Spatrick CXXScopeSpec SS;
1612e5dd7070Spatrick SS.Adopt(QualifierLoc);
1613e5dd7070Spatrick DC = SemaRef.computeDeclContext(SS);
1614e5dd7070Spatrick if (!DC) return nullptr;
1615e5dd7070Spatrick } else {
1616e5dd7070Spatrick DC = SemaRef.FindInstantiatedContext(Pattern->getLocation(),
1617e5dd7070Spatrick Pattern->getDeclContext(),
1618e5dd7070Spatrick TemplateArgs);
1619e5dd7070Spatrick }
1620e5dd7070Spatrick
1621e5dd7070Spatrick // Look for a previous declaration of the template in the owning
1622e5dd7070Spatrick // context.
1623e5dd7070Spatrick LookupResult R(SemaRef, Pattern->getDeclName(), Pattern->getLocation(),
1624e5dd7070Spatrick Sema::LookupOrdinaryName,
1625e5dd7070Spatrick SemaRef.forRedeclarationInCurContext());
1626e5dd7070Spatrick SemaRef.LookupQualifiedName(R, DC);
1627e5dd7070Spatrick
1628e5dd7070Spatrick if (R.isSingleResult()) {
1629e5dd7070Spatrick PrevClassTemplate = R.getAsSingle<ClassTemplateDecl>();
1630e5dd7070Spatrick if (PrevClassTemplate)
1631e5dd7070Spatrick PrevDecl = PrevClassTemplate->getTemplatedDecl();
1632e5dd7070Spatrick }
1633e5dd7070Spatrick
1634e5dd7070Spatrick if (!PrevClassTemplate && QualifierLoc) {
1635e5dd7070Spatrick SemaRef.Diag(Pattern->getLocation(), diag::err_not_tag_in_scope)
1636e5dd7070Spatrick << D->getTemplatedDecl()->getTagKind() << Pattern->getDeclName() << DC
1637e5dd7070Spatrick << QualifierLoc.getSourceRange();
1638e5dd7070Spatrick return nullptr;
1639e5dd7070Spatrick }
1640e5dd7070Spatrick
1641e5dd7070Spatrick if (PrevClassTemplate) {
1642*12c85518Srobert const ClassTemplateDecl *MostRecentPrevCT =
1643*12c85518Srobert PrevClassTemplate->getMostRecentDecl();
1644*12c85518Srobert TemplateParameterList *PrevParams =
1645*12c85518Srobert MostRecentPrevCT->getTemplateParameters();
1646e5dd7070Spatrick
1647e5dd7070Spatrick // Make sure the parameter lists match.
1648*12c85518Srobert if (!SemaRef.TemplateParameterListsAreEqual(
1649*12c85518Srobert D->getTemplatedDecl(), InstParams,
1650*12c85518Srobert MostRecentPrevCT->getTemplatedDecl(), PrevParams, true,
1651a9ac8606Spatrick Sema::TPL_TemplateMatch))
1652e5dd7070Spatrick return nullptr;
1653e5dd7070Spatrick
1654e5dd7070Spatrick // Do some additional validation, then merge default arguments
1655e5dd7070Spatrick // from the existing declarations.
1656a9ac8606Spatrick if (SemaRef.CheckTemplateParameterList(InstParams, PrevParams,
1657e5dd7070Spatrick Sema::TPC_ClassTemplate))
1658e5dd7070Spatrick return nullptr;
1659e5dd7070Spatrick }
1660e5dd7070Spatrick }
1661e5dd7070Spatrick
1662e5dd7070Spatrick CXXRecordDecl *RecordInst = CXXRecordDecl::Create(
1663e5dd7070Spatrick SemaRef.Context, Pattern->getTagKind(), DC, Pattern->getBeginLoc(),
1664e5dd7070Spatrick Pattern->getLocation(), Pattern->getIdentifier(), PrevDecl,
1665e5dd7070Spatrick /*DelayTypeCreation=*/true);
1666e5dd7070Spatrick
1667e5dd7070Spatrick if (QualifierLoc)
1668e5dd7070Spatrick RecordInst->setQualifierInfo(QualifierLoc);
1669e5dd7070Spatrick
1670e5dd7070Spatrick SemaRef.InstantiateAttrsForDecl(TemplateArgs, Pattern, RecordInst, LateAttrs,
1671e5dd7070Spatrick StartingScope);
1672e5dd7070Spatrick
1673e5dd7070Spatrick ClassTemplateDecl *Inst
1674e5dd7070Spatrick = ClassTemplateDecl::Create(SemaRef.Context, DC, D->getLocation(),
1675e5dd7070Spatrick D->getIdentifier(), InstParams, RecordInst);
1676e5dd7070Spatrick assert(!(isFriend && Owner->isDependentContext()));
1677e5dd7070Spatrick Inst->setPreviousDecl(PrevClassTemplate);
1678e5dd7070Spatrick
1679e5dd7070Spatrick RecordInst->setDescribedClassTemplate(Inst);
1680e5dd7070Spatrick
1681e5dd7070Spatrick if (isFriend) {
1682e5dd7070Spatrick if (PrevClassTemplate)
1683e5dd7070Spatrick Inst->setAccess(PrevClassTemplate->getAccess());
1684e5dd7070Spatrick else
1685e5dd7070Spatrick Inst->setAccess(D->getAccess());
1686e5dd7070Spatrick
1687e5dd7070Spatrick Inst->setObjectOfFriendDecl();
1688e5dd7070Spatrick // TODO: do we want to track the instantiation progeny of this
1689e5dd7070Spatrick // friend target decl?
1690e5dd7070Spatrick } else {
1691e5dd7070Spatrick Inst->setAccess(D->getAccess());
1692e5dd7070Spatrick if (!PrevClassTemplate)
1693e5dd7070Spatrick Inst->setInstantiatedFromMemberTemplate(D);
1694e5dd7070Spatrick }
1695e5dd7070Spatrick
1696e5dd7070Spatrick // Trigger creation of the type for the instantiation.
1697e5dd7070Spatrick SemaRef.Context.getInjectedClassNameType(RecordInst,
1698e5dd7070Spatrick Inst->getInjectedClassNameSpecialization());
1699e5dd7070Spatrick
1700e5dd7070Spatrick // Finish handling of friends.
1701e5dd7070Spatrick if (isFriend) {
1702e5dd7070Spatrick DC->makeDeclVisibleInContext(Inst);
1703e5dd7070Spatrick Inst->setLexicalDeclContext(Owner);
1704e5dd7070Spatrick RecordInst->setLexicalDeclContext(Owner);
1705e5dd7070Spatrick return Inst;
1706e5dd7070Spatrick }
1707e5dd7070Spatrick
1708e5dd7070Spatrick if (D->isOutOfLine()) {
1709e5dd7070Spatrick Inst->setLexicalDeclContext(D->getLexicalDeclContext());
1710e5dd7070Spatrick RecordInst->setLexicalDeclContext(D->getLexicalDeclContext());
1711e5dd7070Spatrick }
1712e5dd7070Spatrick
1713e5dd7070Spatrick Owner->addDecl(Inst);
1714e5dd7070Spatrick
1715e5dd7070Spatrick if (!PrevClassTemplate) {
1716e5dd7070Spatrick // Queue up any out-of-line partial specializations of this member
1717e5dd7070Spatrick // class template; the client will force their instantiation once
1718e5dd7070Spatrick // the enclosing class has been instantiated.
1719e5dd7070Spatrick SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs;
1720e5dd7070Spatrick D->getPartialSpecializations(PartialSpecs);
1721e5dd7070Spatrick for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I)
1722e5dd7070Spatrick if (PartialSpecs[I]->getFirstDecl()->isOutOfLine())
1723e5dd7070Spatrick OutOfLinePartialSpecs.push_back(std::make_pair(Inst, PartialSpecs[I]));
1724e5dd7070Spatrick }
1725e5dd7070Spatrick
1726e5dd7070Spatrick return Inst;
1727e5dd7070Spatrick }
1728e5dd7070Spatrick
1729e5dd7070Spatrick Decl *
VisitClassTemplatePartialSpecializationDecl(ClassTemplatePartialSpecializationDecl * D)1730e5dd7070Spatrick TemplateDeclInstantiator::VisitClassTemplatePartialSpecializationDecl(
1731e5dd7070Spatrick ClassTemplatePartialSpecializationDecl *D) {
1732e5dd7070Spatrick ClassTemplateDecl *ClassTemplate = D->getSpecializedTemplate();
1733e5dd7070Spatrick
1734e5dd7070Spatrick // Lookup the already-instantiated declaration in the instantiation
1735e5dd7070Spatrick // of the class template and return that.
1736e5dd7070Spatrick DeclContext::lookup_result Found
1737e5dd7070Spatrick = Owner->lookup(ClassTemplate->getDeclName());
1738e5dd7070Spatrick if (Found.empty())
1739e5dd7070Spatrick return nullptr;
1740e5dd7070Spatrick
1741e5dd7070Spatrick ClassTemplateDecl *InstClassTemplate
1742e5dd7070Spatrick = dyn_cast<ClassTemplateDecl>(Found.front());
1743e5dd7070Spatrick if (!InstClassTemplate)
1744e5dd7070Spatrick return nullptr;
1745e5dd7070Spatrick
1746e5dd7070Spatrick if (ClassTemplatePartialSpecializationDecl *Result
1747e5dd7070Spatrick = InstClassTemplate->findPartialSpecInstantiatedFromMember(D))
1748e5dd7070Spatrick return Result;
1749e5dd7070Spatrick
1750e5dd7070Spatrick return InstantiateClassTemplatePartialSpecialization(InstClassTemplate, D);
1751e5dd7070Spatrick }
1752e5dd7070Spatrick
VisitVarTemplateDecl(VarTemplateDecl * D)1753e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitVarTemplateDecl(VarTemplateDecl *D) {
1754e5dd7070Spatrick assert(D->getTemplatedDecl()->isStaticDataMember() &&
1755e5dd7070Spatrick "Only static data member templates are allowed.");
1756e5dd7070Spatrick
1757e5dd7070Spatrick // Create a local instantiation scope for this variable template, which
1758e5dd7070Spatrick // will contain the instantiations of the template parameters.
1759e5dd7070Spatrick LocalInstantiationScope Scope(SemaRef);
1760e5dd7070Spatrick TemplateParameterList *TempParams = D->getTemplateParameters();
1761e5dd7070Spatrick TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
1762e5dd7070Spatrick if (!InstParams)
1763e5dd7070Spatrick return nullptr;
1764e5dd7070Spatrick
1765e5dd7070Spatrick VarDecl *Pattern = D->getTemplatedDecl();
1766e5dd7070Spatrick VarTemplateDecl *PrevVarTemplate = nullptr;
1767e5dd7070Spatrick
1768e5dd7070Spatrick if (getPreviousDeclForInstantiation(Pattern)) {
1769e5dd7070Spatrick DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName());
1770e5dd7070Spatrick if (!Found.empty())
1771e5dd7070Spatrick PrevVarTemplate = dyn_cast<VarTemplateDecl>(Found.front());
1772e5dd7070Spatrick }
1773e5dd7070Spatrick
1774e5dd7070Spatrick VarDecl *VarInst =
1775e5dd7070Spatrick cast_or_null<VarDecl>(VisitVarDecl(Pattern,
1776e5dd7070Spatrick /*InstantiatingVarTemplate=*/true));
1777e5dd7070Spatrick if (!VarInst) return nullptr;
1778e5dd7070Spatrick
1779e5dd7070Spatrick DeclContext *DC = Owner;
1780e5dd7070Spatrick
1781e5dd7070Spatrick VarTemplateDecl *Inst = VarTemplateDecl::Create(
1782e5dd7070Spatrick SemaRef.Context, DC, D->getLocation(), D->getIdentifier(), InstParams,
1783e5dd7070Spatrick VarInst);
1784e5dd7070Spatrick VarInst->setDescribedVarTemplate(Inst);
1785e5dd7070Spatrick Inst->setPreviousDecl(PrevVarTemplate);
1786e5dd7070Spatrick
1787e5dd7070Spatrick Inst->setAccess(D->getAccess());
1788e5dd7070Spatrick if (!PrevVarTemplate)
1789e5dd7070Spatrick Inst->setInstantiatedFromMemberTemplate(D);
1790e5dd7070Spatrick
1791e5dd7070Spatrick if (D->isOutOfLine()) {
1792e5dd7070Spatrick Inst->setLexicalDeclContext(D->getLexicalDeclContext());
1793e5dd7070Spatrick VarInst->setLexicalDeclContext(D->getLexicalDeclContext());
1794e5dd7070Spatrick }
1795e5dd7070Spatrick
1796e5dd7070Spatrick Owner->addDecl(Inst);
1797e5dd7070Spatrick
1798e5dd7070Spatrick if (!PrevVarTemplate) {
1799e5dd7070Spatrick // Queue up any out-of-line partial specializations of this member
1800e5dd7070Spatrick // variable template; the client will force their instantiation once
1801e5dd7070Spatrick // the enclosing class has been instantiated.
1802e5dd7070Spatrick SmallVector<VarTemplatePartialSpecializationDecl *, 4> PartialSpecs;
1803e5dd7070Spatrick D->getPartialSpecializations(PartialSpecs);
1804e5dd7070Spatrick for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I)
1805e5dd7070Spatrick if (PartialSpecs[I]->getFirstDecl()->isOutOfLine())
1806e5dd7070Spatrick OutOfLineVarPartialSpecs.push_back(
1807e5dd7070Spatrick std::make_pair(Inst, PartialSpecs[I]));
1808e5dd7070Spatrick }
1809e5dd7070Spatrick
1810e5dd7070Spatrick return Inst;
1811e5dd7070Spatrick }
1812e5dd7070Spatrick
VisitVarTemplatePartialSpecializationDecl(VarTemplatePartialSpecializationDecl * D)1813e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitVarTemplatePartialSpecializationDecl(
1814e5dd7070Spatrick VarTemplatePartialSpecializationDecl *D) {
1815e5dd7070Spatrick assert(D->isStaticDataMember() &&
1816e5dd7070Spatrick "Only static data member templates are allowed.");
1817e5dd7070Spatrick
1818e5dd7070Spatrick VarTemplateDecl *VarTemplate = D->getSpecializedTemplate();
1819e5dd7070Spatrick
1820e5dd7070Spatrick // Lookup the already-instantiated declaration and return that.
1821e5dd7070Spatrick DeclContext::lookup_result Found = Owner->lookup(VarTemplate->getDeclName());
1822e5dd7070Spatrick assert(!Found.empty() && "Instantiation found nothing?");
1823e5dd7070Spatrick
1824e5dd7070Spatrick VarTemplateDecl *InstVarTemplate = dyn_cast<VarTemplateDecl>(Found.front());
1825e5dd7070Spatrick assert(InstVarTemplate && "Instantiation did not find a variable template?");
1826e5dd7070Spatrick
1827e5dd7070Spatrick if (VarTemplatePartialSpecializationDecl *Result =
1828e5dd7070Spatrick InstVarTemplate->findPartialSpecInstantiatedFromMember(D))
1829e5dd7070Spatrick return Result;
1830e5dd7070Spatrick
1831e5dd7070Spatrick return InstantiateVarTemplatePartialSpecialization(InstVarTemplate, D);
1832e5dd7070Spatrick }
1833e5dd7070Spatrick
1834e5dd7070Spatrick Decl *
VisitFunctionTemplateDecl(FunctionTemplateDecl * D)1835e5dd7070Spatrick TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
1836e5dd7070Spatrick // Create a local instantiation scope for this function template, which
1837e5dd7070Spatrick // will contain the instantiations of the template parameters and then get
1838e5dd7070Spatrick // merged with the local instantiation scope for the function template
1839e5dd7070Spatrick // itself.
1840e5dd7070Spatrick LocalInstantiationScope Scope(SemaRef);
1841*12c85518Srobert Sema::ConstraintEvalRAII<TemplateDeclInstantiator> RAII(*this);
1842e5dd7070Spatrick
1843e5dd7070Spatrick TemplateParameterList *TempParams = D->getTemplateParameters();
1844e5dd7070Spatrick TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
1845e5dd7070Spatrick if (!InstParams)
1846e5dd7070Spatrick return nullptr;
1847e5dd7070Spatrick
1848e5dd7070Spatrick FunctionDecl *Instantiated = nullptr;
1849e5dd7070Spatrick if (CXXMethodDecl *DMethod = dyn_cast<CXXMethodDecl>(D->getTemplatedDecl()))
1850e5dd7070Spatrick Instantiated = cast_or_null<FunctionDecl>(VisitCXXMethodDecl(DMethod,
1851e5dd7070Spatrick InstParams));
1852e5dd7070Spatrick else
1853e5dd7070Spatrick Instantiated = cast_or_null<FunctionDecl>(VisitFunctionDecl(
1854e5dd7070Spatrick D->getTemplatedDecl(),
1855e5dd7070Spatrick InstParams));
1856e5dd7070Spatrick
1857e5dd7070Spatrick if (!Instantiated)
1858e5dd7070Spatrick return nullptr;
1859e5dd7070Spatrick
1860e5dd7070Spatrick // Link the instantiated function template declaration to the function
1861e5dd7070Spatrick // template from which it was instantiated.
1862e5dd7070Spatrick FunctionTemplateDecl *InstTemplate
1863e5dd7070Spatrick = Instantiated->getDescribedFunctionTemplate();
1864e5dd7070Spatrick InstTemplate->setAccess(D->getAccess());
1865e5dd7070Spatrick assert(InstTemplate &&
1866e5dd7070Spatrick "VisitFunctionDecl/CXXMethodDecl didn't create a template!");
1867e5dd7070Spatrick
1868e5dd7070Spatrick bool isFriend = (InstTemplate->getFriendObjectKind() != Decl::FOK_None);
1869e5dd7070Spatrick
1870e5dd7070Spatrick // Link the instantiation back to the pattern *unless* this is a
1871e5dd7070Spatrick // non-definition friend declaration.
1872e5dd7070Spatrick if (!InstTemplate->getInstantiatedFromMemberTemplate() &&
1873e5dd7070Spatrick !(isFriend && !D->getTemplatedDecl()->isThisDeclarationADefinition()))
1874e5dd7070Spatrick InstTemplate->setInstantiatedFromMemberTemplate(D);
1875e5dd7070Spatrick
1876e5dd7070Spatrick // Make declarations visible in the appropriate context.
1877e5dd7070Spatrick if (!isFriend) {
1878e5dd7070Spatrick Owner->addDecl(InstTemplate);
1879e5dd7070Spatrick } else if (InstTemplate->getDeclContext()->isRecord() &&
1880e5dd7070Spatrick !getPreviousDeclForInstantiation(D)) {
1881e5dd7070Spatrick SemaRef.CheckFriendAccess(InstTemplate);
1882e5dd7070Spatrick }
1883e5dd7070Spatrick
1884e5dd7070Spatrick return InstTemplate;
1885e5dd7070Spatrick }
1886e5dd7070Spatrick
VisitCXXRecordDecl(CXXRecordDecl * D)1887e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
1888e5dd7070Spatrick CXXRecordDecl *PrevDecl = nullptr;
1889*12c85518Srobert if (CXXRecordDecl *PatternPrev = getPreviousDeclForInstantiation(D)) {
1890e5dd7070Spatrick NamedDecl *Prev = SemaRef.FindInstantiatedDecl(D->getLocation(),
1891e5dd7070Spatrick PatternPrev,
1892e5dd7070Spatrick TemplateArgs);
1893e5dd7070Spatrick if (!Prev) return nullptr;
1894e5dd7070Spatrick PrevDecl = cast<CXXRecordDecl>(Prev);
1895e5dd7070Spatrick }
1896e5dd7070Spatrick
1897a9ac8606Spatrick CXXRecordDecl *Record = nullptr;
1898*12c85518Srobert bool IsInjectedClassName = D->isInjectedClassName();
1899a9ac8606Spatrick if (D->isLambda())
1900a9ac8606Spatrick Record = CXXRecordDecl::CreateLambda(
1901a9ac8606Spatrick SemaRef.Context, Owner, D->getLambdaTypeInfo(), D->getLocation(),
1902*12c85518Srobert D->getLambdaDependencyKind(), D->isGenericLambda(),
1903a9ac8606Spatrick D->getLambdaCaptureDefault());
1904a9ac8606Spatrick else
1905a9ac8606Spatrick Record = CXXRecordDecl::Create(SemaRef.Context, D->getTagKind(), Owner,
1906a9ac8606Spatrick D->getBeginLoc(), D->getLocation(),
1907*12c85518Srobert D->getIdentifier(), PrevDecl,
1908*12c85518Srobert /*DelayTypeCreation=*/IsInjectedClassName);
1909*12c85518Srobert // Link the type of the injected-class-name to that of the outer class.
1910*12c85518Srobert if (IsInjectedClassName)
1911*12c85518Srobert (void)SemaRef.Context.getTypeDeclType(Record, cast<CXXRecordDecl>(Owner));
1912e5dd7070Spatrick
1913e5dd7070Spatrick // Substitute the nested name specifier, if any.
1914e5dd7070Spatrick if (SubstQualifier(D, Record))
1915e5dd7070Spatrick return nullptr;
1916e5dd7070Spatrick
1917e5dd7070Spatrick SemaRef.InstantiateAttrsForDecl(TemplateArgs, D, Record, LateAttrs,
1918e5dd7070Spatrick StartingScope);
1919e5dd7070Spatrick
1920e5dd7070Spatrick Record->setImplicit(D->isImplicit());
1921e5dd7070Spatrick // FIXME: Check against AS_none is an ugly hack to work around the issue that
1922e5dd7070Spatrick // the tag decls introduced by friend class declarations don't have an access
1923e5dd7070Spatrick // specifier. Remove once this area of the code gets sorted out.
1924e5dd7070Spatrick if (D->getAccess() != AS_none)
1925e5dd7070Spatrick Record->setAccess(D->getAccess());
1926*12c85518Srobert if (!IsInjectedClassName)
1927e5dd7070Spatrick Record->setInstantiationOfMemberClass(D, TSK_ImplicitInstantiation);
1928e5dd7070Spatrick
1929e5dd7070Spatrick // If the original function was part of a friend declaration,
1930e5dd7070Spatrick // inherit its namespace state.
1931e5dd7070Spatrick if (D->getFriendObjectKind())
1932e5dd7070Spatrick Record->setObjectOfFriendDecl();
1933e5dd7070Spatrick
1934e5dd7070Spatrick // Make sure that anonymous structs and unions are recorded.
1935e5dd7070Spatrick if (D->isAnonymousStructOrUnion())
1936e5dd7070Spatrick Record->setAnonymousStructOrUnion(true);
1937e5dd7070Spatrick
1938e5dd7070Spatrick if (D->isLocalClass())
1939e5dd7070Spatrick SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Record);
1940e5dd7070Spatrick
1941e5dd7070Spatrick // Forward the mangling number from the template to the instantiated decl.
1942e5dd7070Spatrick SemaRef.Context.setManglingNumber(Record,
1943e5dd7070Spatrick SemaRef.Context.getManglingNumber(D));
1944e5dd7070Spatrick
1945e5dd7070Spatrick // See if the old tag was defined along with a declarator.
1946e5dd7070Spatrick // If it did, mark the new tag as being associated with that declarator.
1947e5dd7070Spatrick if (DeclaratorDecl *DD = SemaRef.Context.getDeclaratorForUnnamedTagDecl(D))
1948e5dd7070Spatrick SemaRef.Context.addDeclaratorForUnnamedTagDecl(Record, DD);
1949e5dd7070Spatrick
1950e5dd7070Spatrick // See if the old tag was defined along with a typedef.
1951e5dd7070Spatrick // If it did, mark the new tag as being associated with that typedef.
1952e5dd7070Spatrick if (TypedefNameDecl *TND = SemaRef.Context.getTypedefNameForUnnamedTagDecl(D))
1953e5dd7070Spatrick SemaRef.Context.addTypedefNameForUnnamedTagDecl(Record, TND);
1954e5dd7070Spatrick
1955e5dd7070Spatrick Owner->addDecl(Record);
1956e5dd7070Spatrick
1957e5dd7070Spatrick // DR1484 clarifies that the members of a local class are instantiated as part
1958e5dd7070Spatrick // of the instantiation of their enclosing entity.
1959e5dd7070Spatrick if (D->isCompleteDefinition() && D->isLocalClass()) {
1960e5dd7070Spatrick Sema::LocalEagerInstantiationScope LocalInstantiations(SemaRef);
1961e5dd7070Spatrick
1962e5dd7070Spatrick SemaRef.InstantiateClass(D->getLocation(), Record, D, TemplateArgs,
1963e5dd7070Spatrick TSK_ImplicitInstantiation,
1964e5dd7070Spatrick /*Complain=*/true);
1965e5dd7070Spatrick
1966e5dd7070Spatrick // For nested local classes, we will instantiate the members when we
1967e5dd7070Spatrick // reach the end of the outermost (non-nested) local class.
1968e5dd7070Spatrick if (!D->isCXXClassMember())
1969e5dd7070Spatrick SemaRef.InstantiateClassMembers(D->getLocation(), Record, TemplateArgs,
1970e5dd7070Spatrick TSK_ImplicitInstantiation);
1971e5dd7070Spatrick
1972e5dd7070Spatrick // This class may have local implicit instantiations that need to be
1973e5dd7070Spatrick // performed within this scope.
1974e5dd7070Spatrick LocalInstantiations.perform();
1975e5dd7070Spatrick }
1976e5dd7070Spatrick
1977e5dd7070Spatrick SemaRef.DiagnoseUnusedNestedTypedefs(Record);
1978e5dd7070Spatrick
1979*12c85518Srobert if (IsInjectedClassName)
1980*12c85518Srobert assert(Record->isInjectedClassName() && "Broken injected-class-name");
1981*12c85518Srobert
1982e5dd7070Spatrick return Record;
1983e5dd7070Spatrick }
1984e5dd7070Spatrick
1985e5dd7070Spatrick /// Adjust the given function type for an instantiation of the
1986e5dd7070Spatrick /// given declaration, to cope with modifications to the function's type that
1987e5dd7070Spatrick /// aren't reflected in the type-source information.
1988e5dd7070Spatrick ///
1989e5dd7070Spatrick /// \param D The declaration we're instantiating.
1990e5dd7070Spatrick /// \param TInfo The already-instantiated type.
adjustFunctionTypeForInstantiation(ASTContext & Context,FunctionDecl * D,TypeSourceInfo * TInfo)1991e5dd7070Spatrick static QualType adjustFunctionTypeForInstantiation(ASTContext &Context,
1992e5dd7070Spatrick FunctionDecl *D,
1993e5dd7070Spatrick TypeSourceInfo *TInfo) {
1994e5dd7070Spatrick const FunctionProtoType *OrigFunc
1995e5dd7070Spatrick = D->getType()->castAs<FunctionProtoType>();
1996e5dd7070Spatrick const FunctionProtoType *NewFunc
1997e5dd7070Spatrick = TInfo->getType()->castAs<FunctionProtoType>();
1998e5dd7070Spatrick if (OrigFunc->getExtInfo() == NewFunc->getExtInfo())
1999e5dd7070Spatrick return TInfo->getType();
2000e5dd7070Spatrick
2001e5dd7070Spatrick FunctionProtoType::ExtProtoInfo NewEPI = NewFunc->getExtProtoInfo();
2002e5dd7070Spatrick NewEPI.ExtInfo = OrigFunc->getExtInfo();
2003e5dd7070Spatrick return Context.getFunctionType(NewFunc->getReturnType(),
2004e5dd7070Spatrick NewFunc->getParamTypes(), NewEPI);
2005e5dd7070Spatrick }
2006e5dd7070Spatrick
2007e5dd7070Spatrick /// Normal class members are of more specific types and therefore
2008e5dd7070Spatrick /// don't make it here. This function serves three purposes:
2009e5dd7070Spatrick /// 1) instantiating function templates
2010*12c85518Srobert /// 2) substituting friend and local function declarations
2011e5dd7070Spatrick /// 3) substituting deduction guide declarations for nested class templates
VisitFunctionDecl(FunctionDecl * D,TemplateParameterList * TemplateParams,RewriteKind FunctionRewriteKind)2012e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitFunctionDecl(
2013e5dd7070Spatrick FunctionDecl *D, TemplateParameterList *TemplateParams,
2014e5dd7070Spatrick RewriteKind FunctionRewriteKind) {
2015e5dd7070Spatrick // Check whether there is already a function template specialization for
2016e5dd7070Spatrick // this declaration.
2017e5dd7070Spatrick FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate();
2018e5dd7070Spatrick if (FunctionTemplate && !TemplateParams) {
2019e5dd7070Spatrick ArrayRef<TemplateArgument> Innermost = TemplateArgs.getInnermost();
2020e5dd7070Spatrick
2021e5dd7070Spatrick void *InsertPos = nullptr;
2022e5dd7070Spatrick FunctionDecl *SpecFunc
2023e5dd7070Spatrick = FunctionTemplate->findSpecialization(Innermost, InsertPos);
2024e5dd7070Spatrick
2025e5dd7070Spatrick // If we already have a function template specialization, return it.
2026e5dd7070Spatrick if (SpecFunc)
2027e5dd7070Spatrick return SpecFunc;
2028e5dd7070Spatrick }
2029e5dd7070Spatrick
2030e5dd7070Spatrick bool isFriend;
2031e5dd7070Spatrick if (FunctionTemplate)
2032e5dd7070Spatrick isFriend = (FunctionTemplate->getFriendObjectKind() != Decl::FOK_None);
2033e5dd7070Spatrick else
2034e5dd7070Spatrick isFriend = (D->getFriendObjectKind() != Decl::FOK_None);
2035e5dd7070Spatrick
2036e5dd7070Spatrick bool MergeWithParentScope = (TemplateParams != nullptr) ||
2037e5dd7070Spatrick Owner->isFunctionOrMethod() ||
2038e5dd7070Spatrick !(isa<Decl>(Owner) &&
2039e5dd7070Spatrick cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod());
2040e5dd7070Spatrick LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
2041e5dd7070Spatrick
2042e5dd7070Spatrick ExplicitSpecifier InstantiatedExplicitSpecifier;
2043e5dd7070Spatrick if (auto *DGuide = dyn_cast<CXXDeductionGuideDecl>(D)) {
2044e5dd7070Spatrick InstantiatedExplicitSpecifier = instantiateExplicitSpecifier(
2045e5dd7070Spatrick SemaRef, TemplateArgs, DGuide->getExplicitSpecifier(), DGuide);
2046e5dd7070Spatrick if (InstantiatedExplicitSpecifier.isInvalid())
2047e5dd7070Spatrick return nullptr;
2048e5dd7070Spatrick }
2049e5dd7070Spatrick
2050e5dd7070Spatrick SmallVector<ParmVarDecl *, 4> Params;
2051e5dd7070Spatrick TypeSourceInfo *TInfo = SubstFunctionType(D, Params);
2052e5dd7070Spatrick if (!TInfo)
2053e5dd7070Spatrick return nullptr;
2054e5dd7070Spatrick QualType T = adjustFunctionTypeForInstantiation(SemaRef.Context, D, TInfo);
2055e5dd7070Spatrick
2056e5dd7070Spatrick if (TemplateParams && TemplateParams->size()) {
2057e5dd7070Spatrick auto *LastParam =
2058e5dd7070Spatrick dyn_cast<TemplateTypeParmDecl>(TemplateParams->asArray().back());
2059e5dd7070Spatrick if (LastParam && LastParam->isImplicit() &&
2060e5dd7070Spatrick LastParam->hasTypeConstraint()) {
2061e5dd7070Spatrick // In abbreviated templates, the type-constraints of invented template
2062e5dd7070Spatrick // type parameters are instantiated with the function type, invalidating
2063e5dd7070Spatrick // the TemplateParameterList which relied on the template type parameter
2064e5dd7070Spatrick // not having a type constraint. Recreate the TemplateParameterList with
2065e5dd7070Spatrick // the updated parameter list.
2066e5dd7070Spatrick TemplateParams = TemplateParameterList::Create(
2067e5dd7070Spatrick SemaRef.Context, TemplateParams->getTemplateLoc(),
2068e5dd7070Spatrick TemplateParams->getLAngleLoc(), TemplateParams->asArray(),
2069e5dd7070Spatrick TemplateParams->getRAngleLoc(), TemplateParams->getRequiresClause());
2070e5dd7070Spatrick }
2071e5dd7070Spatrick }
2072e5dd7070Spatrick
2073e5dd7070Spatrick NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc();
2074e5dd7070Spatrick if (QualifierLoc) {
2075e5dd7070Spatrick QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc,
2076e5dd7070Spatrick TemplateArgs);
2077e5dd7070Spatrick if (!QualifierLoc)
2078e5dd7070Spatrick return nullptr;
2079e5dd7070Spatrick }
2080e5dd7070Spatrick
2081e5dd7070Spatrick Expr *TrailingRequiresClause = D->getTrailingRequiresClause();
2082e5dd7070Spatrick
2083e5dd7070Spatrick // If we're instantiating a local function declaration, put the result
2084e5dd7070Spatrick // in the enclosing namespace; otherwise we need to find the instantiated
2085e5dd7070Spatrick // context.
2086e5dd7070Spatrick DeclContext *DC;
2087e5dd7070Spatrick if (D->isLocalExternDecl()) {
2088e5dd7070Spatrick DC = Owner;
2089e5dd7070Spatrick SemaRef.adjustContextForLocalExternDecl(DC);
2090e5dd7070Spatrick } else if (isFriend && QualifierLoc) {
2091e5dd7070Spatrick CXXScopeSpec SS;
2092e5dd7070Spatrick SS.Adopt(QualifierLoc);
2093e5dd7070Spatrick DC = SemaRef.computeDeclContext(SS);
2094e5dd7070Spatrick if (!DC) return nullptr;
2095e5dd7070Spatrick } else {
2096e5dd7070Spatrick DC = SemaRef.FindInstantiatedContext(D->getLocation(), D->getDeclContext(),
2097e5dd7070Spatrick TemplateArgs);
2098e5dd7070Spatrick }
2099e5dd7070Spatrick
2100e5dd7070Spatrick DeclarationNameInfo NameInfo
2101e5dd7070Spatrick = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
2102e5dd7070Spatrick
2103e5dd7070Spatrick if (FunctionRewriteKind != RewriteKind::None)
2104e5dd7070Spatrick adjustForRewrite(FunctionRewriteKind, D, T, TInfo, NameInfo);
2105e5dd7070Spatrick
2106e5dd7070Spatrick FunctionDecl *Function;
2107e5dd7070Spatrick if (auto *DGuide = dyn_cast<CXXDeductionGuideDecl>(D)) {
2108e5dd7070Spatrick Function = CXXDeductionGuideDecl::Create(
2109e5dd7070Spatrick SemaRef.Context, DC, D->getInnerLocStart(),
2110e5dd7070Spatrick InstantiatedExplicitSpecifier, NameInfo, T, TInfo,
2111e5dd7070Spatrick D->getSourceRange().getEnd());
2112e5dd7070Spatrick if (DGuide->isCopyDeductionCandidate())
2113e5dd7070Spatrick cast<CXXDeductionGuideDecl>(Function)->setIsCopyDeductionCandidate();
2114e5dd7070Spatrick Function->setAccess(D->getAccess());
2115e5dd7070Spatrick } else {
2116e5dd7070Spatrick Function = FunctionDecl::Create(
2117e5dd7070Spatrick SemaRef.Context, DC, D->getInnerLocStart(), NameInfo, T, TInfo,
2118*12c85518Srobert D->getCanonicalDecl()->getStorageClass(), D->UsesFPIntrin(),
2119*12c85518Srobert D->isInlineSpecified(), D->hasWrittenPrototype(), D->getConstexprKind(),
2120e5dd7070Spatrick TrailingRequiresClause);
2121*12c85518Srobert Function->setFriendConstraintRefersToEnclosingTemplate(
2122*12c85518Srobert D->FriendConstraintRefersToEnclosingTemplate());
2123e5dd7070Spatrick Function->setRangeEnd(D->getSourceRange().getEnd());
2124e5dd7070Spatrick }
2125e5dd7070Spatrick
2126e5dd7070Spatrick if (D->isInlined())
2127e5dd7070Spatrick Function->setImplicitlyInline();
2128e5dd7070Spatrick
2129e5dd7070Spatrick if (QualifierLoc)
2130e5dd7070Spatrick Function->setQualifierInfo(QualifierLoc);
2131e5dd7070Spatrick
2132e5dd7070Spatrick if (D->isLocalExternDecl())
2133e5dd7070Spatrick Function->setLocalExternDecl();
2134e5dd7070Spatrick
2135e5dd7070Spatrick DeclContext *LexicalDC = Owner;
2136e5dd7070Spatrick if (!isFriend && D->isOutOfLine() && !D->isLocalExternDecl()) {
2137e5dd7070Spatrick assert(D->getDeclContext()->isFileContext());
2138e5dd7070Spatrick LexicalDC = D->getDeclContext();
2139e5dd7070Spatrick }
2140*12c85518Srobert else if (D->isLocalExternDecl()) {
2141*12c85518Srobert LexicalDC = SemaRef.CurContext;
2142*12c85518Srobert }
2143e5dd7070Spatrick
2144e5dd7070Spatrick Function->setLexicalDeclContext(LexicalDC);
2145e5dd7070Spatrick
2146e5dd7070Spatrick // Attach the parameters
2147e5dd7070Spatrick for (unsigned P = 0; P < Params.size(); ++P)
2148e5dd7070Spatrick if (Params[P])
2149e5dd7070Spatrick Params[P]->setOwningFunction(Function);
2150e5dd7070Spatrick Function->setParams(Params);
2151e5dd7070Spatrick
2152e5dd7070Spatrick if (TrailingRequiresClause)
2153e5dd7070Spatrick Function->setTrailingRequiresClause(TrailingRequiresClause);
2154e5dd7070Spatrick
2155e5dd7070Spatrick if (TemplateParams) {
2156e5dd7070Spatrick // Our resulting instantiation is actually a function template, since we
2157e5dd7070Spatrick // are substituting only the outer template parameters. For example, given
2158e5dd7070Spatrick //
2159e5dd7070Spatrick // template<typename T>
2160e5dd7070Spatrick // struct X {
2161e5dd7070Spatrick // template<typename U> friend void f(T, U);
2162e5dd7070Spatrick // };
2163e5dd7070Spatrick //
2164e5dd7070Spatrick // X<int> x;
2165e5dd7070Spatrick //
2166e5dd7070Spatrick // We are instantiating the friend function template "f" within X<int>,
2167e5dd7070Spatrick // which means substituting int for T, but leaving "f" as a friend function
2168e5dd7070Spatrick // template.
2169e5dd7070Spatrick // Build the function template itself.
2170e5dd7070Spatrick FunctionTemplate = FunctionTemplateDecl::Create(SemaRef.Context, DC,
2171e5dd7070Spatrick Function->getLocation(),
2172e5dd7070Spatrick Function->getDeclName(),
2173e5dd7070Spatrick TemplateParams, Function);
2174e5dd7070Spatrick Function->setDescribedFunctionTemplate(FunctionTemplate);
2175e5dd7070Spatrick
2176e5dd7070Spatrick FunctionTemplate->setLexicalDeclContext(LexicalDC);
2177e5dd7070Spatrick
2178e5dd7070Spatrick if (isFriend && D->isThisDeclarationADefinition()) {
2179e5dd7070Spatrick FunctionTemplate->setInstantiatedFromMemberTemplate(
2180e5dd7070Spatrick D->getDescribedFunctionTemplate());
2181e5dd7070Spatrick }
2182e5dd7070Spatrick } else if (FunctionTemplate) {
2183e5dd7070Spatrick // Record this function template specialization.
2184e5dd7070Spatrick ArrayRef<TemplateArgument> Innermost = TemplateArgs.getInnermost();
2185e5dd7070Spatrick Function->setFunctionTemplateSpecialization(FunctionTemplate,
2186e5dd7070Spatrick TemplateArgumentList::CreateCopy(SemaRef.Context,
2187e5dd7070Spatrick Innermost),
2188e5dd7070Spatrick /*InsertPos=*/nullptr);
2189e5dd7070Spatrick } else if (isFriend && D->isThisDeclarationADefinition()) {
2190e5dd7070Spatrick // Do not connect the friend to the template unless it's actually a
2191e5dd7070Spatrick // definition. We don't want non-template functions to be marked as being
2192e5dd7070Spatrick // template instantiations.
2193e5dd7070Spatrick Function->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);
2194*12c85518Srobert } else if (!isFriend) {
2195*12c85518Srobert // If this is not a function template, and this is not a friend (that is,
2196*12c85518Srobert // this is a locally declared function), save the instantiation relationship
2197*12c85518Srobert // for the purposes of constraint instantiation.
2198*12c85518Srobert Function->setInstantiatedFromDecl(D);
2199e5dd7070Spatrick }
2200e5dd7070Spatrick
2201a9ac8606Spatrick if (isFriend) {
2202e5dd7070Spatrick Function->setObjectOfFriendDecl();
2203a9ac8606Spatrick if (FunctionTemplateDecl *FT = Function->getDescribedFunctionTemplate())
2204a9ac8606Spatrick FT->setObjectOfFriendDecl();
2205a9ac8606Spatrick }
2206e5dd7070Spatrick
2207e5dd7070Spatrick if (InitFunctionInstantiation(Function, D))
2208e5dd7070Spatrick Function->setInvalidDecl();
2209e5dd7070Spatrick
2210e5dd7070Spatrick bool IsExplicitSpecialization = false;
2211e5dd7070Spatrick
2212e5dd7070Spatrick LookupResult Previous(
2213e5dd7070Spatrick SemaRef, Function->getDeclName(), SourceLocation(),
2214e5dd7070Spatrick D->isLocalExternDecl() ? Sema::LookupRedeclarationWithLinkage
2215e5dd7070Spatrick : Sema::LookupOrdinaryName,
2216e5dd7070Spatrick D->isLocalExternDecl() ? Sema::ForExternalRedeclaration
2217e5dd7070Spatrick : SemaRef.forRedeclarationInCurContext());
2218e5dd7070Spatrick
2219e5dd7070Spatrick if (DependentFunctionTemplateSpecializationInfo *Info
2220e5dd7070Spatrick = D->getDependentSpecializationInfo()) {
2221e5dd7070Spatrick assert(isFriend && "non-friend has dependent specialization info?");
2222e5dd7070Spatrick
2223e5dd7070Spatrick // Instantiate the explicit template arguments.
2224e5dd7070Spatrick TemplateArgumentListInfo ExplicitArgs(Info->getLAngleLoc(),
2225e5dd7070Spatrick Info->getRAngleLoc());
2226*12c85518Srobert if (SemaRef.SubstTemplateArguments(Info->arguments(), TemplateArgs,
2227*12c85518Srobert ExplicitArgs))
2228e5dd7070Spatrick return nullptr;
2229e5dd7070Spatrick
2230e5dd7070Spatrick // Map the candidate templates to their instantiations.
2231e5dd7070Spatrick for (unsigned I = 0, E = Info->getNumTemplates(); I != E; ++I) {
2232e5dd7070Spatrick Decl *Temp = SemaRef.FindInstantiatedDecl(D->getLocation(),
2233e5dd7070Spatrick Info->getTemplate(I),
2234e5dd7070Spatrick TemplateArgs);
2235e5dd7070Spatrick if (!Temp) return nullptr;
2236e5dd7070Spatrick
2237e5dd7070Spatrick Previous.addDecl(cast<FunctionTemplateDecl>(Temp));
2238e5dd7070Spatrick }
2239e5dd7070Spatrick
2240e5dd7070Spatrick if (SemaRef.CheckFunctionTemplateSpecialization(Function,
2241e5dd7070Spatrick &ExplicitArgs,
2242e5dd7070Spatrick Previous))
2243e5dd7070Spatrick Function->setInvalidDecl();
2244e5dd7070Spatrick
2245e5dd7070Spatrick IsExplicitSpecialization = true;
2246e5dd7070Spatrick } else if (const ASTTemplateArgumentListInfo *Info =
2247e5dd7070Spatrick D->getTemplateSpecializationArgsAsWritten()) {
2248e5dd7070Spatrick // The name of this function was written as a template-id.
2249e5dd7070Spatrick SemaRef.LookupQualifiedName(Previous, DC);
2250e5dd7070Spatrick
2251e5dd7070Spatrick // Instantiate the explicit template arguments.
2252e5dd7070Spatrick TemplateArgumentListInfo ExplicitArgs(Info->getLAngleLoc(),
2253e5dd7070Spatrick Info->getRAngleLoc());
2254*12c85518Srobert if (SemaRef.SubstTemplateArguments(Info->arguments(), TemplateArgs,
2255*12c85518Srobert ExplicitArgs))
2256e5dd7070Spatrick return nullptr;
2257e5dd7070Spatrick
2258e5dd7070Spatrick if (SemaRef.CheckFunctionTemplateSpecialization(Function,
2259e5dd7070Spatrick &ExplicitArgs,
2260e5dd7070Spatrick Previous))
2261e5dd7070Spatrick Function->setInvalidDecl();
2262e5dd7070Spatrick
2263e5dd7070Spatrick IsExplicitSpecialization = true;
2264e5dd7070Spatrick } else if (TemplateParams || !FunctionTemplate) {
2265e5dd7070Spatrick // Look only into the namespace where the friend would be declared to
2266e5dd7070Spatrick // find a previous declaration. This is the innermost enclosing namespace,
2267e5dd7070Spatrick // as described in ActOnFriendFunctionDecl.
2268ec727ea7Spatrick SemaRef.LookupQualifiedName(Previous, DC->getRedeclContext());
2269e5dd7070Spatrick
2270e5dd7070Spatrick // In C++, the previous declaration we find might be a tag type
2271e5dd7070Spatrick // (class or enum). In this case, the new declaration will hide the
2272*12c85518Srobert // tag type. Note that this does not apply if we're declaring a
2273e5dd7070Spatrick // typedef (C++ [dcl.typedef]p4).
2274e5dd7070Spatrick if (Previous.isSingleTagDecl())
2275e5dd7070Spatrick Previous.clear();
2276ec727ea7Spatrick
2277ec727ea7Spatrick // Filter out previous declarations that don't match the scope. The only
2278ec727ea7Spatrick // effect this has is to remove declarations found in inline namespaces
2279ec727ea7Spatrick // for friend declarations with unqualified names.
2280*12c85518Srobert if (isFriend && !QualifierLoc && !FunctionTemplate) {
2281*12c85518Srobert SemaRef.FilterLookupForScope(Previous, DC, /*Scope=*/ nullptr,
2282*12c85518Srobert /*ConsiderLinkage=*/ true,
2283ec727ea7Spatrick QualifierLoc.hasQualifier());
2284e5dd7070Spatrick }
2285*12c85518Srobert }
2286*12c85518Srobert
2287*12c85518Srobert // Per [temp.inst], default arguments in function declarations at local scope
2288*12c85518Srobert // are instantiated along with the enclosing declaration. For example:
2289*12c85518Srobert //
2290*12c85518Srobert // template<typename T>
2291*12c85518Srobert // void ft() {
2292*12c85518Srobert // void f(int = []{ return T::value; }());
2293*12c85518Srobert // }
2294*12c85518Srobert // template void ft<int>(); // error: type 'int' cannot be used prior
2295*12c85518Srobert // to '::' because it has no members
2296*12c85518Srobert //
2297*12c85518Srobert // The error is issued during instantiation of ft<int>() because substitution
2298*12c85518Srobert // into the default argument fails; the default argument is instantiated even
2299*12c85518Srobert // though it is never used.
2300*12c85518Srobert if (Function->isLocalExternDecl()) {
2301*12c85518Srobert for (ParmVarDecl *PVD : Function->parameters()) {
2302*12c85518Srobert if (!PVD->hasDefaultArg())
2303*12c85518Srobert continue;
2304*12c85518Srobert if (SemaRef.SubstDefaultArgument(D->getInnerLocStart(), PVD, TemplateArgs)) {
2305*12c85518Srobert // If substitution fails, the default argument is set to a
2306*12c85518Srobert // RecoveryExpr that wraps the uninstantiated default argument so
2307*12c85518Srobert // that downstream diagnostics are omitted.
2308*12c85518Srobert Expr *UninstExpr = PVD->getUninstantiatedDefaultArg();
2309*12c85518Srobert ExprResult ErrorResult = SemaRef.CreateRecoveryExpr(
2310*12c85518Srobert UninstExpr->getBeginLoc(), UninstExpr->getEndLoc(),
2311*12c85518Srobert { UninstExpr }, UninstExpr->getType());
2312*12c85518Srobert if (ErrorResult.isUsable())
2313*12c85518Srobert PVD->setDefaultArg(ErrorResult.get());
2314*12c85518Srobert }
2315*12c85518Srobert }
2316*12c85518Srobert }
2317e5dd7070Spatrick
2318e5dd7070Spatrick SemaRef.CheckFunctionDeclaration(/*Scope*/ nullptr, Function, Previous,
2319*12c85518Srobert IsExplicitSpecialization,
2320*12c85518Srobert Function->isThisDeclarationADefinition());
2321e5dd7070Spatrick
2322e5dd7070Spatrick // Check the template parameter list against the previous declaration. The
2323e5dd7070Spatrick // goal here is to pick up default arguments added since the friend was
2324e5dd7070Spatrick // declared; we know the template parameter lists match, since otherwise
2325e5dd7070Spatrick // we would not have picked this template as the previous declaration.
2326a9ac8606Spatrick if (isFriend && TemplateParams && FunctionTemplate->getPreviousDecl()) {
2327e5dd7070Spatrick SemaRef.CheckTemplateParameterList(
2328e5dd7070Spatrick TemplateParams,
2329e5dd7070Spatrick FunctionTemplate->getPreviousDecl()->getTemplateParameters(),
2330e5dd7070Spatrick Function->isThisDeclarationADefinition()
2331e5dd7070Spatrick ? Sema::TPC_FriendFunctionTemplateDefinition
2332e5dd7070Spatrick : Sema::TPC_FriendFunctionTemplate);
2333e5dd7070Spatrick }
2334a9ac8606Spatrick
2335a9ac8606Spatrick // If we're introducing a friend definition after the first use, trigger
2336a9ac8606Spatrick // instantiation.
2337a9ac8606Spatrick // FIXME: If this is a friend function template definition, we should check
2338a9ac8606Spatrick // to see if any specializations have been used.
2339a9ac8606Spatrick if (isFriend && D->isThisDeclarationADefinition() && Function->isUsed(false)) {
2340a9ac8606Spatrick if (MemberSpecializationInfo *MSInfo =
2341a9ac8606Spatrick Function->getMemberSpecializationInfo()) {
2342a9ac8606Spatrick if (MSInfo->getPointOfInstantiation().isInvalid()) {
2343a9ac8606Spatrick SourceLocation Loc = D->getLocation(); // FIXME
2344a9ac8606Spatrick MSInfo->setPointOfInstantiation(Loc);
2345a9ac8606Spatrick SemaRef.PendingLocalImplicitInstantiations.push_back(
2346a9ac8606Spatrick std::make_pair(Function, Loc));
2347a9ac8606Spatrick }
2348a9ac8606Spatrick }
2349e5dd7070Spatrick }
2350e5dd7070Spatrick
2351e5dd7070Spatrick if (D->isExplicitlyDefaulted()) {
2352e5dd7070Spatrick if (SubstDefaultedFunction(Function, D))
2353e5dd7070Spatrick return nullptr;
2354e5dd7070Spatrick }
2355e5dd7070Spatrick if (D->isDeleted())
2356e5dd7070Spatrick SemaRef.SetDeclDeleted(Function, D->getLocation());
2357e5dd7070Spatrick
2358a9ac8606Spatrick NamedDecl *PrincipalDecl =
2359a9ac8606Spatrick (TemplateParams ? cast<NamedDecl>(FunctionTemplate) : Function);
2360a9ac8606Spatrick
2361a9ac8606Spatrick // If this declaration lives in a different context from its lexical context,
2362a9ac8606Spatrick // add it to the corresponding lookup table.
2363a9ac8606Spatrick if (isFriend ||
2364a9ac8606Spatrick (Function->isLocalExternDecl() && !Function->getPreviousDecl()))
2365e5dd7070Spatrick DC->makeDeclVisibleInContext(PrincipalDecl);
2366e5dd7070Spatrick
2367e5dd7070Spatrick if (Function->isOverloadedOperator() && !DC->isRecord() &&
2368e5dd7070Spatrick PrincipalDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary))
2369e5dd7070Spatrick PrincipalDecl->setNonMemberOperator();
2370e5dd7070Spatrick
2371e5dd7070Spatrick return Function;
2372e5dd7070Spatrick }
2373e5dd7070Spatrick
VisitCXXMethodDecl(CXXMethodDecl * D,TemplateParameterList * TemplateParams,std::optional<const ASTTemplateArgumentListInfo * > ClassScopeSpecializationArgs,RewriteKind FunctionRewriteKind)2374e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(
2375e5dd7070Spatrick CXXMethodDecl *D, TemplateParameterList *TemplateParams,
2376*12c85518Srobert std::optional<const ASTTemplateArgumentListInfo *>
2377*12c85518Srobert ClassScopeSpecializationArgs,
2378e5dd7070Spatrick RewriteKind FunctionRewriteKind) {
2379e5dd7070Spatrick FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate();
2380e5dd7070Spatrick if (FunctionTemplate && !TemplateParams) {
2381e5dd7070Spatrick // We are creating a function template specialization from a function
2382e5dd7070Spatrick // template. Check whether there is already a function template
2383e5dd7070Spatrick // specialization for this particular set of template arguments.
2384e5dd7070Spatrick ArrayRef<TemplateArgument> Innermost = TemplateArgs.getInnermost();
2385e5dd7070Spatrick
2386e5dd7070Spatrick void *InsertPos = nullptr;
2387e5dd7070Spatrick FunctionDecl *SpecFunc
2388e5dd7070Spatrick = FunctionTemplate->findSpecialization(Innermost, InsertPos);
2389e5dd7070Spatrick
2390e5dd7070Spatrick // If we already have a function template specialization, return it.
2391e5dd7070Spatrick if (SpecFunc)
2392e5dd7070Spatrick return SpecFunc;
2393e5dd7070Spatrick }
2394e5dd7070Spatrick
2395e5dd7070Spatrick bool isFriend;
2396e5dd7070Spatrick if (FunctionTemplate)
2397e5dd7070Spatrick isFriend = (FunctionTemplate->getFriendObjectKind() != Decl::FOK_None);
2398e5dd7070Spatrick else
2399e5dd7070Spatrick isFriend = (D->getFriendObjectKind() != Decl::FOK_None);
2400e5dd7070Spatrick
2401e5dd7070Spatrick bool MergeWithParentScope = (TemplateParams != nullptr) ||
2402e5dd7070Spatrick !(isa<Decl>(Owner) &&
2403e5dd7070Spatrick cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod());
2404e5dd7070Spatrick LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
2405e5dd7070Spatrick
2406e5dd7070Spatrick // Instantiate enclosing template arguments for friends.
2407e5dd7070Spatrick SmallVector<TemplateParameterList *, 4> TempParamLists;
2408e5dd7070Spatrick unsigned NumTempParamLists = 0;
2409e5dd7070Spatrick if (isFriend && (NumTempParamLists = D->getNumTemplateParameterLists())) {
2410e5dd7070Spatrick TempParamLists.resize(NumTempParamLists);
2411e5dd7070Spatrick for (unsigned I = 0; I != NumTempParamLists; ++I) {
2412e5dd7070Spatrick TemplateParameterList *TempParams = D->getTemplateParameterList(I);
2413e5dd7070Spatrick TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
2414e5dd7070Spatrick if (!InstParams)
2415e5dd7070Spatrick return nullptr;
2416e5dd7070Spatrick TempParamLists[I] = InstParams;
2417e5dd7070Spatrick }
2418e5dd7070Spatrick }
2419e5dd7070Spatrick
2420e5dd7070Spatrick ExplicitSpecifier InstantiatedExplicitSpecifier =
2421e5dd7070Spatrick instantiateExplicitSpecifier(SemaRef, TemplateArgs,
2422e5dd7070Spatrick ExplicitSpecifier::getFromDecl(D), D);
2423e5dd7070Spatrick if (InstantiatedExplicitSpecifier.isInvalid())
2424e5dd7070Spatrick return nullptr;
2425e5dd7070Spatrick
2426a9ac8606Spatrick // Implicit destructors/constructors created for local classes in
2427a9ac8606Spatrick // DeclareImplicit* (see SemaDeclCXX.cpp) might not have an associated TSI.
2428a9ac8606Spatrick // Unfortunately there isn't enough context in those functions to
2429a9ac8606Spatrick // conditionally populate the TSI without breaking non-template related use
2430a9ac8606Spatrick // cases. Populate TSIs prior to calling SubstFunctionType to make sure we get
2431a9ac8606Spatrick // a proper transformation.
2432a9ac8606Spatrick if (cast<CXXRecordDecl>(D->getParent())->isLambda() &&
2433a9ac8606Spatrick !D->getTypeSourceInfo() &&
2434a9ac8606Spatrick isa<CXXConstructorDecl, CXXDestructorDecl>(D)) {
2435a9ac8606Spatrick TypeSourceInfo *TSI =
2436a9ac8606Spatrick SemaRef.Context.getTrivialTypeSourceInfo(D->getType());
2437a9ac8606Spatrick D->setTypeSourceInfo(TSI);
2438a9ac8606Spatrick }
2439a9ac8606Spatrick
2440e5dd7070Spatrick SmallVector<ParmVarDecl *, 4> Params;
2441e5dd7070Spatrick TypeSourceInfo *TInfo = SubstFunctionType(D, Params);
2442e5dd7070Spatrick if (!TInfo)
2443e5dd7070Spatrick return nullptr;
2444e5dd7070Spatrick QualType T = adjustFunctionTypeForInstantiation(SemaRef.Context, D, TInfo);
2445e5dd7070Spatrick
2446e5dd7070Spatrick if (TemplateParams && TemplateParams->size()) {
2447e5dd7070Spatrick auto *LastParam =
2448e5dd7070Spatrick dyn_cast<TemplateTypeParmDecl>(TemplateParams->asArray().back());
2449e5dd7070Spatrick if (LastParam && LastParam->isImplicit() &&
2450e5dd7070Spatrick LastParam->hasTypeConstraint()) {
2451e5dd7070Spatrick // In abbreviated templates, the type-constraints of invented template
2452e5dd7070Spatrick // type parameters are instantiated with the function type, invalidating
2453e5dd7070Spatrick // the TemplateParameterList which relied on the template type parameter
2454e5dd7070Spatrick // not having a type constraint. Recreate the TemplateParameterList with
2455e5dd7070Spatrick // the updated parameter list.
2456e5dd7070Spatrick TemplateParams = TemplateParameterList::Create(
2457e5dd7070Spatrick SemaRef.Context, TemplateParams->getTemplateLoc(),
2458e5dd7070Spatrick TemplateParams->getLAngleLoc(), TemplateParams->asArray(),
2459e5dd7070Spatrick TemplateParams->getRAngleLoc(), TemplateParams->getRequiresClause());
2460e5dd7070Spatrick }
2461e5dd7070Spatrick }
2462e5dd7070Spatrick
2463e5dd7070Spatrick NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc();
2464e5dd7070Spatrick if (QualifierLoc) {
2465e5dd7070Spatrick QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc,
2466e5dd7070Spatrick TemplateArgs);
2467e5dd7070Spatrick if (!QualifierLoc)
2468e5dd7070Spatrick return nullptr;
2469e5dd7070Spatrick }
2470e5dd7070Spatrick
2471e5dd7070Spatrick DeclContext *DC = Owner;
2472e5dd7070Spatrick if (isFriend) {
2473e5dd7070Spatrick if (QualifierLoc) {
2474e5dd7070Spatrick CXXScopeSpec SS;
2475e5dd7070Spatrick SS.Adopt(QualifierLoc);
2476e5dd7070Spatrick DC = SemaRef.computeDeclContext(SS);
2477e5dd7070Spatrick
2478e5dd7070Spatrick if (DC && SemaRef.RequireCompleteDeclContext(SS, DC))
2479e5dd7070Spatrick return nullptr;
2480e5dd7070Spatrick } else {
2481e5dd7070Spatrick DC = SemaRef.FindInstantiatedContext(D->getLocation(),
2482e5dd7070Spatrick D->getDeclContext(),
2483e5dd7070Spatrick TemplateArgs);
2484e5dd7070Spatrick }
2485e5dd7070Spatrick if (!DC) return nullptr;
2486e5dd7070Spatrick }
2487e5dd7070Spatrick
2488*12c85518Srobert CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
2489*12c85518Srobert Expr *TrailingRequiresClause = D->getTrailingRequiresClause();
2490*12c85518Srobert
2491e5dd7070Spatrick DeclarationNameInfo NameInfo
2492e5dd7070Spatrick = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
2493e5dd7070Spatrick
2494e5dd7070Spatrick if (FunctionRewriteKind != RewriteKind::None)
2495e5dd7070Spatrick adjustForRewrite(FunctionRewriteKind, D, T, TInfo, NameInfo);
2496e5dd7070Spatrick
2497e5dd7070Spatrick // Build the instantiated method declaration.
2498e5dd7070Spatrick CXXMethodDecl *Method = nullptr;
2499e5dd7070Spatrick
2500e5dd7070Spatrick SourceLocation StartLoc = D->getInnerLocStart();
2501e5dd7070Spatrick if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
2502e5dd7070Spatrick Method = CXXConstructorDecl::Create(
2503e5dd7070Spatrick SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo,
2504*12c85518Srobert InstantiatedExplicitSpecifier, Constructor->UsesFPIntrin(),
2505*12c85518Srobert Constructor->isInlineSpecified(), false,
2506e5dd7070Spatrick Constructor->getConstexprKind(), InheritedConstructor(),
2507e5dd7070Spatrick TrailingRequiresClause);
2508e5dd7070Spatrick Method->setRangeEnd(Constructor->getEndLoc());
2509*12c85518Srobert if (Constructor->isDefaultConstructor() ||
2510*12c85518Srobert Constructor->isCopyOrMoveConstructor())
2511*12c85518Srobert Method->setIneligibleOrNotSelected(true);
2512e5dd7070Spatrick } else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) {
2513e5dd7070Spatrick Method = CXXDestructorDecl::Create(
2514e5dd7070Spatrick SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo,
2515*12c85518Srobert Destructor->UsesFPIntrin(), Destructor->isInlineSpecified(), false,
2516*12c85518Srobert Destructor->getConstexprKind(), TrailingRequiresClause);
2517*12c85518Srobert Method->setIneligibleOrNotSelected(true);
2518e5dd7070Spatrick Method->setRangeEnd(Destructor->getEndLoc());
2519a9ac8606Spatrick Method->setDeclName(SemaRef.Context.DeclarationNames.getCXXDestructorName(
2520a9ac8606Spatrick SemaRef.Context.getCanonicalType(
2521a9ac8606Spatrick SemaRef.Context.getTypeDeclType(Record))));
2522e5dd7070Spatrick } else if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(D)) {
2523e5dd7070Spatrick Method = CXXConversionDecl::Create(
2524e5dd7070Spatrick SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo,
2525*12c85518Srobert Conversion->UsesFPIntrin(), Conversion->isInlineSpecified(),
2526*12c85518Srobert InstantiatedExplicitSpecifier, Conversion->getConstexprKind(),
2527*12c85518Srobert Conversion->getEndLoc(), TrailingRequiresClause);
2528e5dd7070Spatrick } else {
2529e5dd7070Spatrick StorageClass SC = D->isStatic() ? SC_Static : SC_None;
2530*12c85518Srobert Method = CXXMethodDecl::Create(
2531*12c85518Srobert SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo, SC,
2532*12c85518Srobert D->UsesFPIntrin(), D->isInlineSpecified(), D->getConstexprKind(),
2533*12c85518Srobert D->getEndLoc(), TrailingRequiresClause);
2534*12c85518Srobert if (D->isMoveAssignmentOperator() || D->isCopyAssignmentOperator())
2535*12c85518Srobert Method->setIneligibleOrNotSelected(true);
2536e5dd7070Spatrick }
2537e5dd7070Spatrick
2538e5dd7070Spatrick if (D->isInlined())
2539e5dd7070Spatrick Method->setImplicitlyInline();
2540e5dd7070Spatrick
2541e5dd7070Spatrick if (QualifierLoc)
2542e5dd7070Spatrick Method->setQualifierInfo(QualifierLoc);
2543e5dd7070Spatrick
2544e5dd7070Spatrick if (TemplateParams) {
2545e5dd7070Spatrick // Our resulting instantiation is actually a function template, since we
2546e5dd7070Spatrick // are substituting only the outer template parameters. For example, given
2547e5dd7070Spatrick //
2548e5dd7070Spatrick // template<typename T>
2549e5dd7070Spatrick // struct X {
2550e5dd7070Spatrick // template<typename U> void f(T, U);
2551e5dd7070Spatrick // };
2552e5dd7070Spatrick //
2553e5dd7070Spatrick // X<int> x;
2554e5dd7070Spatrick //
2555e5dd7070Spatrick // We are instantiating the member template "f" within X<int>, which means
2556e5dd7070Spatrick // substituting int for T, but leaving "f" as a member function template.
2557e5dd7070Spatrick // Build the function template itself.
2558e5dd7070Spatrick FunctionTemplate = FunctionTemplateDecl::Create(SemaRef.Context, Record,
2559e5dd7070Spatrick Method->getLocation(),
2560e5dd7070Spatrick Method->getDeclName(),
2561e5dd7070Spatrick TemplateParams, Method);
2562e5dd7070Spatrick if (isFriend) {
2563e5dd7070Spatrick FunctionTemplate->setLexicalDeclContext(Owner);
2564e5dd7070Spatrick FunctionTemplate->setObjectOfFriendDecl();
2565e5dd7070Spatrick } else if (D->isOutOfLine())
2566e5dd7070Spatrick FunctionTemplate->setLexicalDeclContext(D->getLexicalDeclContext());
2567e5dd7070Spatrick Method->setDescribedFunctionTemplate(FunctionTemplate);
2568e5dd7070Spatrick } else if (FunctionTemplate) {
2569e5dd7070Spatrick // Record this function template specialization.
2570e5dd7070Spatrick ArrayRef<TemplateArgument> Innermost = TemplateArgs.getInnermost();
2571e5dd7070Spatrick Method->setFunctionTemplateSpecialization(FunctionTemplate,
2572e5dd7070Spatrick TemplateArgumentList::CreateCopy(SemaRef.Context,
2573e5dd7070Spatrick Innermost),
2574e5dd7070Spatrick /*InsertPos=*/nullptr);
2575e5dd7070Spatrick } else if (!isFriend) {
2576e5dd7070Spatrick // Record that this is an instantiation of a member function.
2577e5dd7070Spatrick Method->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);
2578e5dd7070Spatrick }
2579e5dd7070Spatrick
2580e5dd7070Spatrick // If we are instantiating a member function defined
2581e5dd7070Spatrick // out-of-line, the instantiation will have the same lexical
2582e5dd7070Spatrick // context (which will be a namespace scope) as the template.
2583e5dd7070Spatrick if (isFriend) {
2584e5dd7070Spatrick if (NumTempParamLists)
2585e5dd7070Spatrick Method->setTemplateParameterListsInfo(
2586e5dd7070Spatrick SemaRef.Context,
2587*12c85518Srobert llvm::ArrayRef(TempParamLists.data(), NumTempParamLists));
2588e5dd7070Spatrick
2589e5dd7070Spatrick Method->setLexicalDeclContext(Owner);
2590e5dd7070Spatrick Method->setObjectOfFriendDecl();
2591e5dd7070Spatrick } else if (D->isOutOfLine())
2592e5dd7070Spatrick Method->setLexicalDeclContext(D->getLexicalDeclContext());
2593e5dd7070Spatrick
2594e5dd7070Spatrick // Attach the parameters
2595e5dd7070Spatrick for (unsigned P = 0; P < Params.size(); ++P)
2596e5dd7070Spatrick Params[P]->setOwningFunction(Method);
2597e5dd7070Spatrick Method->setParams(Params);
2598e5dd7070Spatrick
2599e5dd7070Spatrick if (InitMethodInstantiation(Method, D))
2600e5dd7070Spatrick Method->setInvalidDecl();
2601e5dd7070Spatrick
2602e5dd7070Spatrick LookupResult Previous(SemaRef, NameInfo, Sema::LookupOrdinaryName,
2603e5dd7070Spatrick Sema::ForExternalRedeclaration);
2604e5dd7070Spatrick
2605e5dd7070Spatrick bool IsExplicitSpecialization = false;
2606e5dd7070Spatrick
2607e5dd7070Spatrick // If the name of this function was written as a template-id, instantiate
2608e5dd7070Spatrick // the explicit template arguments.
2609e5dd7070Spatrick if (DependentFunctionTemplateSpecializationInfo *Info
2610e5dd7070Spatrick = D->getDependentSpecializationInfo()) {
2611e5dd7070Spatrick assert(isFriend && "non-friend has dependent specialization info?");
2612e5dd7070Spatrick
2613e5dd7070Spatrick // Instantiate the explicit template arguments.
2614e5dd7070Spatrick TemplateArgumentListInfo ExplicitArgs(Info->getLAngleLoc(),
2615e5dd7070Spatrick Info->getRAngleLoc());
2616*12c85518Srobert if (SemaRef.SubstTemplateArguments(Info->arguments(), TemplateArgs,
2617*12c85518Srobert ExplicitArgs))
2618e5dd7070Spatrick return nullptr;
2619e5dd7070Spatrick
2620e5dd7070Spatrick // Map the candidate templates to their instantiations.
2621e5dd7070Spatrick for (unsigned I = 0, E = Info->getNumTemplates(); I != E; ++I) {
2622e5dd7070Spatrick Decl *Temp = SemaRef.FindInstantiatedDecl(D->getLocation(),
2623e5dd7070Spatrick Info->getTemplate(I),
2624e5dd7070Spatrick TemplateArgs);
2625e5dd7070Spatrick if (!Temp) return nullptr;
2626e5dd7070Spatrick
2627e5dd7070Spatrick Previous.addDecl(cast<FunctionTemplateDecl>(Temp));
2628e5dd7070Spatrick }
2629e5dd7070Spatrick
2630e5dd7070Spatrick if (SemaRef.CheckFunctionTemplateSpecialization(Method,
2631e5dd7070Spatrick &ExplicitArgs,
2632e5dd7070Spatrick Previous))
2633e5dd7070Spatrick Method->setInvalidDecl();
2634e5dd7070Spatrick
2635e5dd7070Spatrick IsExplicitSpecialization = true;
2636e5dd7070Spatrick } else if (const ASTTemplateArgumentListInfo *Info =
2637*12c85518Srobert ClassScopeSpecializationArgs.value_or(
2638e5dd7070Spatrick D->getTemplateSpecializationArgsAsWritten())) {
2639e5dd7070Spatrick SemaRef.LookupQualifiedName(Previous, DC);
2640e5dd7070Spatrick
2641e5dd7070Spatrick TemplateArgumentListInfo ExplicitArgs(Info->getLAngleLoc(),
2642e5dd7070Spatrick Info->getRAngleLoc());
2643*12c85518Srobert if (SemaRef.SubstTemplateArguments(Info->arguments(), TemplateArgs,
2644*12c85518Srobert ExplicitArgs))
2645e5dd7070Spatrick return nullptr;
2646e5dd7070Spatrick
2647e5dd7070Spatrick if (SemaRef.CheckFunctionTemplateSpecialization(Method,
2648e5dd7070Spatrick &ExplicitArgs,
2649e5dd7070Spatrick Previous))
2650e5dd7070Spatrick Method->setInvalidDecl();
2651e5dd7070Spatrick
2652e5dd7070Spatrick IsExplicitSpecialization = true;
2653e5dd7070Spatrick } else if (ClassScopeSpecializationArgs) {
2654e5dd7070Spatrick // Class-scope explicit specialization written without explicit template
2655e5dd7070Spatrick // arguments.
2656e5dd7070Spatrick SemaRef.LookupQualifiedName(Previous, DC);
2657e5dd7070Spatrick if (SemaRef.CheckFunctionTemplateSpecialization(Method, nullptr, Previous))
2658e5dd7070Spatrick Method->setInvalidDecl();
2659e5dd7070Spatrick
2660e5dd7070Spatrick IsExplicitSpecialization = true;
2661e5dd7070Spatrick } else if (!FunctionTemplate || TemplateParams || isFriend) {
2662e5dd7070Spatrick SemaRef.LookupQualifiedName(Previous, Record);
2663e5dd7070Spatrick
2664e5dd7070Spatrick // In C++, the previous declaration we find might be a tag type
2665e5dd7070Spatrick // (class or enum). In this case, the new declaration will hide the
2666*12c85518Srobert // tag type. Note that this does not apply if we're declaring a
2667e5dd7070Spatrick // typedef (C++ [dcl.typedef]p4).
2668e5dd7070Spatrick if (Previous.isSingleTagDecl())
2669e5dd7070Spatrick Previous.clear();
2670e5dd7070Spatrick }
2671e5dd7070Spatrick
2672*12c85518Srobert // Per [temp.inst], default arguments in member functions of local classes
2673*12c85518Srobert // are instantiated along with the member function declaration. For example:
2674*12c85518Srobert //
2675*12c85518Srobert // template<typename T>
2676*12c85518Srobert // void ft() {
2677*12c85518Srobert // struct lc {
2678*12c85518Srobert // int operator()(int p = []{ return T::value; }());
2679*12c85518Srobert // };
2680*12c85518Srobert // }
2681*12c85518Srobert // template void ft<int>(); // error: type 'int' cannot be used prior
2682*12c85518Srobert // to '::'because it has no members
2683*12c85518Srobert //
2684*12c85518Srobert // The error is issued during instantiation of ft<int>()::lc::operator()
2685*12c85518Srobert // because substitution into the default argument fails; the default argument
2686*12c85518Srobert // is instantiated even though it is never used.
2687*12c85518Srobert if (D->isInLocalScopeForInstantiation()) {
2688*12c85518Srobert for (unsigned P = 0; P < Params.size(); ++P) {
2689*12c85518Srobert if (!Params[P]->hasDefaultArg())
2690*12c85518Srobert continue;
2691*12c85518Srobert if (SemaRef.SubstDefaultArgument(StartLoc, Params[P], TemplateArgs)) {
2692*12c85518Srobert // If substitution fails, the default argument is set to a
2693*12c85518Srobert // RecoveryExpr that wraps the uninstantiated default argument so
2694*12c85518Srobert // that downstream diagnostics are omitted.
2695*12c85518Srobert Expr *UninstExpr = Params[P]->getUninstantiatedDefaultArg();
2696*12c85518Srobert ExprResult ErrorResult = SemaRef.CreateRecoveryExpr(
2697*12c85518Srobert UninstExpr->getBeginLoc(), UninstExpr->getEndLoc(),
2698*12c85518Srobert { UninstExpr }, UninstExpr->getType());
2699*12c85518Srobert if (ErrorResult.isUsable())
2700*12c85518Srobert Params[P]->setDefaultArg(ErrorResult.get());
2701*12c85518Srobert }
2702*12c85518Srobert }
2703*12c85518Srobert }
2704*12c85518Srobert
2705e5dd7070Spatrick SemaRef.CheckFunctionDeclaration(nullptr, Method, Previous,
2706*12c85518Srobert IsExplicitSpecialization,
2707*12c85518Srobert Method->isThisDeclarationADefinition());
2708e5dd7070Spatrick
2709e5dd7070Spatrick if (D->isPure())
2710e5dd7070Spatrick SemaRef.CheckPureMethod(Method, SourceRange());
2711e5dd7070Spatrick
2712e5dd7070Spatrick // Propagate access. For a non-friend declaration, the access is
2713e5dd7070Spatrick // whatever we're propagating from. For a friend, it should be the
2714e5dd7070Spatrick // previous declaration we just found.
2715e5dd7070Spatrick if (isFriend && Method->getPreviousDecl())
2716e5dd7070Spatrick Method->setAccess(Method->getPreviousDecl()->getAccess());
2717e5dd7070Spatrick else
2718e5dd7070Spatrick Method->setAccess(D->getAccess());
2719e5dd7070Spatrick if (FunctionTemplate)
2720e5dd7070Spatrick FunctionTemplate->setAccess(Method->getAccess());
2721e5dd7070Spatrick
2722e5dd7070Spatrick SemaRef.CheckOverrideControl(Method);
2723e5dd7070Spatrick
2724e5dd7070Spatrick // If a function is defined as defaulted or deleted, mark it as such now.
2725e5dd7070Spatrick if (D->isExplicitlyDefaulted()) {
2726e5dd7070Spatrick if (SubstDefaultedFunction(Method, D))
2727e5dd7070Spatrick return nullptr;
2728e5dd7070Spatrick }
2729e5dd7070Spatrick if (D->isDeletedAsWritten())
2730e5dd7070Spatrick SemaRef.SetDeclDeleted(Method, Method->getLocation());
2731e5dd7070Spatrick
2732e5dd7070Spatrick // If this is an explicit specialization, mark the implicitly-instantiated
2733e5dd7070Spatrick // template specialization as being an explicit specialization too.
2734e5dd7070Spatrick // FIXME: Is this necessary?
2735e5dd7070Spatrick if (IsExplicitSpecialization && !isFriend)
2736e5dd7070Spatrick SemaRef.CompleteMemberSpecialization(Method, Previous);
2737e5dd7070Spatrick
2738e5dd7070Spatrick // If there's a function template, let our caller handle it.
2739e5dd7070Spatrick if (FunctionTemplate) {
2740e5dd7070Spatrick // do nothing
2741e5dd7070Spatrick
2742e5dd7070Spatrick // Don't hide a (potentially) valid declaration with an invalid one.
2743e5dd7070Spatrick } else if (Method->isInvalidDecl() && !Previous.empty()) {
2744e5dd7070Spatrick // do nothing
2745e5dd7070Spatrick
2746e5dd7070Spatrick // Otherwise, check access to friends and make them visible.
2747e5dd7070Spatrick } else if (isFriend) {
2748e5dd7070Spatrick // We only need to re-check access for methods which we didn't
2749e5dd7070Spatrick // manage to match during parsing.
2750e5dd7070Spatrick if (!D->getPreviousDecl())
2751e5dd7070Spatrick SemaRef.CheckFriendAccess(Method);
2752e5dd7070Spatrick
2753e5dd7070Spatrick Record->makeDeclVisibleInContext(Method);
2754e5dd7070Spatrick
2755e5dd7070Spatrick // Otherwise, add the declaration. We don't need to do this for
2756e5dd7070Spatrick // class-scope specializations because we'll have matched them with
2757e5dd7070Spatrick // the appropriate template.
2758e5dd7070Spatrick } else {
2759e5dd7070Spatrick Owner->addDecl(Method);
2760e5dd7070Spatrick }
2761e5dd7070Spatrick
2762e5dd7070Spatrick // PR17480: Honor the used attribute to instantiate member function
2763e5dd7070Spatrick // definitions
2764e5dd7070Spatrick if (Method->hasAttr<UsedAttr>()) {
2765e5dd7070Spatrick if (const auto *A = dyn_cast<CXXRecordDecl>(Owner)) {
2766e5dd7070Spatrick SourceLocation Loc;
2767e5dd7070Spatrick if (const MemberSpecializationInfo *MSInfo =
2768e5dd7070Spatrick A->getMemberSpecializationInfo())
2769e5dd7070Spatrick Loc = MSInfo->getPointOfInstantiation();
2770e5dd7070Spatrick else if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(A))
2771e5dd7070Spatrick Loc = Spec->getPointOfInstantiation();
2772e5dd7070Spatrick SemaRef.MarkFunctionReferenced(Loc, Method);
2773e5dd7070Spatrick }
2774e5dd7070Spatrick }
2775e5dd7070Spatrick
2776e5dd7070Spatrick return Method;
2777e5dd7070Spatrick }
2778e5dd7070Spatrick
VisitCXXConstructorDecl(CXXConstructorDecl * D)2779e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
2780e5dd7070Spatrick return VisitCXXMethodDecl(D);
2781e5dd7070Spatrick }
2782e5dd7070Spatrick
VisitCXXDestructorDecl(CXXDestructorDecl * D)2783e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
2784e5dd7070Spatrick return VisitCXXMethodDecl(D);
2785e5dd7070Spatrick }
2786e5dd7070Spatrick
VisitCXXConversionDecl(CXXConversionDecl * D)2787e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitCXXConversionDecl(CXXConversionDecl *D) {
2788e5dd7070Spatrick return VisitCXXMethodDecl(D);
2789e5dd7070Spatrick }
2790e5dd7070Spatrick
VisitParmVarDecl(ParmVarDecl * D)2791e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitParmVarDecl(ParmVarDecl *D) {
2792*12c85518Srobert return SemaRef.SubstParmVarDecl(D, TemplateArgs, /*indexAdjustment*/ 0,
2793*12c85518Srobert std::nullopt,
2794e5dd7070Spatrick /*ExpectParameterPack=*/false);
2795e5dd7070Spatrick }
2796e5dd7070Spatrick
VisitTemplateTypeParmDecl(TemplateTypeParmDecl * D)2797e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl(
2798e5dd7070Spatrick TemplateTypeParmDecl *D) {
2799e5dd7070Spatrick assert(D->getTypeForDecl()->isTemplateTypeParmType());
2800e5dd7070Spatrick
2801*12c85518Srobert std::optional<unsigned> NumExpanded;
2802e5dd7070Spatrick
2803e5dd7070Spatrick if (const TypeConstraint *TC = D->getTypeConstraint()) {
2804e5dd7070Spatrick if (D->isPackExpansion() && !D->isExpandedParameterPack()) {
2805e5dd7070Spatrick assert(TC->getTemplateArgsAsWritten() &&
2806e5dd7070Spatrick "type parameter can only be an expansion when explicit arguments "
2807e5dd7070Spatrick "are specified");
2808e5dd7070Spatrick // The template type parameter pack's type is a pack expansion of types.
2809e5dd7070Spatrick // Determine whether we need to expand this parameter pack into separate
2810e5dd7070Spatrick // types.
2811e5dd7070Spatrick SmallVector<UnexpandedParameterPack, 2> Unexpanded;
2812e5dd7070Spatrick for (auto &ArgLoc : TC->getTemplateArgsAsWritten()->arguments())
2813e5dd7070Spatrick SemaRef.collectUnexpandedParameterPacks(ArgLoc, Unexpanded);
2814e5dd7070Spatrick
2815e5dd7070Spatrick // Determine whether the set of unexpanded parameter packs can and should
2816e5dd7070Spatrick // be expanded.
2817e5dd7070Spatrick bool Expand = true;
2818e5dd7070Spatrick bool RetainExpansion = false;
2819e5dd7070Spatrick if (SemaRef.CheckParameterPacksForExpansion(
2820e5dd7070Spatrick cast<CXXFoldExpr>(TC->getImmediatelyDeclaredConstraint())
2821e5dd7070Spatrick ->getEllipsisLoc(),
2822e5dd7070Spatrick SourceRange(TC->getConceptNameLoc(),
2823e5dd7070Spatrick TC->hasExplicitTemplateArgs() ?
2824e5dd7070Spatrick TC->getTemplateArgsAsWritten()->getRAngleLoc() :
2825e5dd7070Spatrick TC->getConceptNameInfo().getEndLoc()),
2826e5dd7070Spatrick Unexpanded, TemplateArgs, Expand, RetainExpansion, NumExpanded))
2827e5dd7070Spatrick return nullptr;
2828e5dd7070Spatrick }
2829e5dd7070Spatrick }
2830e5dd7070Spatrick
2831e5dd7070Spatrick TemplateTypeParmDecl *Inst = TemplateTypeParmDecl::Create(
2832e5dd7070Spatrick SemaRef.Context, Owner, D->getBeginLoc(), D->getLocation(),
2833e5dd7070Spatrick D->getDepth() - TemplateArgs.getNumSubstitutedLevels(), D->getIndex(),
2834e5dd7070Spatrick D->getIdentifier(), D->wasDeclaredWithTypename(), D->isParameterPack(),
2835e5dd7070Spatrick D->hasTypeConstraint(), NumExpanded);
2836e5dd7070Spatrick
2837e5dd7070Spatrick Inst->setAccess(AS_public);
2838e5dd7070Spatrick Inst->setImplicit(D->isImplicit());
2839e5dd7070Spatrick if (auto *TC = D->getTypeConstraint()) {
2840e5dd7070Spatrick if (!D->isImplicit()) {
2841*12c85518Srobert // Invented template parameter type constraints will be instantiated
2842*12c85518Srobert // with the corresponding auto-typed parameter as it might reference
2843*12c85518Srobert // other parameters.
2844*12c85518Srobert if (SemaRef.SubstTypeConstraint(Inst, TC, TemplateArgs,
2845*12c85518Srobert EvaluateConstraints))
2846e5dd7070Spatrick return nullptr;
2847e5dd7070Spatrick }
2848e5dd7070Spatrick }
2849e5dd7070Spatrick if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) {
2850e5dd7070Spatrick TypeSourceInfo *InstantiatedDefaultArg =
2851e5dd7070Spatrick SemaRef.SubstType(D->getDefaultArgumentInfo(), TemplateArgs,
2852e5dd7070Spatrick D->getDefaultArgumentLoc(), D->getDeclName());
2853e5dd7070Spatrick if (InstantiatedDefaultArg)
2854e5dd7070Spatrick Inst->setDefaultArgument(InstantiatedDefaultArg);
2855e5dd7070Spatrick }
2856e5dd7070Spatrick
2857e5dd7070Spatrick // Introduce this template parameter's instantiation into the instantiation
2858e5dd7070Spatrick // scope.
2859e5dd7070Spatrick SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Inst);
2860e5dd7070Spatrick
2861e5dd7070Spatrick return Inst;
2862e5dd7070Spatrick }
2863e5dd7070Spatrick
VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl * D)2864e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl(
2865e5dd7070Spatrick NonTypeTemplateParmDecl *D) {
2866e5dd7070Spatrick // Substitute into the type of the non-type template parameter.
2867e5dd7070Spatrick TypeLoc TL = D->getTypeSourceInfo()->getTypeLoc();
2868e5dd7070Spatrick SmallVector<TypeSourceInfo *, 4> ExpandedParameterPackTypesAsWritten;
2869e5dd7070Spatrick SmallVector<QualType, 4> ExpandedParameterPackTypes;
2870e5dd7070Spatrick bool IsExpandedParameterPack = false;
2871e5dd7070Spatrick TypeSourceInfo *DI;
2872e5dd7070Spatrick QualType T;
2873e5dd7070Spatrick bool Invalid = false;
2874e5dd7070Spatrick
2875e5dd7070Spatrick if (D->isExpandedParameterPack()) {
2876e5dd7070Spatrick // The non-type template parameter pack is an already-expanded pack
2877e5dd7070Spatrick // expansion of types. Substitute into each of the expanded types.
2878e5dd7070Spatrick ExpandedParameterPackTypes.reserve(D->getNumExpansionTypes());
2879e5dd7070Spatrick ExpandedParameterPackTypesAsWritten.reserve(D->getNumExpansionTypes());
2880e5dd7070Spatrick for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) {
2881e5dd7070Spatrick TypeSourceInfo *NewDI =
2882e5dd7070Spatrick SemaRef.SubstType(D->getExpansionTypeSourceInfo(I), TemplateArgs,
2883e5dd7070Spatrick D->getLocation(), D->getDeclName());
2884e5dd7070Spatrick if (!NewDI)
2885e5dd7070Spatrick return nullptr;
2886e5dd7070Spatrick
2887e5dd7070Spatrick QualType NewT =
2888e5dd7070Spatrick SemaRef.CheckNonTypeTemplateParameterType(NewDI, D->getLocation());
2889e5dd7070Spatrick if (NewT.isNull())
2890e5dd7070Spatrick return nullptr;
2891e5dd7070Spatrick
2892e5dd7070Spatrick ExpandedParameterPackTypesAsWritten.push_back(NewDI);
2893e5dd7070Spatrick ExpandedParameterPackTypes.push_back(NewT);
2894e5dd7070Spatrick }
2895e5dd7070Spatrick
2896e5dd7070Spatrick IsExpandedParameterPack = true;
2897e5dd7070Spatrick DI = D->getTypeSourceInfo();
2898e5dd7070Spatrick T = DI->getType();
2899e5dd7070Spatrick } else if (D->isPackExpansion()) {
2900e5dd7070Spatrick // The non-type template parameter pack's type is a pack expansion of types.
2901e5dd7070Spatrick // Determine whether we need to expand this parameter pack into separate
2902e5dd7070Spatrick // types.
2903e5dd7070Spatrick PackExpansionTypeLoc Expansion = TL.castAs<PackExpansionTypeLoc>();
2904e5dd7070Spatrick TypeLoc Pattern = Expansion.getPatternLoc();
2905e5dd7070Spatrick SmallVector<UnexpandedParameterPack, 2> Unexpanded;
2906e5dd7070Spatrick SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded);
2907e5dd7070Spatrick
2908e5dd7070Spatrick // Determine whether the set of unexpanded parameter packs can and should
2909e5dd7070Spatrick // be expanded.
2910e5dd7070Spatrick bool Expand = true;
2911e5dd7070Spatrick bool RetainExpansion = false;
2912*12c85518Srobert std::optional<unsigned> OrigNumExpansions =
2913*12c85518Srobert Expansion.getTypePtr()->getNumExpansions();
2914*12c85518Srobert std::optional<unsigned> NumExpansions = OrigNumExpansions;
2915e5dd7070Spatrick if (SemaRef.CheckParameterPacksForExpansion(Expansion.getEllipsisLoc(),
2916e5dd7070Spatrick Pattern.getSourceRange(),
2917e5dd7070Spatrick Unexpanded,
2918e5dd7070Spatrick TemplateArgs,
2919e5dd7070Spatrick Expand, RetainExpansion,
2920e5dd7070Spatrick NumExpansions))
2921e5dd7070Spatrick return nullptr;
2922e5dd7070Spatrick
2923e5dd7070Spatrick if (Expand) {
2924e5dd7070Spatrick for (unsigned I = 0; I != *NumExpansions; ++I) {
2925e5dd7070Spatrick Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I);
2926e5dd7070Spatrick TypeSourceInfo *NewDI = SemaRef.SubstType(Pattern, TemplateArgs,
2927e5dd7070Spatrick D->getLocation(),
2928e5dd7070Spatrick D->getDeclName());
2929e5dd7070Spatrick if (!NewDI)
2930e5dd7070Spatrick return nullptr;
2931e5dd7070Spatrick
2932e5dd7070Spatrick QualType NewT =
2933e5dd7070Spatrick SemaRef.CheckNonTypeTemplateParameterType(NewDI, D->getLocation());
2934e5dd7070Spatrick if (NewT.isNull())
2935e5dd7070Spatrick return nullptr;
2936e5dd7070Spatrick
2937e5dd7070Spatrick ExpandedParameterPackTypesAsWritten.push_back(NewDI);
2938e5dd7070Spatrick ExpandedParameterPackTypes.push_back(NewT);
2939e5dd7070Spatrick }
2940e5dd7070Spatrick
2941e5dd7070Spatrick // Note that we have an expanded parameter pack. The "type" of this
2942e5dd7070Spatrick // expanded parameter pack is the original expansion type, but callers
2943e5dd7070Spatrick // will end up using the expanded parameter pack types for type-checking.
2944e5dd7070Spatrick IsExpandedParameterPack = true;
2945e5dd7070Spatrick DI = D->getTypeSourceInfo();
2946e5dd7070Spatrick T = DI->getType();
2947e5dd7070Spatrick } else {
2948e5dd7070Spatrick // We cannot fully expand the pack expansion now, so substitute into the
2949e5dd7070Spatrick // pattern and create a new pack expansion type.
2950e5dd7070Spatrick Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, -1);
2951e5dd7070Spatrick TypeSourceInfo *NewPattern = SemaRef.SubstType(Pattern, TemplateArgs,
2952e5dd7070Spatrick D->getLocation(),
2953e5dd7070Spatrick D->getDeclName());
2954e5dd7070Spatrick if (!NewPattern)
2955e5dd7070Spatrick return nullptr;
2956e5dd7070Spatrick
2957e5dd7070Spatrick SemaRef.CheckNonTypeTemplateParameterType(NewPattern, D->getLocation());
2958e5dd7070Spatrick DI = SemaRef.CheckPackExpansion(NewPattern, Expansion.getEllipsisLoc(),
2959e5dd7070Spatrick NumExpansions);
2960e5dd7070Spatrick if (!DI)
2961e5dd7070Spatrick return nullptr;
2962e5dd7070Spatrick
2963e5dd7070Spatrick T = DI->getType();
2964e5dd7070Spatrick }
2965e5dd7070Spatrick } else {
2966e5dd7070Spatrick // Simple case: substitution into a parameter that is not a parameter pack.
2967e5dd7070Spatrick DI = SemaRef.SubstType(D->getTypeSourceInfo(), TemplateArgs,
2968e5dd7070Spatrick D->getLocation(), D->getDeclName());
2969e5dd7070Spatrick if (!DI)
2970e5dd7070Spatrick return nullptr;
2971e5dd7070Spatrick
2972e5dd7070Spatrick // Check that this type is acceptable for a non-type template parameter.
2973e5dd7070Spatrick T = SemaRef.CheckNonTypeTemplateParameterType(DI, D->getLocation());
2974e5dd7070Spatrick if (T.isNull()) {
2975e5dd7070Spatrick T = SemaRef.Context.IntTy;
2976e5dd7070Spatrick Invalid = true;
2977e5dd7070Spatrick }
2978e5dd7070Spatrick }
2979e5dd7070Spatrick
2980e5dd7070Spatrick NonTypeTemplateParmDecl *Param;
2981e5dd7070Spatrick if (IsExpandedParameterPack)
2982e5dd7070Spatrick Param = NonTypeTemplateParmDecl::Create(
2983e5dd7070Spatrick SemaRef.Context, Owner, D->getInnerLocStart(), D->getLocation(),
2984e5dd7070Spatrick D->getDepth() - TemplateArgs.getNumSubstitutedLevels(),
2985e5dd7070Spatrick D->getPosition(), D->getIdentifier(), T, DI, ExpandedParameterPackTypes,
2986e5dd7070Spatrick ExpandedParameterPackTypesAsWritten);
2987e5dd7070Spatrick else
2988e5dd7070Spatrick Param = NonTypeTemplateParmDecl::Create(
2989e5dd7070Spatrick SemaRef.Context, Owner, D->getInnerLocStart(), D->getLocation(),
2990e5dd7070Spatrick D->getDepth() - TemplateArgs.getNumSubstitutedLevels(),
2991e5dd7070Spatrick D->getPosition(), D->getIdentifier(), T, D->isParameterPack(), DI);
2992e5dd7070Spatrick
2993e5dd7070Spatrick if (AutoTypeLoc AutoLoc = DI->getTypeLoc().getContainedAutoTypeLoc())
2994e5dd7070Spatrick if (AutoLoc.isConstrained())
2995e5dd7070Spatrick if (SemaRef.AttachTypeConstraint(
2996e5dd7070Spatrick AutoLoc, Param,
2997e5dd7070Spatrick IsExpandedParameterPack
2998e5dd7070Spatrick ? DI->getTypeLoc().getAs<PackExpansionTypeLoc>()
2999e5dd7070Spatrick .getEllipsisLoc()
3000e5dd7070Spatrick : SourceLocation()))
3001e5dd7070Spatrick Invalid = true;
3002e5dd7070Spatrick
3003e5dd7070Spatrick Param->setAccess(AS_public);
3004e5dd7070Spatrick Param->setImplicit(D->isImplicit());
3005e5dd7070Spatrick if (Invalid)
3006e5dd7070Spatrick Param->setInvalidDecl();
3007e5dd7070Spatrick
3008e5dd7070Spatrick if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) {
3009e5dd7070Spatrick EnterExpressionEvaluationContext ConstantEvaluated(
3010e5dd7070Spatrick SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
3011e5dd7070Spatrick ExprResult Value = SemaRef.SubstExpr(D->getDefaultArgument(), TemplateArgs);
3012e5dd7070Spatrick if (!Value.isInvalid())
3013e5dd7070Spatrick Param->setDefaultArgument(Value.get());
3014e5dd7070Spatrick }
3015e5dd7070Spatrick
3016e5dd7070Spatrick // Introduce this template parameter's instantiation into the instantiation
3017e5dd7070Spatrick // scope.
3018e5dd7070Spatrick SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Param);
3019e5dd7070Spatrick return Param;
3020e5dd7070Spatrick }
3021e5dd7070Spatrick
collectUnexpandedParameterPacks(Sema & S,TemplateParameterList * Params,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)3022e5dd7070Spatrick static void collectUnexpandedParameterPacks(
3023e5dd7070Spatrick Sema &S,
3024e5dd7070Spatrick TemplateParameterList *Params,
3025e5dd7070Spatrick SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
3026e5dd7070Spatrick for (const auto &P : *Params) {
3027e5dd7070Spatrick if (P->isTemplateParameterPack())
3028e5dd7070Spatrick continue;
3029e5dd7070Spatrick if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
3030e5dd7070Spatrick S.collectUnexpandedParameterPacks(NTTP->getTypeSourceInfo()->getTypeLoc(),
3031e5dd7070Spatrick Unexpanded);
3032e5dd7070Spatrick if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
3033e5dd7070Spatrick collectUnexpandedParameterPacks(S, TTP->getTemplateParameters(),
3034e5dd7070Spatrick Unexpanded);
3035e5dd7070Spatrick }
3036e5dd7070Spatrick }
3037e5dd7070Spatrick
3038e5dd7070Spatrick Decl *
VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl * D)3039e5dd7070Spatrick TemplateDeclInstantiator::VisitTemplateTemplateParmDecl(
3040e5dd7070Spatrick TemplateTemplateParmDecl *D) {
3041e5dd7070Spatrick // Instantiate the template parameter list of the template template parameter.
3042e5dd7070Spatrick TemplateParameterList *TempParams = D->getTemplateParameters();
3043e5dd7070Spatrick TemplateParameterList *InstParams;
3044e5dd7070Spatrick SmallVector<TemplateParameterList*, 8> ExpandedParams;
3045e5dd7070Spatrick
3046e5dd7070Spatrick bool IsExpandedParameterPack = false;
3047e5dd7070Spatrick
3048e5dd7070Spatrick if (D->isExpandedParameterPack()) {
3049e5dd7070Spatrick // The template template parameter pack is an already-expanded pack
3050e5dd7070Spatrick // expansion of template parameters. Substitute into each of the expanded
3051e5dd7070Spatrick // parameters.
3052e5dd7070Spatrick ExpandedParams.reserve(D->getNumExpansionTemplateParameters());
3053e5dd7070Spatrick for (unsigned I = 0, N = D->getNumExpansionTemplateParameters();
3054e5dd7070Spatrick I != N; ++I) {
3055e5dd7070Spatrick LocalInstantiationScope Scope(SemaRef);
3056e5dd7070Spatrick TemplateParameterList *Expansion =
3057e5dd7070Spatrick SubstTemplateParams(D->getExpansionTemplateParameters(I));
3058e5dd7070Spatrick if (!Expansion)
3059e5dd7070Spatrick return nullptr;
3060e5dd7070Spatrick ExpandedParams.push_back(Expansion);
3061e5dd7070Spatrick }
3062e5dd7070Spatrick
3063e5dd7070Spatrick IsExpandedParameterPack = true;
3064e5dd7070Spatrick InstParams = TempParams;
3065e5dd7070Spatrick } else if (D->isPackExpansion()) {
3066e5dd7070Spatrick // The template template parameter pack expands to a pack of template
3067e5dd7070Spatrick // template parameters. Determine whether we need to expand this parameter
3068e5dd7070Spatrick // pack into separate parameters.
3069e5dd7070Spatrick SmallVector<UnexpandedParameterPack, 2> Unexpanded;
3070e5dd7070Spatrick collectUnexpandedParameterPacks(SemaRef, D->getTemplateParameters(),
3071e5dd7070Spatrick Unexpanded);
3072e5dd7070Spatrick
3073e5dd7070Spatrick // Determine whether the set of unexpanded parameter packs can and should
3074e5dd7070Spatrick // be expanded.
3075e5dd7070Spatrick bool Expand = true;
3076e5dd7070Spatrick bool RetainExpansion = false;
3077*12c85518Srobert std::optional<unsigned> NumExpansions;
3078e5dd7070Spatrick if (SemaRef.CheckParameterPacksForExpansion(D->getLocation(),
3079e5dd7070Spatrick TempParams->getSourceRange(),
3080e5dd7070Spatrick Unexpanded,
3081e5dd7070Spatrick TemplateArgs,
3082e5dd7070Spatrick Expand, RetainExpansion,
3083e5dd7070Spatrick NumExpansions))
3084e5dd7070Spatrick return nullptr;
3085e5dd7070Spatrick
3086e5dd7070Spatrick if (Expand) {
3087e5dd7070Spatrick for (unsigned I = 0; I != *NumExpansions; ++I) {
3088e5dd7070Spatrick Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I);
3089e5dd7070Spatrick LocalInstantiationScope Scope(SemaRef);
3090e5dd7070Spatrick TemplateParameterList *Expansion = SubstTemplateParams(TempParams);
3091e5dd7070Spatrick if (!Expansion)
3092e5dd7070Spatrick return nullptr;
3093e5dd7070Spatrick ExpandedParams.push_back(Expansion);
3094e5dd7070Spatrick }
3095e5dd7070Spatrick
3096e5dd7070Spatrick // Note that we have an expanded parameter pack. The "type" of this
3097e5dd7070Spatrick // expanded parameter pack is the original expansion type, but callers
3098e5dd7070Spatrick // will end up using the expanded parameter pack types for type-checking.
3099e5dd7070Spatrick IsExpandedParameterPack = true;
3100e5dd7070Spatrick InstParams = TempParams;
3101e5dd7070Spatrick } else {
3102e5dd7070Spatrick // We cannot fully expand the pack expansion now, so just substitute
3103e5dd7070Spatrick // into the pattern.
3104e5dd7070Spatrick Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, -1);
3105e5dd7070Spatrick
3106e5dd7070Spatrick LocalInstantiationScope Scope(SemaRef);
3107e5dd7070Spatrick InstParams = SubstTemplateParams(TempParams);
3108e5dd7070Spatrick if (!InstParams)
3109e5dd7070Spatrick return nullptr;
3110e5dd7070Spatrick }
3111e5dd7070Spatrick } else {
3112e5dd7070Spatrick // Perform the actual substitution of template parameters within a new,
3113e5dd7070Spatrick // local instantiation scope.
3114e5dd7070Spatrick LocalInstantiationScope Scope(SemaRef);
3115e5dd7070Spatrick InstParams = SubstTemplateParams(TempParams);
3116e5dd7070Spatrick if (!InstParams)
3117e5dd7070Spatrick return nullptr;
3118e5dd7070Spatrick }
3119e5dd7070Spatrick
3120e5dd7070Spatrick // Build the template template parameter.
3121e5dd7070Spatrick TemplateTemplateParmDecl *Param;
3122e5dd7070Spatrick if (IsExpandedParameterPack)
3123e5dd7070Spatrick Param = TemplateTemplateParmDecl::Create(
3124e5dd7070Spatrick SemaRef.Context, Owner, D->getLocation(),
3125e5dd7070Spatrick D->getDepth() - TemplateArgs.getNumSubstitutedLevels(),
3126e5dd7070Spatrick D->getPosition(), D->getIdentifier(), InstParams, ExpandedParams);
3127e5dd7070Spatrick else
3128e5dd7070Spatrick Param = TemplateTemplateParmDecl::Create(
3129e5dd7070Spatrick SemaRef.Context, Owner, D->getLocation(),
3130e5dd7070Spatrick D->getDepth() - TemplateArgs.getNumSubstitutedLevels(),
3131e5dd7070Spatrick D->getPosition(), D->isParameterPack(), D->getIdentifier(), InstParams);
3132e5dd7070Spatrick if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) {
3133e5dd7070Spatrick NestedNameSpecifierLoc QualifierLoc =
3134e5dd7070Spatrick D->getDefaultArgument().getTemplateQualifierLoc();
3135e5dd7070Spatrick QualifierLoc =
3136e5dd7070Spatrick SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, TemplateArgs);
3137e5dd7070Spatrick TemplateName TName = SemaRef.SubstTemplateName(
3138e5dd7070Spatrick QualifierLoc, D->getDefaultArgument().getArgument().getAsTemplate(),
3139e5dd7070Spatrick D->getDefaultArgument().getTemplateNameLoc(), TemplateArgs);
3140e5dd7070Spatrick if (!TName.isNull())
3141e5dd7070Spatrick Param->setDefaultArgument(
3142e5dd7070Spatrick SemaRef.Context,
3143a9ac8606Spatrick TemplateArgumentLoc(SemaRef.Context, TemplateArgument(TName),
3144e5dd7070Spatrick D->getDefaultArgument().getTemplateQualifierLoc(),
3145e5dd7070Spatrick D->getDefaultArgument().getTemplateNameLoc()));
3146e5dd7070Spatrick }
3147e5dd7070Spatrick Param->setAccess(AS_public);
3148e5dd7070Spatrick Param->setImplicit(D->isImplicit());
3149e5dd7070Spatrick
3150e5dd7070Spatrick // Introduce this template parameter's instantiation into the instantiation
3151e5dd7070Spatrick // scope.
3152e5dd7070Spatrick SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Param);
3153e5dd7070Spatrick
3154e5dd7070Spatrick return Param;
3155e5dd7070Spatrick }
3156e5dd7070Spatrick
VisitUsingDirectiveDecl(UsingDirectiveDecl * D)3157e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
3158e5dd7070Spatrick // Using directives are never dependent (and never contain any types or
3159e5dd7070Spatrick // expressions), so they require no explicit instantiation work.
3160e5dd7070Spatrick
3161e5dd7070Spatrick UsingDirectiveDecl *Inst
3162e5dd7070Spatrick = UsingDirectiveDecl::Create(SemaRef.Context, Owner, D->getLocation(),
3163e5dd7070Spatrick D->getNamespaceKeyLocation(),
3164e5dd7070Spatrick D->getQualifierLoc(),
3165e5dd7070Spatrick D->getIdentLocation(),
3166e5dd7070Spatrick D->getNominatedNamespace(),
3167e5dd7070Spatrick D->getCommonAncestor());
3168e5dd7070Spatrick
3169e5dd7070Spatrick // Add the using directive to its declaration context
3170e5dd7070Spatrick // only if this is not a function or method.
3171e5dd7070Spatrick if (!Owner->isFunctionOrMethod())
3172e5dd7070Spatrick Owner->addDecl(Inst);
3173e5dd7070Spatrick
3174e5dd7070Spatrick return Inst;
3175e5dd7070Spatrick }
3176e5dd7070Spatrick
VisitBaseUsingDecls(BaseUsingDecl * D,BaseUsingDecl * Inst,LookupResult * Lookup)3177a9ac8606Spatrick Decl *TemplateDeclInstantiator::VisitBaseUsingDecls(BaseUsingDecl *D,
3178a9ac8606Spatrick BaseUsingDecl *Inst,
3179a9ac8606Spatrick LookupResult *Lookup) {
3180a9ac8606Spatrick
3181a9ac8606Spatrick bool isFunctionScope = Owner->isFunctionOrMethod();
3182a9ac8606Spatrick
3183a9ac8606Spatrick for (auto *Shadow : D->shadows()) {
3184a9ac8606Spatrick // FIXME: UsingShadowDecl doesn't preserve its immediate target, so
3185a9ac8606Spatrick // reconstruct it in the case where it matters. Hm, can we extract it from
3186a9ac8606Spatrick // the DeclSpec when parsing and save it in the UsingDecl itself?
3187a9ac8606Spatrick NamedDecl *OldTarget = Shadow->getTargetDecl();
3188a9ac8606Spatrick if (auto *CUSD = dyn_cast<ConstructorUsingShadowDecl>(Shadow))
3189a9ac8606Spatrick if (auto *BaseShadow = CUSD->getNominatedBaseClassShadowDecl())
3190a9ac8606Spatrick OldTarget = BaseShadow;
3191a9ac8606Spatrick
3192a9ac8606Spatrick NamedDecl *InstTarget = nullptr;
3193a9ac8606Spatrick if (auto *EmptyD =
3194a9ac8606Spatrick dyn_cast<UnresolvedUsingIfExistsDecl>(Shadow->getTargetDecl())) {
3195a9ac8606Spatrick InstTarget = UnresolvedUsingIfExistsDecl::Create(
3196a9ac8606Spatrick SemaRef.Context, Owner, EmptyD->getLocation(), EmptyD->getDeclName());
3197a9ac8606Spatrick } else {
3198a9ac8606Spatrick InstTarget = cast_or_null<NamedDecl>(SemaRef.FindInstantiatedDecl(
3199a9ac8606Spatrick Shadow->getLocation(), OldTarget, TemplateArgs));
3200a9ac8606Spatrick }
3201a9ac8606Spatrick if (!InstTarget)
3202a9ac8606Spatrick return nullptr;
3203a9ac8606Spatrick
3204a9ac8606Spatrick UsingShadowDecl *PrevDecl = nullptr;
3205a9ac8606Spatrick if (Lookup &&
3206a9ac8606Spatrick SemaRef.CheckUsingShadowDecl(Inst, InstTarget, *Lookup, PrevDecl))
3207a9ac8606Spatrick continue;
3208a9ac8606Spatrick
3209a9ac8606Spatrick if (UsingShadowDecl *OldPrev = getPreviousDeclForInstantiation(Shadow))
3210a9ac8606Spatrick PrevDecl = cast_or_null<UsingShadowDecl>(SemaRef.FindInstantiatedDecl(
3211a9ac8606Spatrick Shadow->getLocation(), OldPrev, TemplateArgs));
3212a9ac8606Spatrick
3213a9ac8606Spatrick UsingShadowDecl *InstShadow = SemaRef.BuildUsingShadowDecl(
3214a9ac8606Spatrick /*Scope*/ nullptr, Inst, InstTarget, PrevDecl);
3215a9ac8606Spatrick SemaRef.Context.setInstantiatedFromUsingShadowDecl(InstShadow, Shadow);
3216a9ac8606Spatrick
3217a9ac8606Spatrick if (isFunctionScope)
3218a9ac8606Spatrick SemaRef.CurrentInstantiationScope->InstantiatedLocal(Shadow, InstShadow);
3219a9ac8606Spatrick }
3220a9ac8606Spatrick
3221a9ac8606Spatrick return Inst;
3222a9ac8606Spatrick }
3223a9ac8606Spatrick
VisitUsingDecl(UsingDecl * D)3224e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) {
3225e5dd7070Spatrick
3226e5dd7070Spatrick // The nested name specifier may be dependent, for example
3227e5dd7070Spatrick // template <typename T> struct t {
3228e5dd7070Spatrick // struct s1 { T f1(); };
3229e5dd7070Spatrick // struct s2 : s1 { using s1::f1; };
3230e5dd7070Spatrick // };
3231e5dd7070Spatrick // template struct t<int>;
3232e5dd7070Spatrick // Here, in using s1::f1, s1 refers to t<T>::s1;
3233e5dd7070Spatrick // we need to substitute for t<int>::s1.
3234e5dd7070Spatrick NestedNameSpecifierLoc QualifierLoc
3235e5dd7070Spatrick = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(),
3236e5dd7070Spatrick TemplateArgs);
3237e5dd7070Spatrick if (!QualifierLoc)
3238e5dd7070Spatrick return nullptr;
3239e5dd7070Spatrick
3240e5dd7070Spatrick // For an inheriting constructor declaration, the name of the using
3241e5dd7070Spatrick // declaration is the name of a constructor in this class, not in the
3242e5dd7070Spatrick // base class.
3243e5dd7070Spatrick DeclarationNameInfo NameInfo = D->getNameInfo();
3244e5dd7070Spatrick if (NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName)
3245e5dd7070Spatrick if (auto *RD = dyn_cast<CXXRecordDecl>(SemaRef.CurContext))
3246e5dd7070Spatrick NameInfo.setName(SemaRef.Context.DeclarationNames.getCXXConstructorName(
3247e5dd7070Spatrick SemaRef.Context.getCanonicalType(SemaRef.Context.getRecordType(RD))));
3248e5dd7070Spatrick
3249a9ac8606Spatrick // We only need to do redeclaration lookups if we're in a class scope (in
3250a9ac8606Spatrick // fact, it's not really even possible in non-class scopes).
3251e5dd7070Spatrick bool CheckRedeclaration = Owner->isRecord();
3252e5dd7070Spatrick LookupResult Prev(SemaRef, NameInfo, Sema::LookupUsingDeclName,
3253e5dd7070Spatrick Sema::ForVisibleRedeclaration);
3254e5dd7070Spatrick
3255e5dd7070Spatrick UsingDecl *NewUD = UsingDecl::Create(SemaRef.Context, Owner,
3256e5dd7070Spatrick D->getUsingLoc(),
3257e5dd7070Spatrick QualifierLoc,
3258e5dd7070Spatrick NameInfo,
3259e5dd7070Spatrick D->hasTypename());
3260e5dd7070Spatrick
3261e5dd7070Spatrick CXXScopeSpec SS;
3262e5dd7070Spatrick SS.Adopt(QualifierLoc);
3263e5dd7070Spatrick if (CheckRedeclaration) {
3264e5dd7070Spatrick Prev.setHideTags(false);
3265e5dd7070Spatrick SemaRef.LookupQualifiedName(Prev, Owner);
3266e5dd7070Spatrick
3267e5dd7070Spatrick // Check for invalid redeclarations.
3268e5dd7070Spatrick if (SemaRef.CheckUsingDeclRedeclaration(D->getUsingLoc(),
3269e5dd7070Spatrick D->hasTypename(), SS,
3270e5dd7070Spatrick D->getLocation(), Prev))
3271e5dd7070Spatrick NewUD->setInvalidDecl();
3272e5dd7070Spatrick }
3273e5dd7070Spatrick
3274e5dd7070Spatrick if (!NewUD->isInvalidDecl() &&
3275a9ac8606Spatrick SemaRef.CheckUsingDeclQualifier(D->getUsingLoc(), D->hasTypename(), SS,
3276a9ac8606Spatrick NameInfo, D->getLocation(), nullptr, D))
3277e5dd7070Spatrick NewUD->setInvalidDecl();
3278e5dd7070Spatrick
3279e5dd7070Spatrick SemaRef.Context.setInstantiatedFromUsingDecl(NewUD, D);
3280e5dd7070Spatrick NewUD->setAccess(D->getAccess());
3281e5dd7070Spatrick Owner->addDecl(NewUD);
3282e5dd7070Spatrick
3283e5dd7070Spatrick // Don't process the shadow decls for an invalid decl.
3284e5dd7070Spatrick if (NewUD->isInvalidDecl())
3285e5dd7070Spatrick return NewUD;
3286e5dd7070Spatrick
3287a9ac8606Spatrick // If the using scope was dependent, or we had dependent bases, we need to
3288a9ac8606Spatrick // recheck the inheritance
3289e5dd7070Spatrick if (NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName)
3290e5dd7070Spatrick SemaRef.CheckInheritingConstructorUsingDecl(NewUD);
3291e5dd7070Spatrick
3292a9ac8606Spatrick return VisitBaseUsingDecls(D, NewUD, CheckRedeclaration ? &Prev : nullptr);
3293a9ac8606Spatrick }
3294e5dd7070Spatrick
VisitUsingEnumDecl(UsingEnumDecl * D)3295a9ac8606Spatrick Decl *TemplateDeclInstantiator::VisitUsingEnumDecl(UsingEnumDecl *D) {
3296a9ac8606Spatrick // Cannot be a dependent type, but still could be an instantiation
3297a9ac8606Spatrick EnumDecl *EnumD = cast_or_null<EnumDecl>(SemaRef.FindInstantiatedDecl(
3298a9ac8606Spatrick D->getLocation(), D->getEnumDecl(), TemplateArgs));
3299e5dd7070Spatrick
3300a9ac8606Spatrick if (SemaRef.RequireCompleteEnumDecl(EnumD, EnumD->getLocation()))
3301e5dd7070Spatrick return nullptr;
3302e5dd7070Spatrick
3303*12c85518Srobert TypeSourceInfo *TSI = SemaRef.SubstType(D->getEnumType(), TemplateArgs,
3304*12c85518Srobert D->getLocation(), D->getDeclName());
3305a9ac8606Spatrick UsingEnumDecl *NewUD =
3306a9ac8606Spatrick UsingEnumDecl::Create(SemaRef.Context, Owner, D->getUsingLoc(),
3307*12c85518Srobert D->getEnumLoc(), D->getLocation(), TSI);
3308e5dd7070Spatrick
3309a9ac8606Spatrick SemaRef.Context.setInstantiatedFromUsingEnumDecl(NewUD, D);
3310a9ac8606Spatrick NewUD->setAccess(D->getAccess());
3311a9ac8606Spatrick Owner->addDecl(NewUD);
3312e5dd7070Spatrick
3313a9ac8606Spatrick // Don't process the shadow decls for an invalid decl.
3314a9ac8606Spatrick if (NewUD->isInvalidDecl())
3315e5dd7070Spatrick return NewUD;
3316a9ac8606Spatrick
3317a9ac8606Spatrick // We don't have to recheck for duplication of the UsingEnumDecl itself, as it
3318a9ac8606Spatrick // cannot be dependent, and will therefore have been checked during template
3319a9ac8606Spatrick // definition.
3320a9ac8606Spatrick
3321a9ac8606Spatrick return VisitBaseUsingDecls(D, NewUD, nullptr);
3322e5dd7070Spatrick }
3323e5dd7070Spatrick
VisitUsingShadowDecl(UsingShadowDecl * D)3324e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitUsingShadowDecl(UsingShadowDecl *D) {
3325e5dd7070Spatrick // Ignore these; we handle them in bulk when processing the UsingDecl.
3326e5dd7070Spatrick return nullptr;
3327e5dd7070Spatrick }
3328e5dd7070Spatrick
VisitConstructorUsingShadowDecl(ConstructorUsingShadowDecl * D)3329e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitConstructorUsingShadowDecl(
3330e5dd7070Spatrick ConstructorUsingShadowDecl *D) {
3331e5dd7070Spatrick // Ignore these; we handle them in bulk when processing the UsingDecl.
3332e5dd7070Spatrick return nullptr;
3333e5dd7070Spatrick }
3334e5dd7070Spatrick
3335e5dd7070Spatrick template <typename T>
instantiateUnresolvedUsingDecl(T * D,bool InstantiatingPackElement)3336e5dd7070Spatrick Decl *TemplateDeclInstantiator::instantiateUnresolvedUsingDecl(
3337e5dd7070Spatrick T *D, bool InstantiatingPackElement) {
3338e5dd7070Spatrick // If this is a pack expansion, expand it now.
3339e5dd7070Spatrick if (D->isPackExpansion() && !InstantiatingPackElement) {
3340e5dd7070Spatrick SmallVector<UnexpandedParameterPack, 2> Unexpanded;
3341e5dd7070Spatrick SemaRef.collectUnexpandedParameterPacks(D->getQualifierLoc(), Unexpanded);
3342e5dd7070Spatrick SemaRef.collectUnexpandedParameterPacks(D->getNameInfo(), Unexpanded);
3343e5dd7070Spatrick
3344e5dd7070Spatrick // Determine whether the set of unexpanded parameter packs can and should
3345e5dd7070Spatrick // be expanded.
3346e5dd7070Spatrick bool Expand = true;
3347e5dd7070Spatrick bool RetainExpansion = false;
3348*12c85518Srobert std::optional<unsigned> NumExpansions;
3349e5dd7070Spatrick if (SemaRef.CheckParameterPacksForExpansion(
3350e5dd7070Spatrick D->getEllipsisLoc(), D->getSourceRange(), Unexpanded, TemplateArgs,
3351e5dd7070Spatrick Expand, RetainExpansion, NumExpansions))
3352e5dd7070Spatrick return nullptr;
3353e5dd7070Spatrick
3354e5dd7070Spatrick // This declaration cannot appear within a function template signature,
3355e5dd7070Spatrick // so we can't have a partial argument list for a parameter pack.
3356e5dd7070Spatrick assert(!RetainExpansion &&
3357e5dd7070Spatrick "should never need to retain an expansion for UsingPackDecl");
3358e5dd7070Spatrick
3359e5dd7070Spatrick if (!Expand) {
3360e5dd7070Spatrick // We cannot fully expand the pack expansion now, so substitute into the
3361e5dd7070Spatrick // pattern and create a new pack expansion.
3362e5dd7070Spatrick Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, -1);
3363e5dd7070Spatrick return instantiateUnresolvedUsingDecl(D, true);
3364e5dd7070Spatrick }
3365e5dd7070Spatrick
3366e5dd7070Spatrick // Within a function, we don't have any normal way to check for conflicts
3367e5dd7070Spatrick // between shadow declarations from different using declarations in the
3368e5dd7070Spatrick // same pack expansion, but this is always ill-formed because all expansions
3369e5dd7070Spatrick // must produce (conflicting) enumerators.
3370e5dd7070Spatrick //
3371e5dd7070Spatrick // Sadly we can't just reject this in the template definition because it
3372e5dd7070Spatrick // could be valid if the pack is empty or has exactly one expansion.
3373e5dd7070Spatrick if (D->getDeclContext()->isFunctionOrMethod() && *NumExpansions > 1) {
3374e5dd7070Spatrick SemaRef.Diag(D->getEllipsisLoc(),
3375e5dd7070Spatrick diag::err_using_decl_redeclaration_expansion);
3376e5dd7070Spatrick return nullptr;
3377e5dd7070Spatrick }
3378e5dd7070Spatrick
3379e5dd7070Spatrick // Instantiate the slices of this pack and build a UsingPackDecl.
3380e5dd7070Spatrick SmallVector<NamedDecl*, 8> Expansions;
3381e5dd7070Spatrick for (unsigned I = 0; I != *NumExpansions; ++I) {
3382e5dd7070Spatrick Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I);
3383e5dd7070Spatrick Decl *Slice = instantiateUnresolvedUsingDecl(D, true);
3384e5dd7070Spatrick if (!Slice)
3385e5dd7070Spatrick return nullptr;
3386e5dd7070Spatrick // Note that we can still get unresolved using declarations here, if we
3387e5dd7070Spatrick // had arguments for all packs but the pattern also contained other
3388e5dd7070Spatrick // template arguments (this only happens during partial substitution, eg
3389e5dd7070Spatrick // into the body of a generic lambda in a function template).
3390e5dd7070Spatrick Expansions.push_back(cast<NamedDecl>(Slice));
3391e5dd7070Spatrick }
3392e5dd7070Spatrick
3393e5dd7070Spatrick auto *NewD = SemaRef.BuildUsingPackDecl(D, Expansions);
3394e5dd7070Spatrick if (isDeclWithinFunction(D))
3395e5dd7070Spatrick SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewD);
3396e5dd7070Spatrick return NewD;
3397e5dd7070Spatrick }
3398e5dd7070Spatrick
3399e5dd7070Spatrick UnresolvedUsingTypenameDecl *TD = dyn_cast<UnresolvedUsingTypenameDecl>(D);
3400e5dd7070Spatrick SourceLocation TypenameLoc = TD ? TD->getTypenameLoc() : SourceLocation();
3401e5dd7070Spatrick
3402e5dd7070Spatrick NestedNameSpecifierLoc QualifierLoc
3403e5dd7070Spatrick = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(),
3404e5dd7070Spatrick TemplateArgs);
3405e5dd7070Spatrick if (!QualifierLoc)
3406e5dd7070Spatrick return nullptr;
3407e5dd7070Spatrick
3408e5dd7070Spatrick CXXScopeSpec SS;
3409e5dd7070Spatrick SS.Adopt(QualifierLoc);
3410e5dd7070Spatrick
3411e5dd7070Spatrick DeclarationNameInfo NameInfo
3412e5dd7070Spatrick = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
3413e5dd7070Spatrick
3414e5dd7070Spatrick // Produce a pack expansion only if we're not instantiating a particular
3415e5dd7070Spatrick // slice of a pack expansion.
3416e5dd7070Spatrick bool InstantiatingSlice = D->getEllipsisLoc().isValid() &&
3417e5dd7070Spatrick SemaRef.ArgumentPackSubstitutionIndex != -1;
3418e5dd7070Spatrick SourceLocation EllipsisLoc =
3419e5dd7070Spatrick InstantiatingSlice ? SourceLocation() : D->getEllipsisLoc();
3420e5dd7070Spatrick
3421a9ac8606Spatrick bool IsUsingIfExists = D->template hasAttr<UsingIfExistsAttr>();
3422e5dd7070Spatrick NamedDecl *UD = SemaRef.BuildUsingDeclaration(
3423e5dd7070Spatrick /*Scope*/ nullptr, D->getAccess(), D->getUsingLoc(),
3424e5dd7070Spatrick /*HasTypename*/ TD, TypenameLoc, SS, NameInfo, EllipsisLoc,
3425e5dd7070Spatrick ParsedAttributesView(),
3426a9ac8606Spatrick /*IsInstantiation*/ true, IsUsingIfExists);
3427a9ac8606Spatrick if (UD) {
3428a9ac8606Spatrick SemaRef.InstantiateAttrs(TemplateArgs, D, UD);
3429e5dd7070Spatrick SemaRef.Context.setInstantiatedFromUsingDecl(UD, D);
3430a9ac8606Spatrick }
3431e5dd7070Spatrick
3432e5dd7070Spatrick return UD;
3433e5dd7070Spatrick }
3434e5dd7070Spatrick
VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl * D)3435e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitUnresolvedUsingTypenameDecl(
3436e5dd7070Spatrick UnresolvedUsingTypenameDecl *D) {
3437e5dd7070Spatrick return instantiateUnresolvedUsingDecl(D);
3438e5dd7070Spatrick }
3439e5dd7070Spatrick
VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl * D)3440e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitUnresolvedUsingValueDecl(
3441e5dd7070Spatrick UnresolvedUsingValueDecl *D) {
3442e5dd7070Spatrick return instantiateUnresolvedUsingDecl(D);
3443e5dd7070Spatrick }
3444e5dd7070Spatrick
VisitUnresolvedUsingIfExistsDecl(UnresolvedUsingIfExistsDecl * D)3445a9ac8606Spatrick Decl *TemplateDeclInstantiator::VisitUnresolvedUsingIfExistsDecl(
3446a9ac8606Spatrick UnresolvedUsingIfExistsDecl *D) {
3447a9ac8606Spatrick llvm_unreachable("referring to unresolved decl out of UsingShadowDecl");
3448a9ac8606Spatrick }
3449a9ac8606Spatrick
VisitUsingPackDecl(UsingPackDecl * D)3450e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitUsingPackDecl(UsingPackDecl *D) {
3451e5dd7070Spatrick SmallVector<NamedDecl*, 8> Expansions;
3452e5dd7070Spatrick for (auto *UD : D->expansions()) {
3453e5dd7070Spatrick if (NamedDecl *NewUD =
3454e5dd7070Spatrick SemaRef.FindInstantiatedDecl(D->getLocation(), UD, TemplateArgs))
3455e5dd7070Spatrick Expansions.push_back(NewUD);
3456e5dd7070Spatrick else
3457e5dd7070Spatrick return nullptr;
3458e5dd7070Spatrick }
3459e5dd7070Spatrick
3460e5dd7070Spatrick auto *NewD = SemaRef.BuildUsingPackDecl(D, Expansions);
3461e5dd7070Spatrick if (isDeclWithinFunction(D))
3462e5dd7070Spatrick SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewD);
3463e5dd7070Spatrick return NewD;
3464e5dd7070Spatrick }
3465e5dd7070Spatrick
VisitClassScopeFunctionSpecializationDecl(ClassScopeFunctionSpecializationDecl * Decl)3466e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitClassScopeFunctionSpecializationDecl(
3467e5dd7070Spatrick ClassScopeFunctionSpecializationDecl *Decl) {
3468e5dd7070Spatrick CXXMethodDecl *OldFD = Decl->getSpecialization();
3469e5dd7070Spatrick return cast_or_null<CXXMethodDecl>(
3470e5dd7070Spatrick VisitCXXMethodDecl(OldFD, nullptr, Decl->getTemplateArgsAsWritten()));
3471e5dd7070Spatrick }
3472e5dd7070Spatrick
VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl * D)3473e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitOMPThreadPrivateDecl(
3474e5dd7070Spatrick OMPThreadPrivateDecl *D) {
3475e5dd7070Spatrick SmallVector<Expr *, 5> Vars;
3476e5dd7070Spatrick for (auto *I : D->varlists()) {
3477e5dd7070Spatrick Expr *Var = SemaRef.SubstExpr(I, TemplateArgs).get();
3478e5dd7070Spatrick assert(isa<DeclRefExpr>(Var) && "threadprivate arg is not a DeclRefExpr");
3479e5dd7070Spatrick Vars.push_back(Var);
3480e5dd7070Spatrick }
3481e5dd7070Spatrick
3482e5dd7070Spatrick OMPThreadPrivateDecl *TD =
3483e5dd7070Spatrick SemaRef.CheckOMPThreadPrivateDecl(D->getLocation(), Vars);
3484e5dd7070Spatrick
3485e5dd7070Spatrick TD->setAccess(AS_public);
3486e5dd7070Spatrick Owner->addDecl(TD);
3487e5dd7070Spatrick
3488e5dd7070Spatrick return TD;
3489e5dd7070Spatrick }
3490e5dd7070Spatrick
VisitOMPAllocateDecl(OMPAllocateDecl * D)3491e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitOMPAllocateDecl(OMPAllocateDecl *D) {
3492e5dd7070Spatrick SmallVector<Expr *, 5> Vars;
3493e5dd7070Spatrick for (auto *I : D->varlists()) {
3494e5dd7070Spatrick Expr *Var = SemaRef.SubstExpr(I, TemplateArgs).get();
3495e5dd7070Spatrick assert(isa<DeclRefExpr>(Var) && "allocate arg is not a DeclRefExpr");
3496e5dd7070Spatrick Vars.push_back(Var);
3497e5dd7070Spatrick }
3498e5dd7070Spatrick SmallVector<OMPClause *, 4> Clauses;
3499e5dd7070Spatrick // Copy map clauses from the original mapper.
3500e5dd7070Spatrick for (OMPClause *C : D->clauselists()) {
3501*12c85518Srobert OMPClause *IC = nullptr;
3502*12c85518Srobert if (auto *AC = dyn_cast<OMPAllocatorClause>(C)) {
3503e5dd7070Spatrick ExprResult NewE = SemaRef.SubstExpr(AC->getAllocator(), TemplateArgs);
3504e5dd7070Spatrick if (!NewE.isUsable())
3505e5dd7070Spatrick continue;
3506*12c85518Srobert IC = SemaRef.ActOnOpenMPAllocatorClause(
3507e5dd7070Spatrick NewE.get(), AC->getBeginLoc(), AC->getLParenLoc(), AC->getEndLoc());
3508*12c85518Srobert } else if (auto *AC = dyn_cast<OMPAlignClause>(C)) {
3509*12c85518Srobert ExprResult NewE = SemaRef.SubstExpr(AC->getAlignment(), TemplateArgs);
3510*12c85518Srobert if (!NewE.isUsable())
3511*12c85518Srobert continue;
3512*12c85518Srobert IC = SemaRef.ActOnOpenMPAlignClause(NewE.get(), AC->getBeginLoc(),
3513*12c85518Srobert AC->getLParenLoc(), AC->getEndLoc());
3514*12c85518Srobert // If align clause value ends up being invalid, this can end up null.
3515*12c85518Srobert if (!IC)
3516*12c85518Srobert continue;
3517*12c85518Srobert }
3518e5dd7070Spatrick Clauses.push_back(IC);
3519e5dd7070Spatrick }
3520e5dd7070Spatrick
3521e5dd7070Spatrick Sema::DeclGroupPtrTy Res = SemaRef.ActOnOpenMPAllocateDirective(
3522e5dd7070Spatrick D->getLocation(), Vars, Clauses, Owner);
3523e5dd7070Spatrick if (Res.get().isNull())
3524e5dd7070Spatrick return nullptr;
3525e5dd7070Spatrick return Res.get().getSingleDecl();
3526e5dd7070Spatrick }
3527e5dd7070Spatrick
VisitOMPRequiresDecl(OMPRequiresDecl * D)3528e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitOMPRequiresDecl(OMPRequiresDecl *D) {
3529e5dd7070Spatrick llvm_unreachable(
3530e5dd7070Spatrick "Requires directive cannot be instantiated within a dependent context");
3531e5dd7070Spatrick }
3532e5dd7070Spatrick
VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl * D)3533e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl(
3534e5dd7070Spatrick OMPDeclareReductionDecl *D) {
3535e5dd7070Spatrick // Instantiate type and check if it is allowed.
3536e5dd7070Spatrick const bool RequiresInstantiation =
3537e5dd7070Spatrick D->getType()->isDependentType() ||
3538e5dd7070Spatrick D->getType()->isInstantiationDependentType() ||
3539e5dd7070Spatrick D->getType()->containsUnexpandedParameterPack();
3540e5dd7070Spatrick QualType SubstReductionType;
3541e5dd7070Spatrick if (RequiresInstantiation) {
3542e5dd7070Spatrick SubstReductionType = SemaRef.ActOnOpenMPDeclareReductionType(
3543e5dd7070Spatrick D->getLocation(),
3544e5dd7070Spatrick ParsedType::make(SemaRef.SubstType(
3545e5dd7070Spatrick D->getType(), TemplateArgs, D->getLocation(), DeclarationName())));
3546e5dd7070Spatrick } else {
3547e5dd7070Spatrick SubstReductionType = D->getType();
3548e5dd7070Spatrick }
3549e5dd7070Spatrick if (SubstReductionType.isNull())
3550e5dd7070Spatrick return nullptr;
3551e5dd7070Spatrick Expr *Combiner = D->getCombiner();
3552e5dd7070Spatrick Expr *Init = D->getInitializer();
3553e5dd7070Spatrick bool IsCorrect = true;
3554e5dd7070Spatrick // Create instantiated copy.
3555e5dd7070Spatrick std::pair<QualType, SourceLocation> ReductionTypes[] = {
3556e5dd7070Spatrick std::make_pair(SubstReductionType, D->getLocation())};
3557e5dd7070Spatrick auto *PrevDeclInScope = D->getPrevDeclInScope();
3558e5dd7070Spatrick if (PrevDeclInScope && !PrevDeclInScope->isInvalidDecl()) {
3559e5dd7070Spatrick PrevDeclInScope = cast<OMPDeclareReductionDecl>(
3560e5dd7070Spatrick SemaRef.CurrentInstantiationScope->findInstantiationOf(PrevDeclInScope)
3561e5dd7070Spatrick ->get<Decl *>());
3562e5dd7070Spatrick }
3563e5dd7070Spatrick auto DRD = SemaRef.ActOnOpenMPDeclareReductionDirectiveStart(
3564e5dd7070Spatrick /*S=*/nullptr, Owner, D->getDeclName(), ReductionTypes, D->getAccess(),
3565e5dd7070Spatrick PrevDeclInScope);
3566e5dd7070Spatrick auto *NewDRD = cast<OMPDeclareReductionDecl>(DRD.get().getSingleDecl());
3567e5dd7070Spatrick SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewDRD);
3568e5dd7070Spatrick Expr *SubstCombiner = nullptr;
3569e5dd7070Spatrick Expr *SubstInitializer = nullptr;
3570e5dd7070Spatrick // Combiners instantiation sequence.
3571e5dd7070Spatrick if (Combiner) {
3572e5dd7070Spatrick SemaRef.ActOnOpenMPDeclareReductionCombinerStart(
3573e5dd7070Spatrick /*S=*/nullptr, NewDRD);
3574e5dd7070Spatrick SemaRef.CurrentInstantiationScope->InstantiatedLocal(
3575e5dd7070Spatrick cast<DeclRefExpr>(D->getCombinerIn())->getDecl(),
3576e5dd7070Spatrick cast<DeclRefExpr>(NewDRD->getCombinerIn())->getDecl());
3577e5dd7070Spatrick SemaRef.CurrentInstantiationScope->InstantiatedLocal(
3578e5dd7070Spatrick cast<DeclRefExpr>(D->getCombinerOut())->getDecl(),
3579e5dd7070Spatrick cast<DeclRefExpr>(NewDRD->getCombinerOut())->getDecl());
3580e5dd7070Spatrick auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(Owner);
3581e5dd7070Spatrick Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, Qualifiers(),
3582e5dd7070Spatrick ThisContext);
3583e5dd7070Spatrick SubstCombiner = SemaRef.SubstExpr(Combiner, TemplateArgs).get();
3584e5dd7070Spatrick SemaRef.ActOnOpenMPDeclareReductionCombinerEnd(NewDRD, SubstCombiner);
3585e5dd7070Spatrick }
3586e5dd7070Spatrick // Initializers instantiation sequence.
3587e5dd7070Spatrick if (Init) {
3588e5dd7070Spatrick VarDecl *OmpPrivParm = SemaRef.ActOnOpenMPDeclareReductionInitializerStart(
3589e5dd7070Spatrick /*S=*/nullptr, NewDRD);
3590e5dd7070Spatrick SemaRef.CurrentInstantiationScope->InstantiatedLocal(
3591e5dd7070Spatrick cast<DeclRefExpr>(D->getInitOrig())->getDecl(),
3592e5dd7070Spatrick cast<DeclRefExpr>(NewDRD->getInitOrig())->getDecl());
3593e5dd7070Spatrick SemaRef.CurrentInstantiationScope->InstantiatedLocal(
3594e5dd7070Spatrick cast<DeclRefExpr>(D->getInitPriv())->getDecl(),
3595e5dd7070Spatrick cast<DeclRefExpr>(NewDRD->getInitPriv())->getDecl());
3596e5dd7070Spatrick if (D->getInitializerKind() == OMPDeclareReductionDecl::CallInit) {
3597e5dd7070Spatrick SubstInitializer = SemaRef.SubstExpr(Init, TemplateArgs).get();
3598e5dd7070Spatrick } else {
3599e5dd7070Spatrick auto *OldPrivParm =
3600e5dd7070Spatrick cast<VarDecl>(cast<DeclRefExpr>(D->getInitPriv())->getDecl());
3601e5dd7070Spatrick IsCorrect = IsCorrect && OldPrivParm->hasInit();
3602e5dd7070Spatrick if (IsCorrect)
3603e5dd7070Spatrick SemaRef.InstantiateVariableInitializer(OmpPrivParm, OldPrivParm,
3604e5dd7070Spatrick TemplateArgs);
3605e5dd7070Spatrick }
3606e5dd7070Spatrick SemaRef.ActOnOpenMPDeclareReductionInitializerEnd(NewDRD, SubstInitializer,
3607e5dd7070Spatrick OmpPrivParm);
3608e5dd7070Spatrick }
3609e5dd7070Spatrick IsCorrect = IsCorrect && SubstCombiner &&
3610e5dd7070Spatrick (!Init ||
3611e5dd7070Spatrick (D->getInitializerKind() == OMPDeclareReductionDecl::CallInit &&
3612e5dd7070Spatrick SubstInitializer) ||
3613e5dd7070Spatrick (D->getInitializerKind() != OMPDeclareReductionDecl::CallInit &&
3614e5dd7070Spatrick !SubstInitializer));
3615e5dd7070Spatrick
3616e5dd7070Spatrick (void)SemaRef.ActOnOpenMPDeclareReductionDirectiveEnd(
3617e5dd7070Spatrick /*S=*/nullptr, DRD, IsCorrect && !D->isInvalidDecl());
3618e5dd7070Spatrick
3619e5dd7070Spatrick return NewDRD;
3620e5dd7070Spatrick }
3621e5dd7070Spatrick
3622e5dd7070Spatrick Decl *
VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl * D)3623e5dd7070Spatrick TemplateDeclInstantiator::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {
3624e5dd7070Spatrick // Instantiate type and check if it is allowed.
3625e5dd7070Spatrick const bool RequiresInstantiation =
3626e5dd7070Spatrick D->getType()->isDependentType() ||
3627e5dd7070Spatrick D->getType()->isInstantiationDependentType() ||
3628e5dd7070Spatrick D->getType()->containsUnexpandedParameterPack();
3629e5dd7070Spatrick QualType SubstMapperTy;
3630e5dd7070Spatrick DeclarationName VN = D->getVarName();
3631e5dd7070Spatrick if (RequiresInstantiation) {
3632e5dd7070Spatrick SubstMapperTy = SemaRef.ActOnOpenMPDeclareMapperType(
3633e5dd7070Spatrick D->getLocation(),
3634e5dd7070Spatrick ParsedType::make(SemaRef.SubstType(D->getType(), TemplateArgs,
3635e5dd7070Spatrick D->getLocation(), VN)));
3636e5dd7070Spatrick } else {
3637e5dd7070Spatrick SubstMapperTy = D->getType();
3638e5dd7070Spatrick }
3639e5dd7070Spatrick if (SubstMapperTy.isNull())
3640e5dd7070Spatrick return nullptr;
3641e5dd7070Spatrick // Create an instantiated copy of mapper.
3642e5dd7070Spatrick auto *PrevDeclInScope = D->getPrevDeclInScope();
3643e5dd7070Spatrick if (PrevDeclInScope && !PrevDeclInScope->isInvalidDecl()) {
3644e5dd7070Spatrick PrevDeclInScope = cast<OMPDeclareMapperDecl>(
3645e5dd7070Spatrick SemaRef.CurrentInstantiationScope->findInstantiationOf(PrevDeclInScope)
3646e5dd7070Spatrick ->get<Decl *>());
3647e5dd7070Spatrick }
3648e5dd7070Spatrick bool IsCorrect = true;
3649a9ac8606Spatrick SmallVector<OMPClause *, 6> Clauses;
3650e5dd7070Spatrick // Instantiate the mapper variable.
3651e5dd7070Spatrick DeclarationNameInfo DirName;
3652e5dd7070Spatrick SemaRef.StartOpenMPDSABlock(llvm::omp::OMPD_declare_mapper, DirName,
3653e5dd7070Spatrick /*S=*/nullptr,
3654e5dd7070Spatrick (*D->clauselist_begin())->getBeginLoc());
3655a9ac8606Spatrick ExprResult MapperVarRef = SemaRef.ActOnOpenMPDeclareMapperDirectiveVarDecl(
3656a9ac8606Spatrick /*S=*/nullptr, SubstMapperTy, D->getLocation(), VN);
3657e5dd7070Spatrick SemaRef.CurrentInstantiationScope->InstantiatedLocal(
3658e5dd7070Spatrick cast<DeclRefExpr>(D->getMapperVarRef())->getDecl(),
3659a9ac8606Spatrick cast<DeclRefExpr>(MapperVarRef.get())->getDecl());
3660e5dd7070Spatrick auto *ThisContext = dyn_cast_or_null<CXXRecordDecl>(Owner);
3661e5dd7070Spatrick Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, Qualifiers(),
3662e5dd7070Spatrick ThisContext);
3663e5dd7070Spatrick // Instantiate map clauses.
3664e5dd7070Spatrick for (OMPClause *C : D->clauselists()) {
3665e5dd7070Spatrick auto *OldC = cast<OMPMapClause>(C);
3666e5dd7070Spatrick SmallVector<Expr *, 4> NewVars;
3667e5dd7070Spatrick for (Expr *OE : OldC->varlists()) {
3668e5dd7070Spatrick Expr *NE = SemaRef.SubstExpr(OE, TemplateArgs).get();
3669e5dd7070Spatrick if (!NE) {
3670e5dd7070Spatrick IsCorrect = false;
3671e5dd7070Spatrick break;
3672e5dd7070Spatrick }
3673e5dd7070Spatrick NewVars.push_back(NE);
3674e5dd7070Spatrick }
3675e5dd7070Spatrick if (!IsCorrect)
3676e5dd7070Spatrick break;
3677e5dd7070Spatrick NestedNameSpecifierLoc NewQualifierLoc =
3678e5dd7070Spatrick SemaRef.SubstNestedNameSpecifierLoc(OldC->getMapperQualifierLoc(),
3679e5dd7070Spatrick TemplateArgs);
3680e5dd7070Spatrick CXXScopeSpec SS;
3681e5dd7070Spatrick SS.Adopt(NewQualifierLoc);
3682a9ac8606Spatrick DeclarationNameInfo NewNameInfo =
3683a9ac8606Spatrick SemaRef.SubstDeclarationNameInfo(OldC->getMapperIdInfo(), TemplateArgs);
3684e5dd7070Spatrick OMPVarListLocTy Locs(OldC->getBeginLoc(), OldC->getLParenLoc(),
3685e5dd7070Spatrick OldC->getEndLoc());
3686e5dd7070Spatrick OMPClause *NewC = SemaRef.ActOnOpenMPMapClause(
3687*12c85518Srobert OldC->getIteratorModifier(), OldC->getMapTypeModifiers(),
3688*12c85518Srobert OldC->getMapTypeModifiersLoc(), SS, NewNameInfo, OldC->getMapType(),
3689*12c85518Srobert OldC->isImplicitMapType(), OldC->getMapLoc(), OldC->getColonLoc(),
3690*12c85518Srobert NewVars, Locs);
3691e5dd7070Spatrick Clauses.push_back(NewC);
3692e5dd7070Spatrick }
3693e5dd7070Spatrick SemaRef.EndOpenMPDSABlock(nullptr);
3694e5dd7070Spatrick if (!IsCorrect)
3695e5dd7070Spatrick return nullptr;
3696a9ac8606Spatrick Sema::DeclGroupPtrTy DG = SemaRef.ActOnOpenMPDeclareMapperDirective(
3697a9ac8606Spatrick /*S=*/nullptr, Owner, D->getDeclName(), SubstMapperTy, D->getLocation(),
3698a9ac8606Spatrick VN, D->getAccess(), MapperVarRef.get(), Clauses, PrevDeclInScope);
3699a9ac8606Spatrick Decl *NewDMD = DG.get().getSingleDecl();
3700a9ac8606Spatrick SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, NewDMD);
3701e5dd7070Spatrick return NewDMD;
3702e5dd7070Spatrick }
3703e5dd7070Spatrick
VisitOMPCapturedExprDecl(OMPCapturedExprDecl *)3704e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitOMPCapturedExprDecl(
3705e5dd7070Spatrick OMPCapturedExprDecl * /*D*/) {
3706e5dd7070Spatrick llvm_unreachable("Should not be met in templates");
3707e5dd7070Spatrick }
3708e5dd7070Spatrick
VisitFunctionDecl(FunctionDecl * D)3709e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D) {
3710e5dd7070Spatrick return VisitFunctionDecl(D, nullptr);
3711e5dd7070Spatrick }
3712e5dd7070Spatrick
3713e5dd7070Spatrick Decl *
VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl * D)3714e5dd7070Spatrick TemplateDeclInstantiator::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {
3715e5dd7070Spatrick Decl *Inst = VisitFunctionDecl(D, nullptr);
3716e5dd7070Spatrick if (Inst && !D->getDescribedFunctionTemplate())
3717e5dd7070Spatrick Owner->addDecl(Inst);
3718e5dd7070Spatrick return Inst;
3719e5dd7070Spatrick }
3720e5dd7070Spatrick
VisitCXXMethodDecl(CXXMethodDecl * D)3721e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D) {
3722e5dd7070Spatrick return VisitCXXMethodDecl(D, nullptr);
3723e5dd7070Spatrick }
3724e5dd7070Spatrick
VisitRecordDecl(RecordDecl * D)3725e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitRecordDecl(RecordDecl *D) {
3726e5dd7070Spatrick llvm_unreachable("There are only CXXRecordDecls in C++");
3727e5dd7070Spatrick }
3728e5dd7070Spatrick
3729e5dd7070Spatrick Decl *
VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl * D)3730e5dd7070Spatrick TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl(
3731e5dd7070Spatrick ClassTemplateSpecializationDecl *D) {
3732e5dd7070Spatrick // As a MS extension, we permit class-scope explicit specialization
3733e5dd7070Spatrick // of member class templates.
3734e5dd7070Spatrick ClassTemplateDecl *ClassTemplate = D->getSpecializedTemplate();
3735e5dd7070Spatrick assert(ClassTemplate->getDeclContext()->isRecord() &&
3736e5dd7070Spatrick D->getTemplateSpecializationKind() == TSK_ExplicitSpecialization &&
3737e5dd7070Spatrick "can only instantiate an explicit specialization "
3738e5dd7070Spatrick "for a member class template");
3739e5dd7070Spatrick
3740e5dd7070Spatrick // Lookup the already-instantiated declaration in the instantiation
3741e5dd7070Spatrick // of the class template.
3742e5dd7070Spatrick ClassTemplateDecl *InstClassTemplate =
3743e5dd7070Spatrick cast_or_null<ClassTemplateDecl>(SemaRef.FindInstantiatedDecl(
3744e5dd7070Spatrick D->getLocation(), ClassTemplate, TemplateArgs));
3745e5dd7070Spatrick if (!InstClassTemplate)
3746e5dd7070Spatrick return nullptr;
3747e5dd7070Spatrick
3748e5dd7070Spatrick // Substitute into the template arguments of the class template explicit
3749e5dd7070Spatrick // specialization.
3750e5dd7070Spatrick TemplateSpecializationTypeLoc Loc = D->getTypeAsWritten()->getTypeLoc().
3751e5dd7070Spatrick castAs<TemplateSpecializationTypeLoc>();
3752e5dd7070Spatrick TemplateArgumentListInfo InstTemplateArgs(Loc.getLAngleLoc(),
3753e5dd7070Spatrick Loc.getRAngleLoc());
3754e5dd7070Spatrick SmallVector<TemplateArgumentLoc, 4> ArgLocs;
3755e5dd7070Spatrick for (unsigned I = 0; I != Loc.getNumArgs(); ++I)
3756e5dd7070Spatrick ArgLocs.push_back(Loc.getArgLoc(I));
3757*12c85518Srobert if (SemaRef.SubstTemplateArguments(ArgLocs, TemplateArgs, InstTemplateArgs))
3758e5dd7070Spatrick return nullptr;
3759e5dd7070Spatrick
3760e5dd7070Spatrick // Check that the template argument list is well-formed for this
3761e5dd7070Spatrick // class template.
3762*12c85518Srobert SmallVector<TemplateArgument, 4> SugaredConverted, CanonicalConverted;
3763*12c85518Srobert if (SemaRef.CheckTemplateArgumentList(InstClassTemplate, D->getLocation(),
3764*12c85518Srobert InstTemplateArgs, false,
3765*12c85518Srobert SugaredConverted, CanonicalConverted,
3766*12c85518Srobert /*UpdateArgsWithConversions=*/true))
3767e5dd7070Spatrick return nullptr;
3768e5dd7070Spatrick
3769e5dd7070Spatrick // Figure out where to insert this class template explicit specialization
3770e5dd7070Spatrick // in the member template's set of class template explicit specializations.
3771e5dd7070Spatrick void *InsertPos = nullptr;
3772e5dd7070Spatrick ClassTemplateSpecializationDecl *PrevDecl =
3773*12c85518Srobert InstClassTemplate->findSpecialization(CanonicalConverted, InsertPos);
3774e5dd7070Spatrick
3775e5dd7070Spatrick // Check whether we've already seen a conflicting instantiation of this
3776e5dd7070Spatrick // declaration (for instance, if there was a prior implicit instantiation).
3777e5dd7070Spatrick bool Ignored;
3778e5dd7070Spatrick if (PrevDecl &&
3779e5dd7070Spatrick SemaRef.CheckSpecializationInstantiationRedecl(D->getLocation(),
3780e5dd7070Spatrick D->getSpecializationKind(),
3781e5dd7070Spatrick PrevDecl,
3782e5dd7070Spatrick PrevDecl->getSpecializationKind(),
3783e5dd7070Spatrick PrevDecl->getPointOfInstantiation(),
3784e5dd7070Spatrick Ignored))
3785e5dd7070Spatrick return nullptr;
3786e5dd7070Spatrick
3787e5dd7070Spatrick // If PrevDecl was a definition and D is also a definition, diagnose.
3788e5dd7070Spatrick // This happens in cases like:
3789e5dd7070Spatrick //
3790e5dd7070Spatrick // template<typename T, typename U>
3791e5dd7070Spatrick // struct Outer {
3792e5dd7070Spatrick // template<typename X> struct Inner;
3793e5dd7070Spatrick // template<> struct Inner<T> {};
3794e5dd7070Spatrick // template<> struct Inner<U> {};
3795e5dd7070Spatrick // };
3796e5dd7070Spatrick //
3797e5dd7070Spatrick // Outer<int, int> outer; // error: the explicit specializations of Inner
3798e5dd7070Spatrick // // have the same signature.
3799e5dd7070Spatrick if (PrevDecl && PrevDecl->getDefinition() &&
3800e5dd7070Spatrick D->isThisDeclarationADefinition()) {
3801e5dd7070Spatrick SemaRef.Diag(D->getLocation(), diag::err_redefinition) << PrevDecl;
3802e5dd7070Spatrick SemaRef.Diag(PrevDecl->getDefinition()->getLocation(),
3803e5dd7070Spatrick diag::note_previous_definition);
3804e5dd7070Spatrick return nullptr;
3805e5dd7070Spatrick }
3806e5dd7070Spatrick
3807e5dd7070Spatrick // Create the class template partial specialization declaration.
3808e5dd7070Spatrick ClassTemplateSpecializationDecl *InstD =
3809e5dd7070Spatrick ClassTemplateSpecializationDecl::Create(
3810e5dd7070Spatrick SemaRef.Context, D->getTagKind(), Owner, D->getBeginLoc(),
3811*12c85518Srobert D->getLocation(), InstClassTemplate, CanonicalConverted, PrevDecl);
3812e5dd7070Spatrick
3813e5dd7070Spatrick // Add this partial specialization to the set of class template partial
3814e5dd7070Spatrick // specializations.
3815e5dd7070Spatrick if (!PrevDecl)
3816e5dd7070Spatrick InstClassTemplate->AddSpecialization(InstD, InsertPos);
3817e5dd7070Spatrick
3818e5dd7070Spatrick // Substitute the nested name specifier, if any.
3819e5dd7070Spatrick if (SubstQualifier(D, InstD))
3820e5dd7070Spatrick return nullptr;
3821e5dd7070Spatrick
3822e5dd7070Spatrick // Build the canonical type that describes the converted template
3823e5dd7070Spatrick // arguments of the class template explicit specialization.
3824e5dd7070Spatrick QualType CanonType = SemaRef.Context.getTemplateSpecializationType(
3825*12c85518Srobert TemplateName(InstClassTemplate), CanonicalConverted,
3826e5dd7070Spatrick SemaRef.Context.getRecordType(InstD));
3827e5dd7070Spatrick
3828e5dd7070Spatrick // Build the fully-sugared type for this class template
3829e5dd7070Spatrick // specialization as the user wrote in the specialization
3830e5dd7070Spatrick // itself. This means that we'll pretty-print the type retrieved
3831e5dd7070Spatrick // from the specialization's declaration the way that the user
3832e5dd7070Spatrick // actually wrote the specialization, rather than formatting the
3833e5dd7070Spatrick // name based on the "canonical" representation used to store the
3834e5dd7070Spatrick // template arguments in the specialization.
3835e5dd7070Spatrick TypeSourceInfo *WrittenTy = SemaRef.Context.getTemplateSpecializationTypeInfo(
3836e5dd7070Spatrick TemplateName(InstClassTemplate), D->getLocation(), InstTemplateArgs,
3837e5dd7070Spatrick CanonType);
3838e5dd7070Spatrick
3839e5dd7070Spatrick InstD->setAccess(D->getAccess());
3840e5dd7070Spatrick InstD->setInstantiationOfMemberClass(D, TSK_ImplicitInstantiation);
3841e5dd7070Spatrick InstD->setSpecializationKind(D->getSpecializationKind());
3842e5dd7070Spatrick InstD->setTypeAsWritten(WrittenTy);
3843e5dd7070Spatrick InstD->setExternLoc(D->getExternLoc());
3844e5dd7070Spatrick InstD->setTemplateKeywordLoc(D->getTemplateKeywordLoc());
3845e5dd7070Spatrick
3846e5dd7070Spatrick Owner->addDecl(InstD);
3847e5dd7070Spatrick
3848e5dd7070Spatrick // Instantiate the members of the class-scope explicit specialization eagerly.
3849e5dd7070Spatrick // We don't have support for lazy instantiation of an explicit specialization
3850e5dd7070Spatrick // yet, and MSVC eagerly instantiates in this case.
3851e5dd7070Spatrick // FIXME: This is wrong in standard C++.
3852e5dd7070Spatrick if (D->isThisDeclarationADefinition() &&
3853e5dd7070Spatrick SemaRef.InstantiateClass(D->getLocation(), InstD, D, TemplateArgs,
3854e5dd7070Spatrick TSK_ImplicitInstantiation,
3855e5dd7070Spatrick /*Complain=*/true))
3856e5dd7070Spatrick return nullptr;
3857e5dd7070Spatrick
3858e5dd7070Spatrick return InstD;
3859e5dd7070Spatrick }
3860e5dd7070Spatrick
VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl * D)3861e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl(
3862e5dd7070Spatrick VarTemplateSpecializationDecl *D) {
3863e5dd7070Spatrick
3864e5dd7070Spatrick TemplateArgumentListInfo VarTemplateArgsInfo;
3865e5dd7070Spatrick VarTemplateDecl *VarTemplate = D->getSpecializedTemplate();
3866e5dd7070Spatrick assert(VarTemplate &&
3867e5dd7070Spatrick "A template specialization without specialized template?");
3868e5dd7070Spatrick
3869e5dd7070Spatrick VarTemplateDecl *InstVarTemplate =
3870e5dd7070Spatrick cast_or_null<VarTemplateDecl>(SemaRef.FindInstantiatedDecl(
3871e5dd7070Spatrick D->getLocation(), VarTemplate, TemplateArgs));
3872e5dd7070Spatrick if (!InstVarTemplate)
3873e5dd7070Spatrick return nullptr;
3874e5dd7070Spatrick
3875e5dd7070Spatrick // Substitute the current template arguments.
3876*12c85518Srobert if (const ASTTemplateArgumentListInfo *TemplateArgsInfo =
3877*12c85518Srobert D->getTemplateArgsInfo()) {
3878*12c85518Srobert VarTemplateArgsInfo.setLAngleLoc(TemplateArgsInfo->getLAngleLoc());
3879*12c85518Srobert VarTemplateArgsInfo.setRAngleLoc(TemplateArgsInfo->getRAngleLoc());
3880e5dd7070Spatrick
3881*12c85518Srobert if (SemaRef.SubstTemplateArguments(TemplateArgsInfo->arguments(),
3882*12c85518Srobert TemplateArgs, VarTemplateArgsInfo))
3883e5dd7070Spatrick return nullptr;
3884*12c85518Srobert }
3885e5dd7070Spatrick
3886e5dd7070Spatrick // Check that the template argument list is well-formed for this template.
3887*12c85518Srobert SmallVector<TemplateArgument, 4> SugaredConverted, CanonicalConverted;
3888e5dd7070Spatrick if (SemaRef.CheckTemplateArgumentList(InstVarTemplate, D->getLocation(),
3889*12c85518Srobert VarTemplateArgsInfo, false,
3890*12c85518Srobert SugaredConverted, CanonicalConverted,
3891*12c85518Srobert /*UpdateArgsWithConversions=*/true))
3892e5dd7070Spatrick return nullptr;
3893e5dd7070Spatrick
3894e5dd7070Spatrick // Check whether we've already seen a declaration of this specialization.
3895e5dd7070Spatrick void *InsertPos = nullptr;
3896e5dd7070Spatrick VarTemplateSpecializationDecl *PrevDecl =
3897*12c85518Srobert InstVarTemplate->findSpecialization(CanonicalConverted, InsertPos);
3898e5dd7070Spatrick
3899e5dd7070Spatrick // Check whether we've already seen a conflicting instantiation of this
3900e5dd7070Spatrick // declaration (for instance, if there was a prior implicit instantiation).
3901e5dd7070Spatrick bool Ignored;
3902e5dd7070Spatrick if (PrevDecl && SemaRef.CheckSpecializationInstantiationRedecl(
3903e5dd7070Spatrick D->getLocation(), D->getSpecializationKind(), PrevDecl,
3904e5dd7070Spatrick PrevDecl->getSpecializationKind(),
3905e5dd7070Spatrick PrevDecl->getPointOfInstantiation(), Ignored))
3906e5dd7070Spatrick return nullptr;
3907e5dd7070Spatrick
3908e5dd7070Spatrick return VisitVarTemplateSpecializationDecl(
3909*12c85518Srobert InstVarTemplate, D, VarTemplateArgsInfo, CanonicalConverted, PrevDecl);
3910e5dd7070Spatrick }
3911e5dd7070Spatrick
VisitVarTemplateSpecializationDecl(VarTemplateDecl * VarTemplate,VarDecl * D,const TemplateArgumentListInfo & TemplateArgsInfo,ArrayRef<TemplateArgument> Converted,VarTemplateSpecializationDecl * PrevDecl)3912e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl(
3913a9ac8606Spatrick VarTemplateDecl *VarTemplate, VarDecl *D,
3914e5dd7070Spatrick const TemplateArgumentListInfo &TemplateArgsInfo,
3915e5dd7070Spatrick ArrayRef<TemplateArgument> Converted,
3916e5dd7070Spatrick VarTemplateSpecializationDecl *PrevDecl) {
3917e5dd7070Spatrick
3918e5dd7070Spatrick // Do substitution on the type of the declaration
3919e5dd7070Spatrick TypeSourceInfo *DI =
3920e5dd7070Spatrick SemaRef.SubstType(D->getTypeSourceInfo(), TemplateArgs,
3921e5dd7070Spatrick D->getTypeSpecStartLoc(), D->getDeclName());
3922e5dd7070Spatrick if (!DI)
3923e5dd7070Spatrick return nullptr;
3924e5dd7070Spatrick
3925e5dd7070Spatrick if (DI->getType()->isFunctionType()) {
3926e5dd7070Spatrick SemaRef.Diag(D->getLocation(), diag::err_variable_instantiates_to_function)
3927e5dd7070Spatrick << D->isStaticDataMember() << DI->getType();
3928e5dd7070Spatrick return nullptr;
3929e5dd7070Spatrick }
3930e5dd7070Spatrick
3931e5dd7070Spatrick // Build the instantiated declaration
3932e5dd7070Spatrick VarTemplateSpecializationDecl *Var = VarTemplateSpecializationDecl::Create(
3933e5dd7070Spatrick SemaRef.Context, Owner, D->getInnerLocStart(), D->getLocation(),
3934e5dd7070Spatrick VarTemplate, DI->getType(), DI, D->getStorageClass(), Converted);
3935e5dd7070Spatrick Var->setTemplateArgsInfo(TemplateArgsInfo);
3936ec727ea7Spatrick if (!PrevDecl) {
3937ec727ea7Spatrick void *InsertPos = nullptr;
3938ec727ea7Spatrick VarTemplate->findSpecialization(Converted, InsertPos);
3939e5dd7070Spatrick VarTemplate->AddSpecialization(Var, InsertPos);
3940ec727ea7Spatrick }
3941ec727ea7Spatrick
3942ec727ea7Spatrick if (SemaRef.getLangOpts().OpenCL)
3943ec727ea7Spatrick SemaRef.deduceOpenCLAddressSpace(Var);
3944e5dd7070Spatrick
3945e5dd7070Spatrick // Substitute the nested name specifier, if any.
3946e5dd7070Spatrick if (SubstQualifier(D, Var))
3947e5dd7070Spatrick return nullptr;
3948e5dd7070Spatrick
3949e5dd7070Spatrick SemaRef.BuildVariableInstantiation(Var, D, TemplateArgs, LateAttrs, Owner,
3950e5dd7070Spatrick StartingScope, false, PrevDecl);
3951e5dd7070Spatrick
3952e5dd7070Spatrick return Var;
3953e5dd7070Spatrick }
3954e5dd7070Spatrick
VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl * D)3955e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitObjCAtDefsFieldDecl(ObjCAtDefsFieldDecl *D) {
3956e5dd7070Spatrick llvm_unreachable("@defs is not supported in Objective-C++");
3957e5dd7070Spatrick }
3958e5dd7070Spatrick
VisitFriendTemplateDecl(FriendTemplateDecl * D)3959e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
3960e5dd7070Spatrick // FIXME: We need to be able to instantiate FriendTemplateDecls.
3961e5dd7070Spatrick unsigned DiagID = SemaRef.getDiagnostics().getCustomDiagID(
3962e5dd7070Spatrick DiagnosticsEngine::Error,
3963e5dd7070Spatrick "cannot instantiate %0 yet");
3964e5dd7070Spatrick SemaRef.Diag(D->getLocation(), DiagID)
3965e5dd7070Spatrick << D->getDeclKindName();
3966e5dd7070Spatrick
3967e5dd7070Spatrick return nullptr;
3968e5dd7070Spatrick }
3969e5dd7070Spatrick
VisitConceptDecl(ConceptDecl * D)3970e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitConceptDecl(ConceptDecl *D) {
3971e5dd7070Spatrick llvm_unreachable("Concept definitions cannot reside inside a template");
3972e5dd7070Spatrick }
3973e5dd7070Spatrick
VisitImplicitConceptSpecializationDecl(ImplicitConceptSpecializationDecl * D)3974*12c85518Srobert Decl *TemplateDeclInstantiator::VisitImplicitConceptSpecializationDecl(
3975*12c85518Srobert ImplicitConceptSpecializationDecl *D) {
3976*12c85518Srobert llvm_unreachable("Concept specializations cannot reside inside a template");
3977*12c85518Srobert }
3978*12c85518Srobert
3979e5dd7070Spatrick Decl *
VisitRequiresExprBodyDecl(RequiresExprBodyDecl * D)3980e5dd7070Spatrick TemplateDeclInstantiator::VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D) {
3981e5dd7070Spatrick return RequiresExprBodyDecl::Create(SemaRef.Context, D->getDeclContext(),
3982e5dd7070Spatrick D->getBeginLoc());
3983e5dd7070Spatrick }
3984e5dd7070Spatrick
VisitDecl(Decl * D)3985e5dd7070Spatrick Decl *TemplateDeclInstantiator::VisitDecl(Decl *D) {
3986e5dd7070Spatrick llvm_unreachable("Unexpected decl");
3987e5dd7070Spatrick }
3988e5dd7070Spatrick
SubstDecl(Decl * D,DeclContext * Owner,const MultiLevelTemplateArgumentList & TemplateArgs)3989e5dd7070Spatrick Decl *Sema::SubstDecl(Decl *D, DeclContext *Owner,
3990e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs) {
3991e5dd7070Spatrick TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs);
3992e5dd7070Spatrick if (D->isInvalidDecl())
3993e5dd7070Spatrick return nullptr;
3994e5dd7070Spatrick
3995e5dd7070Spatrick Decl *SubstD;
3996e5dd7070Spatrick runWithSufficientStackSpace(D->getLocation(), [&] {
3997e5dd7070Spatrick SubstD = Instantiator.Visit(D);
3998e5dd7070Spatrick });
3999e5dd7070Spatrick return SubstD;
4000e5dd7070Spatrick }
4001e5dd7070Spatrick
adjustForRewrite(RewriteKind RK,FunctionDecl * Orig,QualType & T,TypeSourceInfo * & TInfo,DeclarationNameInfo & NameInfo)4002e5dd7070Spatrick void TemplateDeclInstantiator::adjustForRewrite(RewriteKind RK,
4003e5dd7070Spatrick FunctionDecl *Orig, QualType &T,
4004e5dd7070Spatrick TypeSourceInfo *&TInfo,
4005e5dd7070Spatrick DeclarationNameInfo &NameInfo) {
4006e5dd7070Spatrick assert(RK == RewriteKind::RewriteSpaceshipAsEqualEqual);
4007e5dd7070Spatrick
4008e5dd7070Spatrick // C++2a [class.compare.default]p3:
4009e5dd7070Spatrick // the return type is replaced with bool
4010e5dd7070Spatrick auto *FPT = T->castAs<FunctionProtoType>();
4011e5dd7070Spatrick T = SemaRef.Context.getFunctionType(
4012e5dd7070Spatrick SemaRef.Context.BoolTy, FPT->getParamTypes(), FPT->getExtProtoInfo());
4013e5dd7070Spatrick
4014e5dd7070Spatrick // Update the return type in the source info too. The most straightforward
4015e5dd7070Spatrick // way is to create new TypeSourceInfo for the new type. Use the location of
4016e5dd7070Spatrick // the '= default' as the location of the new type.
4017e5dd7070Spatrick //
4018e5dd7070Spatrick // FIXME: Set the correct return type when we initially transform the type,
4019e5dd7070Spatrick // rather than delaying it to now.
4020e5dd7070Spatrick TypeSourceInfo *NewTInfo =
4021e5dd7070Spatrick SemaRef.Context.getTrivialTypeSourceInfo(T, Orig->getEndLoc());
4022e5dd7070Spatrick auto OldLoc = TInfo->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>();
4023e5dd7070Spatrick assert(OldLoc && "type of function is not a function type?");
4024e5dd7070Spatrick auto NewLoc = NewTInfo->getTypeLoc().castAs<FunctionProtoTypeLoc>();
4025e5dd7070Spatrick for (unsigned I = 0, N = OldLoc.getNumParams(); I != N; ++I)
4026e5dd7070Spatrick NewLoc.setParam(I, OldLoc.getParam(I));
4027e5dd7070Spatrick TInfo = NewTInfo;
4028e5dd7070Spatrick
4029e5dd7070Spatrick // and the declarator-id is replaced with operator==
4030e5dd7070Spatrick NameInfo.setName(
4031e5dd7070Spatrick SemaRef.Context.DeclarationNames.getCXXOperatorName(OO_EqualEqual));
4032e5dd7070Spatrick }
4033e5dd7070Spatrick
SubstSpaceshipAsEqualEqual(CXXRecordDecl * RD,FunctionDecl * Spaceship)4034e5dd7070Spatrick FunctionDecl *Sema::SubstSpaceshipAsEqualEqual(CXXRecordDecl *RD,
4035e5dd7070Spatrick FunctionDecl *Spaceship) {
4036e5dd7070Spatrick if (Spaceship->isInvalidDecl())
4037e5dd7070Spatrick return nullptr;
4038e5dd7070Spatrick
4039e5dd7070Spatrick // C++2a [class.compare.default]p3:
4040e5dd7070Spatrick // an == operator function is declared implicitly [...] with the same
4041e5dd7070Spatrick // access and function-definition and in the same class scope as the
4042e5dd7070Spatrick // three-way comparison operator function
4043e5dd7070Spatrick MultiLevelTemplateArgumentList NoTemplateArgs;
4044ec727ea7Spatrick NoTemplateArgs.setKind(TemplateSubstitutionKind::Rewrite);
4045ec727ea7Spatrick NoTemplateArgs.addOuterRetainedLevels(RD->getTemplateDepth());
4046e5dd7070Spatrick TemplateDeclInstantiator Instantiator(*this, RD, NoTemplateArgs);
4047e5dd7070Spatrick Decl *R;
4048e5dd7070Spatrick if (auto *MD = dyn_cast<CXXMethodDecl>(Spaceship)) {
4049e5dd7070Spatrick R = Instantiator.VisitCXXMethodDecl(
4050*12c85518Srobert MD, nullptr, std::nullopt,
4051e5dd7070Spatrick TemplateDeclInstantiator::RewriteKind::RewriteSpaceshipAsEqualEqual);
4052e5dd7070Spatrick } else {
4053e5dd7070Spatrick assert(Spaceship->getFriendObjectKind() &&
4054e5dd7070Spatrick "defaulted spaceship is neither a member nor a friend");
4055e5dd7070Spatrick
4056e5dd7070Spatrick R = Instantiator.VisitFunctionDecl(
4057e5dd7070Spatrick Spaceship, nullptr,
4058e5dd7070Spatrick TemplateDeclInstantiator::RewriteKind::RewriteSpaceshipAsEqualEqual);
4059e5dd7070Spatrick if (!R)
4060e5dd7070Spatrick return nullptr;
4061e5dd7070Spatrick
4062e5dd7070Spatrick FriendDecl *FD =
4063e5dd7070Spatrick FriendDecl::Create(Context, RD, Spaceship->getLocation(),
4064e5dd7070Spatrick cast<NamedDecl>(R), Spaceship->getBeginLoc());
4065e5dd7070Spatrick FD->setAccess(AS_public);
4066e5dd7070Spatrick RD->addDecl(FD);
4067e5dd7070Spatrick }
4068e5dd7070Spatrick return cast_or_null<FunctionDecl>(R);
4069e5dd7070Spatrick }
4070e5dd7070Spatrick
4071e5dd7070Spatrick /// Instantiates a nested template parameter list in the current
4072e5dd7070Spatrick /// instantiation context.
4073e5dd7070Spatrick ///
4074e5dd7070Spatrick /// \param L The parameter list to instantiate
4075e5dd7070Spatrick ///
4076e5dd7070Spatrick /// \returns NULL if there was an error
4077e5dd7070Spatrick TemplateParameterList *
SubstTemplateParams(TemplateParameterList * L)4078e5dd7070Spatrick TemplateDeclInstantiator::SubstTemplateParams(TemplateParameterList *L) {
4079e5dd7070Spatrick // Get errors for all the parameters before bailing out.
4080e5dd7070Spatrick bool Invalid = false;
4081e5dd7070Spatrick
4082e5dd7070Spatrick unsigned N = L->size();
4083e5dd7070Spatrick typedef SmallVector<NamedDecl *, 8> ParamVector;
4084e5dd7070Spatrick ParamVector Params;
4085e5dd7070Spatrick Params.reserve(N);
4086e5dd7070Spatrick for (auto &P : *L) {
4087e5dd7070Spatrick NamedDecl *D = cast_or_null<NamedDecl>(Visit(P));
4088e5dd7070Spatrick Params.push_back(D);
4089e5dd7070Spatrick Invalid = Invalid || !D || D->isInvalidDecl();
4090e5dd7070Spatrick }
4091e5dd7070Spatrick
4092e5dd7070Spatrick // Clean up if we had an error.
4093e5dd7070Spatrick if (Invalid)
4094e5dd7070Spatrick return nullptr;
4095e5dd7070Spatrick
4096*12c85518Srobert Expr *InstRequiresClause = L->getRequiresClause();
4097e5dd7070Spatrick
4098e5dd7070Spatrick TemplateParameterList *InstL
4099e5dd7070Spatrick = TemplateParameterList::Create(SemaRef.Context, L->getTemplateLoc(),
4100e5dd7070Spatrick L->getLAngleLoc(), Params,
4101e5dd7070Spatrick L->getRAngleLoc(), InstRequiresClause);
4102e5dd7070Spatrick return InstL;
4103e5dd7070Spatrick }
4104e5dd7070Spatrick
4105e5dd7070Spatrick TemplateParameterList *
SubstTemplateParams(TemplateParameterList * Params,DeclContext * Owner,const MultiLevelTemplateArgumentList & TemplateArgs,bool EvaluateConstraints)4106e5dd7070Spatrick Sema::SubstTemplateParams(TemplateParameterList *Params, DeclContext *Owner,
4107*12c85518Srobert const MultiLevelTemplateArgumentList &TemplateArgs,
4108*12c85518Srobert bool EvaluateConstraints) {
4109e5dd7070Spatrick TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs);
4110*12c85518Srobert Instantiator.setEvaluateConstraints(EvaluateConstraints);
4111e5dd7070Spatrick return Instantiator.SubstTemplateParams(Params);
4112e5dd7070Spatrick }
4113e5dd7070Spatrick
4114e5dd7070Spatrick /// Instantiate the declaration of a class template partial
4115e5dd7070Spatrick /// specialization.
4116e5dd7070Spatrick ///
4117e5dd7070Spatrick /// \param ClassTemplate the (instantiated) class template that is partially
4118e5dd7070Spatrick // specialized by the instantiation of \p PartialSpec.
4119e5dd7070Spatrick ///
4120e5dd7070Spatrick /// \param PartialSpec the (uninstantiated) class template partial
4121e5dd7070Spatrick /// specialization that we are instantiating.
4122e5dd7070Spatrick ///
4123e5dd7070Spatrick /// \returns The instantiated partial specialization, if successful; otherwise,
4124e5dd7070Spatrick /// NULL to indicate an error.
4125e5dd7070Spatrick ClassTemplatePartialSpecializationDecl *
InstantiateClassTemplatePartialSpecialization(ClassTemplateDecl * ClassTemplate,ClassTemplatePartialSpecializationDecl * PartialSpec)4126e5dd7070Spatrick TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
4127e5dd7070Spatrick ClassTemplateDecl *ClassTemplate,
4128e5dd7070Spatrick ClassTemplatePartialSpecializationDecl *PartialSpec) {
4129e5dd7070Spatrick // Create a local instantiation scope for this class template partial
4130e5dd7070Spatrick // specialization, which will contain the instantiations of the template
4131e5dd7070Spatrick // parameters.
4132e5dd7070Spatrick LocalInstantiationScope Scope(SemaRef);
4133e5dd7070Spatrick
4134e5dd7070Spatrick // Substitute into the template parameters of the class template partial
4135e5dd7070Spatrick // specialization.
4136e5dd7070Spatrick TemplateParameterList *TempParams = PartialSpec->getTemplateParameters();
4137e5dd7070Spatrick TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
4138e5dd7070Spatrick if (!InstParams)
4139e5dd7070Spatrick return nullptr;
4140e5dd7070Spatrick
4141e5dd7070Spatrick // Substitute into the template arguments of the class template partial
4142e5dd7070Spatrick // specialization.
4143e5dd7070Spatrick const ASTTemplateArgumentListInfo *TemplArgInfo
4144e5dd7070Spatrick = PartialSpec->getTemplateArgsAsWritten();
4145e5dd7070Spatrick TemplateArgumentListInfo InstTemplateArgs(TemplArgInfo->LAngleLoc,
4146e5dd7070Spatrick TemplArgInfo->RAngleLoc);
4147*12c85518Srobert if (SemaRef.SubstTemplateArguments(TemplArgInfo->arguments(), TemplateArgs,
4148*12c85518Srobert InstTemplateArgs))
4149e5dd7070Spatrick return nullptr;
4150e5dd7070Spatrick
4151e5dd7070Spatrick // Check that the template argument list is well-formed for this
4152e5dd7070Spatrick // class template.
4153*12c85518Srobert SmallVector<TemplateArgument, 4> SugaredConverted, CanonicalConverted;
4154*12c85518Srobert if (SemaRef.CheckTemplateArgumentList(
4155*12c85518Srobert ClassTemplate, PartialSpec->getLocation(), InstTemplateArgs,
4156*12c85518Srobert /*PartialTemplateArgs=*/false, SugaredConverted, CanonicalConverted))
4157e5dd7070Spatrick return nullptr;
4158e5dd7070Spatrick
4159e5dd7070Spatrick // Check these arguments are valid for a template partial specialization.
4160e5dd7070Spatrick if (SemaRef.CheckTemplatePartialSpecializationArgs(
4161e5dd7070Spatrick PartialSpec->getLocation(), ClassTemplate, InstTemplateArgs.size(),
4162*12c85518Srobert CanonicalConverted))
4163e5dd7070Spatrick return nullptr;
4164e5dd7070Spatrick
4165e5dd7070Spatrick // Figure out where to insert this class template partial specialization
4166e5dd7070Spatrick // in the member template's set of class template partial specializations.
4167e5dd7070Spatrick void *InsertPos = nullptr;
4168*12c85518Srobert ClassTemplateSpecializationDecl *PrevDecl =
4169*12c85518Srobert ClassTemplate->findPartialSpecialization(CanonicalConverted, InstParams,
4170e5dd7070Spatrick InsertPos);
4171e5dd7070Spatrick
4172e5dd7070Spatrick // Build the canonical type that describes the converted template
4173e5dd7070Spatrick // arguments of the class template partial specialization.
4174*12c85518Srobert QualType CanonType = SemaRef.Context.getTemplateSpecializationType(
4175*12c85518Srobert TemplateName(ClassTemplate), CanonicalConverted);
4176e5dd7070Spatrick
4177e5dd7070Spatrick // Build the fully-sugared type for this class template
4178e5dd7070Spatrick // specialization as the user wrote in the specialization
4179e5dd7070Spatrick // itself. This means that we'll pretty-print the type retrieved
4180e5dd7070Spatrick // from the specialization's declaration the way that the user
4181e5dd7070Spatrick // actually wrote the specialization, rather than formatting the
4182e5dd7070Spatrick // name based on the "canonical" representation used to store the
4183e5dd7070Spatrick // template arguments in the specialization.
4184e5dd7070Spatrick TypeSourceInfo *WrittenTy
4185e5dd7070Spatrick = SemaRef.Context.getTemplateSpecializationTypeInfo(
4186e5dd7070Spatrick TemplateName(ClassTemplate),
4187e5dd7070Spatrick PartialSpec->getLocation(),
4188e5dd7070Spatrick InstTemplateArgs,
4189e5dd7070Spatrick CanonType);
4190e5dd7070Spatrick
4191e5dd7070Spatrick if (PrevDecl) {
4192e5dd7070Spatrick // We've already seen a partial specialization with the same template
4193e5dd7070Spatrick // parameters and template arguments. This can happen, for example, when
4194e5dd7070Spatrick // substituting the outer template arguments ends up causing two
4195e5dd7070Spatrick // class template partial specializations of a member class template
4196e5dd7070Spatrick // to have identical forms, e.g.,
4197e5dd7070Spatrick //
4198e5dd7070Spatrick // template<typename T, typename U>
4199e5dd7070Spatrick // struct Outer {
4200e5dd7070Spatrick // template<typename X, typename Y> struct Inner;
4201e5dd7070Spatrick // template<typename Y> struct Inner<T, Y>;
4202e5dd7070Spatrick // template<typename Y> struct Inner<U, Y>;
4203e5dd7070Spatrick // };
4204e5dd7070Spatrick //
4205e5dd7070Spatrick // Outer<int, int> outer; // error: the partial specializations of Inner
4206e5dd7070Spatrick // // have the same signature.
4207e5dd7070Spatrick SemaRef.Diag(PartialSpec->getLocation(), diag::err_partial_spec_redeclared)
4208e5dd7070Spatrick << WrittenTy->getType();
4209e5dd7070Spatrick SemaRef.Diag(PrevDecl->getLocation(), diag::note_prev_partial_spec_here)
4210e5dd7070Spatrick << SemaRef.Context.getTypeDeclType(PrevDecl);
4211e5dd7070Spatrick return nullptr;
4212e5dd7070Spatrick }
4213e5dd7070Spatrick
4214e5dd7070Spatrick
4215e5dd7070Spatrick // Create the class template partial specialization declaration.
4216e5dd7070Spatrick ClassTemplatePartialSpecializationDecl *InstPartialSpec =
4217e5dd7070Spatrick ClassTemplatePartialSpecializationDecl::Create(
4218e5dd7070Spatrick SemaRef.Context, PartialSpec->getTagKind(), Owner,
4219e5dd7070Spatrick PartialSpec->getBeginLoc(), PartialSpec->getLocation(), InstParams,
4220*12c85518Srobert ClassTemplate, CanonicalConverted, InstTemplateArgs, CanonType,
4221*12c85518Srobert nullptr);
4222e5dd7070Spatrick // Substitute the nested name specifier, if any.
4223e5dd7070Spatrick if (SubstQualifier(PartialSpec, InstPartialSpec))
4224e5dd7070Spatrick return nullptr;
4225e5dd7070Spatrick
4226e5dd7070Spatrick InstPartialSpec->setInstantiatedFromMember(PartialSpec);
4227e5dd7070Spatrick InstPartialSpec->setTypeAsWritten(WrittenTy);
4228e5dd7070Spatrick
4229e5dd7070Spatrick // Check the completed partial specialization.
4230e5dd7070Spatrick SemaRef.CheckTemplatePartialSpecialization(InstPartialSpec);
4231e5dd7070Spatrick
4232e5dd7070Spatrick // Add this partial specialization to the set of class template partial
4233e5dd7070Spatrick // specializations.
4234e5dd7070Spatrick ClassTemplate->AddPartialSpecialization(InstPartialSpec,
4235e5dd7070Spatrick /*InsertPos=*/nullptr);
4236e5dd7070Spatrick return InstPartialSpec;
4237e5dd7070Spatrick }
4238e5dd7070Spatrick
4239e5dd7070Spatrick /// Instantiate the declaration of a variable template partial
4240e5dd7070Spatrick /// specialization.
4241e5dd7070Spatrick ///
4242e5dd7070Spatrick /// \param VarTemplate the (instantiated) variable template that is partially
4243e5dd7070Spatrick /// specialized by the instantiation of \p PartialSpec.
4244e5dd7070Spatrick ///
4245e5dd7070Spatrick /// \param PartialSpec the (uninstantiated) variable template partial
4246e5dd7070Spatrick /// specialization that we are instantiating.
4247e5dd7070Spatrick ///
4248e5dd7070Spatrick /// \returns The instantiated partial specialization, if successful; otherwise,
4249e5dd7070Spatrick /// NULL to indicate an error.
4250e5dd7070Spatrick VarTemplatePartialSpecializationDecl *
InstantiateVarTemplatePartialSpecialization(VarTemplateDecl * VarTemplate,VarTemplatePartialSpecializationDecl * PartialSpec)4251e5dd7070Spatrick TemplateDeclInstantiator::InstantiateVarTemplatePartialSpecialization(
4252e5dd7070Spatrick VarTemplateDecl *VarTemplate,
4253e5dd7070Spatrick VarTemplatePartialSpecializationDecl *PartialSpec) {
4254e5dd7070Spatrick // Create a local instantiation scope for this variable template partial
4255e5dd7070Spatrick // specialization, which will contain the instantiations of the template
4256e5dd7070Spatrick // parameters.
4257e5dd7070Spatrick LocalInstantiationScope Scope(SemaRef);
4258e5dd7070Spatrick
4259e5dd7070Spatrick // Substitute into the template parameters of the variable template partial
4260e5dd7070Spatrick // specialization.
4261e5dd7070Spatrick TemplateParameterList *TempParams = PartialSpec->getTemplateParameters();
4262e5dd7070Spatrick TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
4263e5dd7070Spatrick if (!InstParams)
4264e5dd7070Spatrick return nullptr;
4265e5dd7070Spatrick
4266e5dd7070Spatrick // Substitute into the template arguments of the variable template partial
4267e5dd7070Spatrick // specialization.
4268e5dd7070Spatrick const ASTTemplateArgumentListInfo *TemplArgInfo
4269e5dd7070Spatrick = PartialSpec->getTemplateArgsAsWritten();
4270e5dd7070Spatrick TemplateArgumentListInfo InstTemplateArgs(TemplArgInfo->LAngleLoc,
4271e5dd7070Spatrick TemplArgInfo->RAngleLoc);
4272*12c85518Srobert if (SemaRef.SubstTemplateArguments(TemplArgInfo->arguments(), TemplateArgs,
4273*12c85518Srobert InstTemplateArgs))
4274e5dd7070Spatrick return nullptr;
4275e5dd7070Spatrick
4276e5dd7070Spatrick // Check that the template argument list is well-formed for this
4277e5dd7070Spatrick // class template.
4278*12c85518Srobert SmallVector<TemplateArgument, 4> SugaredConverted, CanonicalConverted;
4279*12c85518Srobert if (SemaRef.CheckTemplateArgumentList(
4280*12c85518Srobert VarTemplate, PartialSpec->getLocation(), InstTemplateArgs,
4281*12c85518Srobert /*PartialTemplateArgs=*/false, SugaredConverted, CanonicalConverted))
4282e5dd7070Spatrick return nullptr;
4283e5dd7070Spatrick
4284e5dd7070Spatrick // Check these arguments are valid for a template partial specialization.
4285e5dd7070Spatrick if (SemaRef.CheckTemplatePartialSpecializationArgs(
4286e5dd7070Spatrick PartialSpec->getLocation(), VarTemplate, InstTemplateArgs.size(),
4287*12c85518Srobert CanonicalConverted))
4288e5dd7070Spatrick return nullptr;
4289e5dd7070Spatrick
4290e5dd7070Spatrick // Figure out where to insert this variable template partial specialization
4291e5dd7070Spatrick // in the member template's set of variable template partial specializations.
4292e5dd7070Spatrick void *InsertPos = nullptr;
4293e5dd7070Spatrick VarTemplateSpecializationDecl *PrevDecl =
4294*12c85518Srobert VarTemplate->findPartialSpecialization(CanonicalConverted, InstParams,
4295*12c85518Srobert InsertPos);
4296e5dd7070Spatrick
4297e5dd7070Spatrick // Build the canonical type that describes the converted template
4298e5dd7070Spatrick // arguments of the variable template partial specialization.
4299e5dd7070Spatrick QualType CanonType = SemaRef.Context.getTemplateSpecializationType(
4300*12c85518Srobert TemplateName(VarTemplate), CanonicalConverted);
4301e5dd7070Spatrick
4302e5dd7070Spatrick // Build the fully-sugared type for this variable template
4303e5dd7070Spatrick // specialization as the user wrote in the specialization
4304e5dd7070Spatrick // itself. This means that we'll pretty-print the type retrieved
4305e5dd7070Spatrick // from the specialization's declaration the way that the user
4306e5dd7070Spatrick // actually wrote the specialization, rather than formatting the
4307e5dd7070Spatrick // name based on the "canonical" representation used to store the
4308e5dd7070Spatrick // template arguments in the specialization.
4309e5dd7070Spatrick TypeSourceInfo *WrittenTy = SemaRef.Context.getTemplateSpecializationTypeInfo(
4310e5dd7070Spatrick TemplateName(VarTemplate), PartialSpec->getLocation(), InstTemplateArgs,
4311e5dd7070Spatrick CanonType);
4312e5dd7070Spatrick
4313e5dd7070Spatrick if (PrevDecl) {
4314e5dd7070Spatrick // We've already seen a partial specialization with the same template
4315e5dd7070Spatrick // parameters and template arguments. This can happen, for example, when
4316e5dd7070Spatrick // substituting the outer template arguments ends up causing two
4317e5dd7070Spatrick // variable template partial specializations of a member variable template
4318e5dd7070Spatrick // to have identical forms, e.g.,
4319e5dd7070Spatrick //
4320e5dd7070Spatrick // template<typename T, typename U>
4321e5dd7070Spatrick // struct Outer {
4322e5dd7070Spatrick // template<typename X, typename Y> pair<X,Y> p;
4323e5dd7070Spatrick // template<typename Y> pair<T, Y> p;
4324e5dd7070Spatrick // template<typename Y> pair<U, Y> p;
4325e5dd7070Spatrick // };
4326e5dd7070Spatrick //
4327e5dd7070Spatrick // Outer<int, int> outer; // error: the partial specializations of Inner
4328e5dd7070Spatrick // // have the same signature.
4329e5dd7070Spatrick SemaRef.Diag(PartialSpec->getLocation(),
4330e5dd7070Spatrick diag::err_var_partial_spec_redeclared)
4331e5dd7070Spatrick << WrittenTy->getType();
4332e5dd7070Spatrick SemaRef.Diag(PrevDecl->getLocation(),
4333e5dd7070Spatrick diag::note_var_prev_partial_spec_here);
4334e5dd7070Spatrick return nullptr;
4335e5dd7070Spatrick }
4336e5dd7070Spatrick
4337e5dd7070Spatrick // Do substitution on the type of the declaration
4338e5dd7070Spatrick TypeSourceInfo *DI = SemaRef.SubstType(
4339e5dd7070Spatrick PartialSpec->getTypeSourceInfo(), TemplateArgs,
4340e5dd7070Spatrick PartialSpec->getTypeSpecStartLoc(), PartialSpec->getDeclName());
4341e5dd7070Spatrick if (!DI)
4342e5dd7070Spatrick return nullptr;
4343e5dd7070Spatrick
4344e5dd7070Spatrick if (DI->getType()->isFunctionType()) {
4345e5dd7070Spatrick SemaRef.Diag(PartialSpec->getLocation(),
4346e5dd7070Spatrick diag::err_variable_instantiates_to_function)
4347e5dd7070Spatrick << PartialSpec->isStaticDataMember() << DI->getType();
4348e5dd7070Spatrick return nullptr;
4349e5dd7070Spatrick }
4350e5dd7070Spatrick
4351e5dd7070Spatrick // Create the variable template partial specialization declaration.
4352e5dd7070Spatrick VarTemplatePartialSpecializationDecl *InstPartialSpec =
4353e5dd7070Spatrick VarTemplatePartialSpecializationDecl::Create(
4354e5dd7070Spatrick SemaRef.Context, Owner, PartialSpec->getInnerLocStart(),
4355e5dd7070Spatrick PartialSpec->getLocation(), InstParams, VarTemplate, DI->getType(),
4356*12c85518Srobert DI, PartialSpec->getStorageClass(), CanonicalConverted,
4357*12c85518Srobert InstTemplateArgs);
4358e5dd7070Spatrick
4359e5dd7070Spatrick // Substitute the nested name specifier, if any.
4360e5dd7070Spatrick if (SubstQualifier(PartialSpec, InstPartialSpec))
4361e5dd7070Spatrick return nullptr;
4362e5dd7070Spatrick
4363e5dd7070Spatrick InstPartialSpec->setInstantiatedFromMember(PartialSpec);
4364e5dd7070Spatrick InstPartialSpec->setTypeAsWritten(WrittenTy);
4365e5dd7070Spatrick
4366e5dd7070Spatrick // Check the completed partial specialization.
4367e5dd7070Spatrick SemaRef.CheckTemplatePartialSpecialization(InstPartialSpec);
4368e5dd7070Spatrick
4369e5dd7070Spatrick // Add this partial specialization to the set of variable template partial
4370e5dd7070Spatrick // specializations. The instantiation of the initializer is not necessary.
4371e5dd7070Spatrick VarTemplate->AddPartialSpecialization(InstPartialSpec, /*InsertPos=*/nullptr);
4372e5dd7070Spatrick
4373e5dd7070Spatrick SemaRef.BuildVariableInstantiation(InstPartialSpec, PartialSpec, TemplateArgs,
4374e5dd7070Spatrick LateAttrs, Owner, StartingScope);
4375e5dd7070Spatrick
4376e5dd7070Spatrick return InstPartialSpec;
4377e5dd7070Spatrick }
4378e5dd7070Spatrick
4379e5dd7070Spatrick TypeSourceInfo*
SubstFunctionType(FunctionDecl * D,SmallVectorImpl<ParmVarDecl * > & Params)4380e5dd7070Spatrick TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D,
4381e5dd7070Spatrick SmallVectorImpl<ParmVarDecl *> &Params) {
4382e5dd7070Spatrick TypeSourceInfo *OldTInfo = D->getTypeSourceInfo();
4383e5dd7070Spatrick assert(OldTInfo && "substituting function without type source info");
4384e5dd7070Spatrick assert(Params.empty() && "parameter vector is non-empty at start");
4385e5dd7070Spatrick
4386e5dd7070Spatrick CXXRecordDecl *ThisContext = nullptr;
4387e5dd7070Spatrick Qualifiers ThisTypeQuals;
4388e5dd7070Spatrick if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
4389e5dd7070Spatrick ThisContext = cast<CXXRecordDecl>(Owner);
4390e5dd7070Spatrick ThisTypeQuals = Method->getMethodQualifiers();
4391e5dd7070Spatrick }
4392e5dd7070Spatrick
4393*12c85518Srobert TypeSourceInfo *NewTInfo = SemaRef.SubstFunctionDeclType(
4394*12c85518Srobert OldTInfo, TemplateArgs, D->getTypeSpecStartLoc(), D->getDeclName(),
4395*12c85518Srobert ThisContext, ThisTypeQuals, EvaluateConstraints);
4396e5dd7070Spatrick if (!NewTInfo)
4397e5dd7070Spatrick return nullptr;
4398e5dd7070Spatrick
4399e5dd7070Spatrick TypeLoc OldTL = OldTInfo->getTypeLoc().IgnoreParens();
4400e5dd7070Spatrick if (FunctionProtoTypeLoc OldProtoLoc = OldTL.getAs<FunctionProtoTypeLoc>()) {
4401e5dd7070Spatrick if (NewTInfo != OldTInfo) {
4402e5dd7070Spatrick // Get parameters from the new type info.
4403e5dd7070Spatrick TypeLoc NewTL = NewTInfo->getTypeLoc().IgnoreParens();
4404e5dd7070Spatrick FunctionProtoTypeLoc NewProtoLoc = NewTL.castAs<FunctionProtoTypeLoc>();
4405e5dd7070Spatrick unsigned NewIdx = 0;
4406e5dd7070Spatrick for (unsigned OldIdx = 0, NumOldParams = OldProtoLoc.getNumParams();
4407e5dd7070Spatrick OldIdx != NumOldParams; ++OldIdx) {
4408e5dd7070Spatrick ParmVarDecl *OldParam = OldProtoLoc.getParam(OldIdx);
4409a9ac8606Spatrick if (!OldParam)
4410a9ac8606Spatrick return nullptr;
4411a9ac8606Spatrick
4412e5dd7070Spatrick LocalInstantiationScope *Scope = SemaRef.CurrentInstantiationScope;
4413e5dd7070Spatrick
4414*12c85518Srobert std::optional<unsigned> NumArgumentsInExpansion;
4415e5dd7070Spatrick if (OldParam->isParameterPack())
4416e5dd7070Spatrick NumArgumentsInExpansion =
4417e5dd7070Spatrick SemaRef.getNumArgumentsInExpansion(OldParam->getType(),
4418e5dd7070Spatrick TemplateArgs);
4419e5dd7070Spatrick if (!NumArgumentsInExpansion) {
4420e5dd7070Spatrick // Simple case: normal parameter, or a parameter pack that's
4421e5dd7070Spatrick // instantiated to a (still-dependent) parameter pack.
4422e5dd7070Spatrick ParmVarDecl *NewParam = NewProtoLoc.getParam(NewIdx++);
4423e5dd7070Spatrick Params.push_back(NewParam);
4424e5dd7070Spatrick Scope->InstantiatedLocal(OldParam, NewParam);
4425e5dd7070Spatrick } else {
4426e5dd7070Spatrick // Parameter pack expansion: make the instantiation an argument pack.
4427e5dd7070Spatrick Scope->MakeInstantiatedLocalArgPack(OldParam);
4428e5dd7070Spatrick for (unsigned I = 0; I != *NumArgumentsInExpansion; ++I) {
4429e5dd7070Spatrick ParmVarDecl *NewParam = NewProtoLoc.getParam(NewIdx++);
4430e5dd7070Spatrick Params.push_back(NewParam);
4431e5dd7070Spatrick Scope->InstantiatedLocalPackArg(OldParam, NewParam);
4432e5dd7070Spatrick }
4433e5dd7070Spatrick }
4434e5dd7070Spatrick }
4435e5dd7070Spatrick } else {
4436e5dd7070Spatrick // The function type itself was not dependent and therefore no
4437e5dd7070Spatrick // substitution occurred. However, we still need to instantiate
4438e5dd7070Spatrick // the function parameters themselves.
4439e5dd7070Spatrick const FunctionProtoType *OldProto =
4440e5dd7070Spatrick cast<FunctionProtoType>(OldProtoLoc.getType());
4441e5dd7070Spatrick for (unsigned i = 0, i_end = OldProtoLoc.getNumParams(); i != i_end;
4442e5dd7070Spatrick ++i) {
4443e5dd7070Spatrick ParmVarDecl *OldParam = OldProtoLoc.getParam(i);
4444e5dd7070Spatrick if (!OldParam) {
4445e5dd7070Spatrick Params.push_back(SemaRef.BuildParmVarDeclForTypedef(
4446e5dd7070Spatrick D, D->getLocation(), OldProto->getParamType(i)));
4447e5dd7070Spatrick continue;
4448e5dd7070Spatrick }
4449e5dd7070Spatrick
4450e5dd7070Spatrick ParmVarDecl *Parm =
4451e5dd7070Spatrick cast_or_null<ParmVarDecl>(VisitParmVarDecl(OldParam));
4452e5dd7070Spatrick if (!Parm)
4453e5dd7070Spatrick return nullptr;
4454e5dd7070Spatrick Params.push_back(Parm);
4455e5dd7070Spatrick }
4456e5dd7070Spatrick }
4457e5dd7070Spatrick } else {
4458e5dd7070Spatrick // If the type of this function, after ignoring parentheses, is not
4459e5dd7070Spatrick // *directly* a function type, then we're instantiating a function that
4460e5dd7070Spatrick // was declared via a typedef or with attributes, e.g.,
4461e5dd7070Spatrick //
4462e5dd7070Spatrick // typedef int functype(int, int);
4463e5dd7070Spatrick // functype func;
4464e5dd7070Spatrick // int __cdecl meth(int, int);
4465e5dd7070Spatrick //
4466e5dd7070Spatrick // In this case, we'll just go instantiate the ParmVarDecls that we
4467e5dd7070Spatrick // synthesized in the method declaration.
4468e5dd7070Spatrick SmallVector<QualType, 4> ParamTypes;
4469e5dd7070Spatrick Sema::ExtParameterInfoBuilder ExtParamInfos;
4470e5dd7070Spatrick if (SemaRef.SubstParmTypes(D->getLocation(), D->parameters(), nullptr,
4471e5dd7070Spatrick TemplateArgs, ParamTypes, &Params,
4472e5dd7070Spatrick ExtParamInfos))
4473e5dd7070Spatrick return nullptr;
4474e5dd7070Spatrick }
4475e5dd7070Spatrick
4476e5dd7070Spatrick return NewTInfo;
4477e5dd7070Spatrick }
4478e5dd7070Spatrick
4479e5dd7070Spatrick /// Introduce the instantiated function parameters into the local
4480e5dd7070Spatrick /// instantiation scope, and set the parameter names to those used
4481e5dd7070Spatrick /// in the template.
addInstantiatedParametersToScope(FunctionDecl * Function,const FunctionDecl * PatternDecl,LocalInstantiationScope & Scope,const MultiLevelTemplateArgumentList & TemplateArgs)4482*12c85518Srobert bool Sema::addInstantiatedParametersToScope(
4483*12c85518Srobert FunctionDecl *Function, const FunctionDecl *PatternDecl,
4484e5dd7070Spatrick LocalInstantiationScope &Scope,
4485e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs) {
4486e5dd7070Spatrick unsigned FParamIdx = 0;
4487e5dd7070Spatrick for (unsigned I = 0, N = PatternDecl->getNumParams(); I != N; ++I) {
4488e5dd7070Spatrick const ParmVarDecl *PatternParam = PatternDecl->getParamDecl(I);
4489e5dd7070Spatrick if (!PatternParam->isParameterPack()) {
4490e5dd7070Spatrick // Simple case: not a parameter pack.
4491e5dd7070Spatrick assert(FParamIdx < Function->getNumParams());
4492e5dd7070Spatrick ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx);
4493e5dd7070Spatrick FunctionParam->setDeclName(PatternParam->getDeclName());
4494e5dd7070Spatrick // If the parameter's type is not dependent, update it to match the type
4495e5dd7070Spatrick // in the pattern. They can differ in top-level cv-qualifiers, and we want
4496e5dd7070Spatrick // the pattern's type here. If the type is dependent, they can't differ,
4497e5dd7070Spatrick // per core issue 1668. Substitute into the type from the pattern, in case
4498e5dd7070Spatrick // it's instantiation-dependent.
4499e5dd7070Spatrick // FIXME: Updating the type to work around this is at best fragile.
4500e5dd7070Spatrick if (!PatternDecl->getType()->isDependentType()) {
4501*12c85518Srobert QualType T = SubstType(PatternParam->getType(), TemplateArgs,
4502e5dd7070Spatrick FunctionParam->getLocation(),
4503e5dd7070Spatrick FunctionParam->getDeclName());
4504e5dd7070Spatrick if (T.isNull())
4505e5dd7070Spatrick return true;
4506e5dd7070Spatrick FunctionParam->setType(T);
4507e5dd7070Spatrick }
4508e5dd7070Spatrick
4509e5dd7070Spatrick Scope.InstantiatedLocal(PatternParam, FunctionParam);
4510e5dd7070Spatrick ++FParamIdx;
4511e5dd7070Spatrick continue;
4512e5dd7070Spatrick }
4513e5dd7070Spatrick
4514e5dd7070Spatrick // Expand the parameter pack.
4515e5dd7070Spatrick Scope.MakeInstantiatedLocalArgPack(PatternParam);
4516*12c85518Srobert std::optional<unsigned> NumArgumentsInExpansion =
4517*12c85518Srobert getNumArgumentsInExpansion(PatternParam->getType(), TemplateArgs);
4518e5dd7070Spatrick if (NumArgumentsInExpansion) {
4519e5dd7070Spatrick QualType PatternType =
4520e5dd7070Spatrick PatternParam->getType()->castAs<PackExpansionType>()->getPattern();
4521e5dd7070Spatrick for (unsigned Arg = 0; Arg < *NumArgumentsInExpansion; ++Arg) {
4522e5dd7070Spatrick ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx);
4523e5dd7070Spatrick FunctionParam->setDeclName(PatternParam->getDeclName());
4524e5dd7070Spatrick if (!PatternDecl->getType()->isDependentType()) {
4525*12c85518Srobert Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, Arg);
4526*12c85518Srobert QualType T =
4527*12c85518Srobert SubstType(PatternType, TemplateArgs, FunctionParam->getLocation(),
4528e5dd7070Spatrick FunctionParam->getDeclName());
4529e5dd7070Spatrick if (T.isNull())
4530e5dd7070Spatrick return true;
4531e5dd7070Spatrick FunctionParam->setType(T);
4532e5dd7070Spatrick }
4533e5dd7070Spatrick
4534e5dd7070Spatrick Scope.InstantiatedLocalPackArg(PatternParam, FunctionParam);
4535e5dd7070Spatrick ++FParamIdx;
4536e5dd7070Spatrick }
4537e5dd7070Spatrick }
4538e5dd7070Spatrick }
4539e5dd7070Spatrick
4540e5dd7070Spatrick return false;
4541e5dd7070Spatrick }
4542e5dd7070Spatrick
InstantiateDefaultArgument(SourceLocation CallLoc,FunctionDecl * FD,ParmVarDecl * Param)4543ec727ea7Spatrick bool Sema::InstantiateDefaultArgument(SourceLocation CallLoc, FunctionDecl *FD,
4544ec727ea7Spatrick ParmVarDecl *Param) {
4545ec727ea7Spatrick assert(Param->hasUninstantiatedDefaultArg());
4546ec727ea7Spatrick
4547ec727ea7Spatrick // Instantiate the expression.
4548ec727ea7Spatrick //
4549ec727ea7Spatrick // FIXME: Pass in a correct Pattern argument, otherwise
4550ec727ea7Spatrick // getTemplateInstantiationArgs uses the lexical context of FD, e.g.
4551ec727ea7Spatrick //
4552ec727ea7Spatrick // template<typename T>
4553ec727ea7Spatrick // struct A {
4554ec727ea7Spatrick // static int FooImpl();
4555ec727ea7Spatrick //
4556ec727ea7Spatrick // template<typename Tp>
4557ec727ea7Spatrick // // bug: default argument A<T>::FooImpl() is evaluated with 2-level
4558ec727ea7Spatrick // // template argument list [[T], [Tp]], should be [[Tp]].
4559ec727ea7Spatrick // friend A<Tp> Foo(int a);
4560ec727ea7Spatrick // };
4561ec727ea7Spatrick //
4562ec727ea7Spatrick // template<typename T>
4563ec727ea7Spatrick // A<T> Foo(int a = A<T>::FooImpl());
4564*12c85518Srobert MultiLevelTemplateArgumentList TemplateArgs = getTemplateInstantiationArgs(
4565*12c85518Srobert FD, /*Final=*/false, nullptr, /*RelativeToPrimary=*/true);
4566ec727ea7Spatrick
4567*12c85518Srobert if (SubstDefaultArgument(CallLoc, Param, TemplateArgs, /*ForCallExpr*/ true))
4568ec727ea7Spatrick return true;
4569ec727ea7Spatrick
4570ec727ea7Spatrick if (ASTMutationListener *L = getASTMutationListener())
4571ec727ea7Spatrick L->DefaultArgumentInstantiated(Param);
4572ec727ea7Spatrick
4573ec727ea7Spatrick return false;
4574ec727ea7Spatrick }
4575ec727ea7Spatrick
InstantiateExceptionSpec(SourceLocation PointOfInstantiation,FunctionDecl * Decl)4576e5dd7070Spatrick void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation,
4577e5dd7070Spatrick FunctionDecl *Decl) {
4578e5dd7070Spatrick const FunctionProtoType *Proto = Decl->getType()->castAs<FunctionProtoType>();
4579e5dd7070Spatrick if (Proto->getExceptionSpecType() != EST_Uninstantiated)
4580e5dd7070Spatrick return;
4581e5dd7070Spatrick
4582e5dd7070Spatrick InstantiatingTemplate Inst(*this, PointOfInstantiation, Decl,
4583e5dd7070Spatrick InstantiatingTemplate::ExceptionSpecification());
4584e5dd7070Spatrick if (Inst.isInvalid()) {
4585e5dd7070Spatrick // We hit the instantiation depth limit. Clear the exception specification
4586e5dd7070Spatrick // so that our callers don't have to cope with EST_Uninstantiated.
4587e5dd7070Spatrick UpdateExceptionSpec(Decl, EST_None);
4588e5dd7070Spatrick return;
4589e5dd7070Spatrick }
4590e5dd7070Spatrick if (Inst.isAlreadyInstantiating()) {
4591e5dd7070Spatrick // This exception specification indirectly depends on itself. Reject.
4592e5dd7070Spatrick // FIXME: Corresponding rule in the standard?
4593e5dd7070Spatrick Diag(PointOfInstantiation, diag::err_exception_spec_cycle) << Decl;
4594e5dd7070Spatrick UpdateExceptionSpec(Decl, EST_None);
4595e5dd7070Spatrick return;
4596e5dd7070Spatrick }
4597e5dd7070Spatrick
4598e5dd7070Spatrick // Enter the scope of this instantiation. We don't use
4599e5dd7070Spatrick // PushDeclContext because we don't have a scope.
4600e5dd7070Spatrick Sema::ContextRAII savedContext(*this, Decl);
4601e5dd7070Spatrick LocalInstantiationScope Scope(*this);
4602e5dd7070Spatrick
4603*12c85518Srobert MultiLevelTemplateArgumentList TemplateArgs = getTemplateInstantiationArgs(
4604*12c85518Srobert Decl, /*Final=*/false, nullptr, /*RelativeToPrimary*/ true);
4605e5dd7070Spatrick
4606ec727ea7Spatrick // FIXME: We can't use getTemplateInstantiationPattern(false) in general
4607ec727ea7Spatrick // here, because for a non-defining friend declaration in a class template,
4608ec727ea7Spatrick // we don't store enough information to map back to the friend declaration in
4609ec727ea7Spatrick // the template.
4610e5dd7070Spatrick FunctionDecl *Template = Proto->getExceptionSpecTemplate();
4611*12c85518Srobert if (addInstantiatedParametersToScope(Decl, Template, Scope, TemplateArgs)) {
4612e5dd7070Spatrick UpdateExceptionSpec(Decl, EST_None);
4613e5dd7070Spatrick return;
4614e5dd7070Spatrick }
4615e5dd7070Spatrick
4616e5dd7070Spatrick SubstExceptionSpec(Decl, Template->getType()->castAs<FunctionProtoType>(),
4617e5dd7070Spatrick TemplateArgs);
4618e5dd7070Spatrick }
4619e5dd7070Spatrick
4620e5dd7070Spatrick /// Initializes the common fields of an instantiation function
4621e5dd7070Spatrick /// declaration (New) from the corresponding fields of its template (Tmpl).
4622e5dd7070Spatrick ///
4623e5dd7070Spatrick /// \returns true if there was an error
4624e5dd7070Spatrick bool
InitFunctionInstantiation(FunctionDecl * New,FunctionDecl * Tmpl)4625e5dd7070Spatrick TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,
4626e5dd7070Spatrick FunctionDecl *Tmpl) {
4627e5dd7070Spatrick New->setImplicit(Tmpl->isImplicit());
4628e5dd7070Spatrick
4629e5dd7070Spatrick // Forward the mangling number from the template to the instantiated decl.
4630e5dd7070Spatrick SemaRef.Context.setManglingNumber(New,
4631e5dd7070Spatrick SemaRef.Context.getManglingNumber(Tmpl));
4632e5dd7070Spatrick
4633e5dd7070Spatrick // If we are performing substituting explicitly-specified template arguments
4634e5dd7070Spatrick // or deduced template arguments into a function template and we reach this
4635e5dd7070Spatrick // point, we are now past the point where SFINAE applies and have committed
4636e5dd7070Spatrick // to keeping the new function template specialization. We therefore
4637e5dd7070Spatrick // convert the active template instantiation for the function template
4638e5dd7070Spatrick // into a template instantiation for this specific function template
4639e5dd7070Spatrick // specialization, which is not a SFINAE context, so that we diagnose any
4640e5dd7070Spatrick // further errors in the declaration itself.
4641a9ac8606Spatrick //
4642a9ac8606Spatrick // FIXME: This is a hack.
4643e5dd7070Spatrick typedef Sema::CodeSynthesisContext ActiveInstType;
4644e5dd7070Spatrick ActiveInstType &ActiveInst = SemaRef.CodeSynthesisContexts.back();
4645e5dd7070Spatrick if (ActiveInst.Kind == ActiveInstType::ExplicitTemplateArgumentSubstitution ||
4646e5dd7070Spatrick ActiveInst.Kind == ActiveInstType::DeducedTemplateArgumentSubstitution) {
4647e5dd7070Spatrick if (FunctionTemplateDecl *FunTmpl
4648e5dd7070Spatrick = dyn_cast<FunctionTemplateDecl>(ActiveInst.Entity)) {
4649e5dd7070Spatrick assert(FunTmpl->getTemplatedDecl() == Tmpl &&
4650e5dd7070Spatrick "Deduction from the wrong function template?");
4651e5dd7070Spatrick (void) FunTmpl;
4652a9ac8606Spatrick SemaRef.InstantiatingSpecializations.erase(
4653a9ac8606Spatrick {ActiveInst.Entity->getCanonicalDecl(), ActiveInst.Kind});
4654e5dd7070Spatrick atTemplateEnd(SemaRef.TemplateInstCallbacks, SemaRef, ActiveInst);
4655e5dd7070Spatrick ActiveInst.Kind = ActiveInstType::TemplateInstantiation;
4656e5dd7070Spatrick ActiveInst.Entity = New;
4657e5dd7070Spatrick atTemplateBegin(SemaRef.TemplateInstCallbacks, SemaRef, ActiveInst);
4658e5dd7070Spatrick }
4659e5dd7070Spatrick }
4660e5dd7070Spatrick
4661e5dd7070Spatrick const FunctionProtoType *Proto = Tmpl->getType()->getAs<FunctionProtoType>();
4662e5dd7070Spatrick assert(Proto && "Function template without prototype?");
4663e5dd7070Spatrick
4664e5dd7070Spatrick if (Proto->hasExceptionSpec() || Proto->getNoReturnAttr()) {
4665e5dd7070Spatrick FunctionProtoType::ExtProtoInfo EPI = Proto->getExtProtoInfo();
4666e5dd7070Spatrick
4667e5dd7070Spatrick // DR1330: In C++11, defer instantiation of a non-trivial
4668e5dd7070Spatrick // exception specification.
4669e5dd7070Spatrick // DR1484: Local classes and their members are instantiated along with the
4670e5dd7070Spatrick // containing function.
4671e5dd7070Spatrick if (SemaRef.getLangOpts().CPlusPlus11 &&
4672e5dd7070Spatrick EPI.ExceptionSpec.Type != EST_None &&
4673e5dd7070Spatrick EPI.ExceptionSpec.Type != EST_DynamicNone &&
4674e5dd7070Spatrick EPI.ExceptionSpec.Type != EST_BasicNoexcept &&
4675ec727ea7Spatrick !Tmpl->isInLocalScopeForInstantiation()) {
4676e5dd7070Spatrick FunctionDecl *ExceptionSpecTemplate = Tmpl;
4677e5dd7070Spatrick if (EPI.ExceptionSpec.Type == EST_Uninstantiated)
4678e5dd7070Spatrick ExceptionSpecTemplate = EPI.ExceptionSpec.SourceTemplate;
4679e5dd7070Spatrick ExceptionSpecificationType NewEST = EST_Uninstantiated;
4680e5dd7070Spatrick if (EPI.ExceptionSpec.Type == EST_Unevaluated)
4681e5dd7070Spatrick NewEST = EST_Unevaluated;
4682e5dd7070Spatrick
4683e5dd7070Spatrick // Mark the function has having an uninstantiated exception specification.
4684e5dd7070Spatrick const FunctionProtoType *NewProto
4685e5dd7070Spatrick = New->getType()->getAs<FunctionProtoType>();
4686e5dd7070Spatrick assert(NewProto && "Template instantiation without function prototype?");
4687e5dd7070Spatrick EPI = NewProto->getExtProtoInfo();
4688e5dd7070Spatrick EPI.ExceptionSpec.Type = NewEST;
4689e5dd7070Spatrick EPI.ExceptionSpec.SourceDecl = New;
4690e5dd7070Spatrick EPI.ExceptionSpec.SourceTemplate = ExceptionSpecTemplate;
4691e5dd7070Spatrick New->setType(SemaRef.Context.getFunctionType(
4692e5dd7070Spatrick NewProto->getReturnType(), NewProto->getParamTypes(), EPI));
4693e5dd7070Spatrick } else {
4694e5dd7070Spatrick Sema::ContextRAII SwitchContext(SemaRef, New);
4695e5dd7070Spatrick SemaRef.SubstExceptionSpec(New, Proto, TemplateArgs);
4696e5dd7070Spatrick }
4697e5dd7070Spatrick }
4698e5dd7070Spatrick
4699e5dd7070Spatrick // Get the definition. Leaves the variable unchanged if undefined.
4700e5dd7070Spatrick const FunctionDecl *Definition = Tmpl;
4701e5dd7070Spatrick Tmpl->isDefined(Definition);
4702e5dd7070Spatrick
4703e5dd7070Spatrick SemaRef.InstantiateAttrs(TemplateArgs, Definition, New,
4704e5dd7070Spatrick LateAttrs, StartingScope);
4705e5dd7070Spatrick
4706e5dd7070Spatrick return false;
4707e5dd7070Spatrick }
4708e5dd7070Spatrick
4709e5dd7070Spatrick /// Initializes common fields of an instantiated method
4710e5dd7070Spatrick /// declaration (New) from the corresponding fields of its template
4711e5dd7070Spatrick /// (Tmpl).
4712e5dd7070Spatrick ///
4713e5dd7070Spatrick /// \returns true if there was an error
4714e5dd7070Spatrick bool
InitMethodInstantiation(CXXMethodDecl * New,CXXMethodDecl * Tmpl)4715e5dd7070Spatrick TemplateDeclInstantiator::InitMethodInstantiation(CXXMethodDecl *New,
4716e5dd7070Spatrick CXXMethodDecl *Tmpl) {
4717e5dd7070Spatrick if (InitFunctionInstantiation(New, Tmpl))
4718e5dd7070Spatrick return true;
4719e5dd7070Spatrick
4720e5dd7070Spatrick if (isa<CXXDestructorDecl>(New) && SemaRef.getLangOpts().CPlusPlus11)
4721e5dd7070Spatrick SemaRef.AdjustDestructorExceptionSpec(cast<CXXDestructorDecl>(New));
4722e5dd7070Spatrick
4723e5dd7070Spatrick New->setAccess(Tmpl->getAccess());
4724e5dd7070Spatrick if (Tmpl->isVirtualAsWritten())
4725e5dd7070Spatrick New->setVirtualAsWritten(true);
4726e5dd7070Spatrick
4727e5dd7070Spatrick // FIXME: New needs a pointer to Tmpl
4728e5dd7070Spatrick return false;
4729e5dd7070Spatrick }
4730e5dd7070Spatrick
SubstDefaultedFunction(FunctionDecl * New,FunctionDecl * Tmpl)4731e5dd7070Spatrick bool TemplateDeclInstantiator::SubstDefaultedFunction(FunctionDecl *New,
4732e5dd7070Spatrick FunctionDecl *Tmpl) {
4733e5dd7070Spatrick // Transfer across any unqualified lookups.
4734e5dd7070Spatrick if (auto *DFI = Tmpl->getDefaultedFunctionInfo()) {
4735e5dd7070Spatrick SmallVector<DeclAccessPair, 32> Lookups;
4736e5dd7070Spatrick Lookups.reserve(DFI->getUnqualifiedLookups().size());
4737e5dd7070Spatrick bool AnyChanged = false;
4738e5dd7070Spatrick for (DeclAccessPair DA : DFI->getUnqualifiedLookups()) {
4739e5dd7070Spatrick NamedDecl *D = SemaRef.FindInstantiatedDecl(New->getLocation(),
4740e5dd7070Spatrick DA.getDecl(), TemplateArgs);
4741e5dd7070Spatrick if (!D)
4742e5dd7070Spatrick return true;
4743e5dd7070Spatrick AnyChanged |= (D != DA.getDecl());
4744e5dd7070Spatrick Lookups.push_back(DeclAccessPair::make(D, DA.getAccess()));
4745e5dd7070Spatrick }
4746e5dd7070Spatrick
4747e5dd7070Spatrick // It's unlikely that substitution will change any declarations. Don't
4748e5dd7070Spatrick // store an unnecessary copy in that case.
4749e5dd7070Spatrick New->setDefaultedFunctionInfo(
4750e5dd7070Spatrick AnyChanged ? FunctionDecl::DefaultedFunctionInfo::Create(
4751e5dd7070Spatrick SemaRef.Context, Lookups)
4752e5dd7070Spatrick : DFI);
4753e5dd7070Spatrick }
4754e5dd7070Spatrick
4755e5dd7070Spatrick SemaRef.SetDeclDefaulted(New, Tmpl->getLocation());
4756e5dd7070Spatrick return false;
4757e5dd7070Spatrick }
4758e5dd7070Spatrick
4759e5dd7070Spatrick /// Instantiate (or find existing instantiation of) a function template with a
4760e5dd7070Spatrick /// given set of template arguments.
4761e5dd7070Spatrick ///
4762e5dd7070Spatrick /// Usually this should not be used, and template argument deduction should be
4763e5dd7070Spatrick /// used in its place.
4764e5dd7070Spatrick FunctionDecl *
InstantiateFunctionDeclaration(FunctionTemplateDecl * FTD,const TemplateArgumentList * Args,SourceLocation Loc)4765e5dd7070Spatrick Sema::InstantiateFunctionDeclaration(FunctionTemplateDecl *FTD,
4766e5dd7070Spatrick const TemplateArgumentList *Args,
4767e5dd7070Spatrick SourceLocation Loc) {
4768e5dd7070Spatrick FunctionDecl *FD = FTD->getTemplatedDecl();
4769e5dd7070Spatrick
4770e5dd7070Spatrick sema::TemplateDeductionInfo Info(Loc);
4771e5dd7070Spatrick InstantiatingTemplate Inst(
4772e5dd7070Spatrick *this, Loc, FTD, Args->asArray(),
4773e5dd7070Spatrick CodeSynthesisContext::ExplicitTemplateArgumentSubstitution, Info);
4774e5dd7070Spatrick if (Inst.isInvalid())
4775e5dd7070Spatrick return nullptr;
4776e5dd7070Spatrick
4777e5dd7070Spatrick ContextRAII SavedContext(*this, FD);
4778*12c85518Srobert MultiLevelTemplateArgumentList MArgs(FTD, Args->asArray(),
4779*12c85518Srobert /*Final=*/false);
4780e5dd7070Spatrick
4781e5dd7070Spatrick return cast_or_null<FunctionDecl>(SubstDecl(FD, FD->getParent(), MArgs));
4782e5dd7070Spatrick }
4783e5dd7070Spatrick
4784e5dd7070Spatrick /// Instantiate the definition of the given function from its
4785e5dd7070Spatrick /// template.
4786e5dd7070Spatrick ///
4787e5dd7070Spatrick /// \param PointOfInstantiation the point at which the instantiation was
4788e5dd7070Spatrick /// required. Note that this is not precisely a "point of instantiation"
4789e5dd7070Spatrick /// for the function, but it's close.
4790e5dd7070Spatrick ///
4791e5dd7070Spatrick /// \param Function the already-instantiated declaration of a
4792e5dd7070Spatrick /// function template specialization or member function of a class template
4793e5dd7070Spatrick /// specialization.
4794e5dd7070Spatrick ///
4795e5dd7070Spatrick /// \param Recursive if true, recursively instantiates any functions that
4796e5dd7070Spatrick /// are required by this instantiation.
4797e5dd7070Spatrick ///
4798e5dd7070Spatrick /// \param DefinitionRequired if true, then we are performing an explicit
4799e5dd7070Spatrick /// instantiation where the body of the function is required. Complain if
4800e5dd7070Spatrick /// there is no such body.
InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,FunctionDecl * Function,bool Recursive,bool DefinitionRequired,bool AtEndOfTU)4801e5dd7070Spatrick void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
4802e5dd7070Spatrick FunctionDecl *Function,
4803e5dd7070Spatrick bool Recursive,
4804e5dd7070Spatrick bool DefinitionRequired,
4805e5dd7070Spatrick bool AtEndOfTU) {
4806a9ac8606Spatrick if (Function->isInvalidDecl() || isa<CXXDeductionGuideDecl>(Function))
4807e5dd7070Spatrick return;
4808e5dd7070Spatrick
4809e5dd7070Spatrick // Never instantiate an explicit specialization except if it is a class scope
4810e5dd7070Spatrick // explicit specialization.
4811e5dd7070Spatrick TemplateSpecializationKind TSK =
4812e5dd7070Spatrick Function->getTemplateSpecializationKindForInstantiation();
4813e5dd7070Spatrick if (TSK == TSK_ExplicitSpecialization)
4814e5dd7070Spatrick return;
4815e5dd7070Spatrick
4816*12c85518Srobert // Never implicitly instantiate a builtin; we don't actually need a function
4817*12c85518Srobert // body.
4818*12c85518Srobert if (Function->getBuiltinID() && TSK == TSK_ImplicitInstantiation &&
4819*12c85518Srobert !DefinitionRequired)
4820*12c85518Srobert return;
4821*12c85518Srobert
4822a9ac8606Spatrick // Don't instantiate a definition if we already have one.
4823a9ac8606Spatrick const FunctionDecl *ExistingDefn = nullptr;
4824a9ac8606Spatrick if (Function->isDefined(ExistingDefn,
4825a9ac8606Spatrick /*CheckForPendingFriendDefinition=*/true)) {
4826a9ac8606Spatrick if (ExistingDefn->isThisDeclarationADefinition())
4827a9ac8606Spatrick return;
4828a9ac8606Spatrick
4829a9ac8606Spatrick // If we're asked to instantiate a function whose body comes from an
4830a9ac8606Spatrick // instantiated friend declaration, attach the instantiated body to the
4831a9ac8606Spatrick // corresponding declaration of the function.
4832a9ac8606Spatrick assert(ExistingDefn->isThisDeclarationInstantiatedFromAFriendDefinition());
4833a9ac8606Spatrick Function = const_cast<FunctionDecl*>(ExistingDefn);
4834a9ac8606Spatrick }
4835a9ac8606Spatrick
4836e5dd7070Spatrick // Find the function body that we'll be substituting.
4837e5dd7070Spatrick const FunctionDecl *PatternDecl = Function->getTemplateInstantiationPattern();
4838e5dd7070Spatrick assert(PatternDecl && "instantiating a non-template");
4839e5dd7070Spatrick
4840e5dd7070Spatrick const FunctionDecl *PatternDef = PatternDecl->getDefinition();
4841e5dd7070Spatrick Stmt *Pattern = nullptr;
4842e5dd7070Spatrick if (PatternDef) {
4843e5dd7070Spatrick Pattern = PatternDef->getBody(PatternDef);
4844e5dd7070Spatrick PatternDecl = PatternDef;
4845e5dd7070Spatrick if (PatternDef->willHaveBody())
4846e5dd7070Spatrick PatternDef = nullptr;
4847e5dd7070Spatrick }
4848e5dd7070Spatrick
4849e5dd7070Spatrick // FIXME: We need to track the instantiation stack in order to know which
4850e5dd7070Spatrick // definitions should be visible within this instantiation.
4851e5dd7070Spatrick if (DiagnoseUninstantiableTemplate(PointOfInstantiation, Function,
4852e5dd7070Spatrick Function->getInstantiatedFromMemberFunction(),
4853e5dd7070Spatrick PatternDecl, PatternDef, TSK,
4854e5dd7070Spatrick /*Complain*/DefinitionRequired)) {
4855e5dd7070Spatrick if (DefinitionRequired)
4856e5dd7070Spatrick Function->setInvalidDecl();
4857*12c85518Srobert else if (TSK == TSK_ExplicitInstantiationDefinition ||
4858*12c85518Srobert (Function->isConstexpr() && !Recursive)) {
4859e5dd7070Spatrick // Try again at the end of the translation unit (at which point a
4860e5dd7070Spatrick // definition will be required).
4861e5dd7070Spatrick assert(!Recursive);
4862e5dd7070Spatrick Function->setInstantiationIsPending(true);
4863e5dd7070Spatrick PendingInstantiations.push_back(
4864e5dd7070Spatrick std::make_pair(Function, PointOfInstantiation));
4865e5dd7070Spatrick } else if (TSK == TSK_ImplicitInstantiation) {
4866e5dd7070Spatrick if (AtEndOfTU && !getDiagnostics().hasErrorOccurred() &&
4867e5dd7070Spatrick !getSourceManager().isInSystemHeader(PatternDecl->getBeginLoc())) {
4868e5dd7070Spatrick Diag(PointOfInstantiation, diag::warn_func_template_missing)
4869e5dd7070Spatrick << Function;
4870e5dd7070Spatrick Diag(PatternDecl->getLocation(), diag::note_forward_template_decl);
4871e5dd7070Spatrick if (getLangOpts().CPlusPlus11)
4872e5dd7070Spatrick Diag(PointOfInstantiation, diag::note_inst_declaration_hint)
4873e5dd7070Spatrick << Function;
4874e5dd7070Spatrick }
4875e5dd7070Spatrick }
4876e5dd7070Spatrick
4877e5dd7070Spatrick return;
4878e5dd7070Spatrick }
4879e5dd7070Spatrick
4880e5dd7070Spatrick // Postpone late parsed template instantiations.
4881e5dd7070Spatrick if (PatternDecl->isLateTemplateParsed() &&
4882e5dd7070Spatrick !LateTemplateParser) {
4883e5dd7070Spatrick Function->setInstantiationIsPending(true);
4884e5dd7070Spatrick LateParsedInstantiations.push_back(
4885e5dd7070Spatrick std::make_pair(Function, PointOfInstantiation));
4886e5dd7070Spatrick return;
4887e5dd7070Spatrick }
4888e5dd7070Spatrick
4889e5dd7070Spatrick llvm::TimeTraceScope TimeScope("InstantiateFunction", [&]() {
4890e5dd7070Spatrick std::string Name;
4891e5dd7070Spatrick llvm::raw_string_ostream OS(Name);
4892e5dd7070Spatrick Function->getNameForDiagnostic(OS, getPrintingPolicy(),
4893e5dd7070Spatrick /*Qualified=*/true);
4894e5dd7070Spatrick return Name;
4895e5dd7070Spatrick });
4896e5dd7070Spatrick
4897e5dd7070Spatrick // If we're performing recursive template instantiation, create our own
4898e5dd7070Spatrick // queue of pending implicit instantiations that we will instantiate later,
4899e5dd7070Spatrick // while we're still within our own instantiation context.
4900e5dd7070Spatrick // This has to happen before LateTemplateParser below is called, so that
4901e5dd7070Spatrick // it marks vtables used in late parsed templates as used.
4902e5dd7070Spatrick GlobalEagerInstantiationScope GlobalInstantiations(*this,
4903e5dd7070Spatrick /*Enabled=*/Recursive);
4904e5dd7070Spatrick LocalEagerInstantiationScope LocalInstantiations(*this);
4905e5dd7070Spatrick
4906e5dd7070Spatrick // Call the LateTemplateParser callback if there is a need to late parse
4907e5dd7070Spatrick // a templated function definition.
4908e5dd7070Spatrick if (!Pattern && PatternDecl->isLateTemplateParsed() &&
4909e5dd7070Spatrick LateTemplateParser) {
4910e5dd7070Spatrick // FIXME: Optimize to allow individual templates to be deserialized.
4911e5dd7070Spatrick if (PatternDecl->isFromASTFile())
4912e5dd7070Spatrick ExternalSource->ReadLateParsedTemplates(LateParsedTemplateMap);
4913e5dd7070Spatrick
4914e5dd7070Spatrick auto LPTIter = LateParsedTemplateMap.find(PatternDecl);
4915e5dd7070Spatrick assert(LPTIter != LateParsedTemplateMap.end() &&
4916e5dd7070Spatrick "missing LateParsedTemplate");
4917e5dd7070Spatrick LateTemplateParser(OpaqueParser, *LPTIter->second);
4918e5dd7070Spatrick Pattern = PatternDecl->getBody(PatternDecl);
4919e5dd7070Spatrick }
4920e5dd7070Spatrick
4921e5dd7070Spatrick // Note, we should never try to instantiate a deleted function template.
4922e5dd7070Spatrick assert((Pattern || PatternDecl->isDefaulted() ||
4923e5dd7070Spatrick PatternDecl->hasSkippedBody()) &&
4924e5dd7070Spatrick "unexpected kind of function template definition");
4925e5dd7070Spatrick
4926e5dd7070Spatrick // C++1y [temp.explicit]p10:
4927e5dd7070Spatrick // Except for inline functions, declarations with types deduced from their
4928e5dd7070Spatrick // initializer or return value, and class template specializations, other
4929e5dd7070Spatrick // explicit instantiation declarations have the effect of suppressing the
4930e5dd7070Spatrick // implicit instantiation of the entity to which they refer.
4931e5dd7070Spatrick if (TSK == TSK_ExplicitInstantiationDeclaration &&
4932e5dd7070Spatrick !PatternDecl->isInlined() &&
4933e5dd7070Spatrick !PatternDecl->getReturnType()->getContainedAutoType())
4934e5dd7070Spatrick return;
4935e5dd7070Spatrick
4936e5dd7070Spatrick if (PatternDecl->isInlined()) {
4937e5dd7070Spatrick // Function, and all later redeclarations of it (from imported modules,
4938e5dd7070Spatrick // for instance), are now implicitly inline.
4939e5dd7070Spatrick for (auto *D = Function->getMostRecentDecl(); /**/;
4940e5dd7070Spatrick D = D->getPreviousDecl()) {
4941e5dd7070Spatrick D->setImplicitlyInline();
4942e5dd7070Spatrick if (D == Function)
4943e5dd7070Spatrick break;
4944e5dd7070Spatrick }
4945e5dd7070Spatrick }
4946e5dd7070Spatrick
4947e5dd7070Spatrick InstantiatingTemplate Inst(*this, PointOfInstantiation, Function);
4948e5dd7070Spatrick if (Inst.isInvalid() || Inst.isAlreadyInstantiating())
4949e5dd7070Spatrick return;
4950e5dd7070Spatrick PrettyDeclStackTraceEntry CrashInfo(Context, Function, SourceLocation(),
4951e5dd7070Spatrick "instantiating function definition");
4952e5dd7070Spatrick
4953e5dd7070Spatrick // The instantiation is visible here, even if it was first declared in an
4954e5dd7070Spatrick // unimported module.
4955e5dd7070Spatrick Function->setVisibleDespiteOwningModule();
4956e5dd7070Spatrick
4957e5dd7070Spatrick // Copy the inner loc start from the pattern.
4958e5dd7070Spatrick Function->setInnerLocStart(PatternDecl->getInnerLocStart());
4959e5dd7070Spatrick
4960e5dd7070Spatrick EnterExpressionEvaluationContext EvalContext(
4961e5dd7070Spatrick *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
4962e5dd7070Spatrick
4963e5dd7070Spatrick // Introduce a new scope where local variable instantiations will be
4964e5dd7070Spatrick // recorded, unless we're actually a member function within a local
4965e5dd7070Spatrick // class, in which case we need to merge our results with the parent
4966a9ac8606Spatrick // scope (of the enclosing function). The exception is instantiating
4967a9ac8606Spatrick // a function template specialization, since the template to be
4968a9ac8606Spatrick // instantiated already has references to locals properly substituted.
4969e5dd7070Spatrick bool MergeWithParentScope = false;
4970e5dd7070Spatrick if (CXXRecordDecl *Rec = dyn_cast<CXXRecordDecl>(Function->getDeclContext()))
4971a9ac8606Spatrick MergeWithParentScope =
4972a9ac8606Spatrick Rec->isLocalClass() && !Function->isFunctionTemplateSpecialization();
4973e5dd7070Spatrick
4974e5dd7070Spatrick LocalInstantiationScope Scope(*this, MergeWithParentScope);
4975a9ac8606Spatrick auto RebuildTypeSourceInfoForDefaultSpecialMembers = [&]() {
4976a9ac8606Spatrick // Special members might get their TypeSourceInfo set up w.r.t the
4977a9ac8606Spatrick // PatternDecl context, in which case parameters could still be pointing
4978a9ac8606Spatrick // back to the original class, make sure arguments are bound to the
4979a9ac8606Spatrick // instantiated record instead.
4980a9ac8606Spatrick assert(PatternDecl->isDefaulted() &&
4981a9ac8606Spatrick "Special member needs to be defaulted");
4982a9ac8606Spatrick auto PatternSM = getDefaultedFunctionKind(PatternDecl).asSpecialMember();
4983a9ac8606Spatrick if (!(PatternSM == Sema::CXXCopyConstructor ||
4984a9ac8606Spatrick PatternSM == Sema::CXXCopyAssignment ||
4985a9ac8606Spatrick PatternSM == Sema::CXXMoveConstructor ||
4986a9ac8606Spatrick PatternSM == Sema::CXXMoveAssignment))
4987a9ac8606Spatrick return;
4988e5dd7070Spatrick
4989a9ac8606Spatrick auto *NewRec = dyn_cast<CXXRecordDecl>(Function->getDeclContext());
4990a9ac8606Spatrick const auto *PatternRec =
4991a9ac8606Spatrick dyn_cast<CXXRecordDecl>(PatternDecl->getDeclContext());
4992a9ac8606Spatrick if (!NewRec || !PatternRec)
4993a9ac8606Spatrick return;
4994a9ac8606Spatrick if (!PatternRec->isLambda())
4995a9ac8606Spatrick return;
4996a9ac8606Spatrick
4997a9ac8606Spatrick struct SpecialMemberTypeInfoRebuilder
4998a9ac8606Spatrick : TreeTransform<SpecialMemberTypeInfoRebuilder> {
4999a9ac8606Spatrick using Base = TreeTransform<SpecialMemberTypeInfoRebuilder>;
5000a9ac8606Spatrick const CXXRecordDecl *OldDecl;
5001a9ac8606Spatrick CXXRecordDecl *NewDecl;
5002a9ac8606Spatrick
5003a9ac8606Spatrick SpecialMemberTypeInfoRebuilder(Sema &SemaRef, const CXXRecordDecl *O,
5004a9ac8606Spatrick CXXRecordDecl *N)
5005a9ac8606Spatrick : TreeTransform(SemaRef), OldDecl(O), NewDecl(N) {}
5006a9ac8606Spatrick
5007a9ac8606Spatrick bool TransformExceptionSpec(SourceLocation Loc,
5008a9ac8606Spatrick FunctionProtoType::ExceptionSpecInfo &ESI,
5009a9ac8606Spatrick SmallVectorImpl<QualType> &Exceptions,
5010a9ac8606Spatrick bool &Changed) {
5011a9ac8606Spatrick return false;
5012a9ac8606Spatrick }
5013a9ac8606Spatrick
5014a9ac8606Spatrick QualType TransformRecordType(TypeLocBuilder &TLB, RecordTypeLoc TL) {
5015a9ac8606Spatrick const RecordType *T = TL.getTypePtr();
5016a9ac8606Spatrick RecordDecl *Record = cast_or_null<RecordDecl>(
5017a9ac8606Spatrick getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
5018a9ac8606Spatrick if (Record != OldDecl)
5019a9ac8606Spatrick return Base::TransformRecordType(TLB, TL);
5020a9ac8606Spatrick
5021a9ac8606Spatrick QualType Result = getDerived().RebuildRecordType(NewDecl);
5022a9ac8606Spatrick if (Result.isNull())
5023a9ac8606Spatrick return QualType();
5024a9ac8606Spatrick
5025a9ac8606Spatrick RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
5026a9ac8606Spatrick NewTL.setNameLoc(TL.getNameLoc());
5027a9ac8606Spatrick return Result;
5028a9ac8606Spatrick }
5029a9ac8606Spatrick } IR{*this, PatternRec, NewRec};
5030a9ac8606Spatrick
5031a9ac8606Spatrick TypeSourceInfo *NewSI = IR.TransformType(Function->getTypeSourceInfo());
5032a9ac8606Spatrick Function->setType(NewSI->getType());
5033a9ac8606Spatrick Function->setTypeSourceInfo(NewSI);
5034a9ac8606Spatrick
5035a9ac8606Spatrick ParmVarDecl *Parm = Function->getParamDecl(0);
5036a9ac8606Spatrick TypeSourceInfo *NewParmSI = IR.TransformType(Parm->getTypeSourceInfo());
5037a9ac8606Spatrick Parm->setType(NewParmSI->getType());
5038a9ac8606Spatrick Parm->setTypeSourceInfo(NewParmSI);
5039a9ac8606Spatrick };
5040a9ac8606Spatrick
5041a9ac8606Spatrick if (PatternDecl->isDefaulted()) {
5042a9ac8606Spatrick RebuildTypeSourceInfoForDefaultSpecialMembers();
5043e5dd7070Spatrick SetDeclDefaulted(Function, PatternDecl->getLocation());
5044a9ac8606Spatrick } else {
5045*12c85518Srobert MultiLevelTemplateArgumentList TemplateArgs = getTemplateInstantiationArgs(
5046*12c85518Srobert Function, /*Final=*/false, nullptr, false, PatternDecl);
5047e5dd7070Spatrick
5048e5dd7070Spatrick // Substitute into the qualifier; we can get a substitution failure here
5049e5dd7070Spatrick // through evil use of alias templates.
5050e5dd7070Spatrick // FIXME: Is CurContext correct for this? Should we go to the (instantiation
5051e5dd7070Spatrick // of the) lexical context of the pattern?
5052e5dd7070Spatrick SubstQualifier(*this, PatternDecl, Function, TemplateArgs);
5053e5dd7070Spatrick
5054e5dd7070Spatrick ActOnStartOfFunctionDef(nullptr, Function);
5055e5dd7070Spatrick
5056e5dd7070Spatrick // Enter the scope of this instantiation. We don't use
5057e5dd7070Spatrick // PushDeclContext because we don't have a scope.
5058e5dd7070Spatrick Sema::ContextRAII savedContext(*this, Function);
5059e5dd7070Spatrick
5060*12c85518Srobert if (addInstantiatedParametersToScope(Function, PatternDecl, Scope,
5061e5dd7070Spatrick TemplateArgs))
5062e5dd7070Spatrick return;
5063e5dd7070Spatrick
5064e5dd7070Spatrick StmtResult Body;
5065e5dd7070Spatrick if (PatternDecl->hasSkippedBody()) {
5066e5dd7070Spatrick ActOnSkippedFunctionBody(Function);
5067e5dd7070Spatrick Body = nullptr;
5068e5dd7070Spatrick } else {
5069e5dd7070Spatrick if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(Function)) {
5070e5dd7070Spatrick // If this is a constructor, instantiate the member initializers.
5071e5dd7070Spatrick InstantiateMemInitializers(Ctor, cast<CXXConstructorDecl>(PatternDecl),
5072e5dd7070Spatrick TemplateArgs);
5073e5dd7070Spatrick
5074e5dd7070Spatrick // If this is an MS ABI dllexport default constructor, instantiate any
5075e5dd7070Spatrick // default arguments.
5076e5dd7070Spatrick if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
5077e5dd7070Spatrick Ctor->isDefaultConstructor()) {
5078a9ac8606Spatrick InstantiateDefaultCtorDefaultArgs(Ctor);
5079e5dd7070Spatrick }
5080e5dd7070Spatrick }
5081e5dd7070Spatrick
5082e5dd7070Spatrick // Instantiate the function body.
5083e5dd7070Spatrick Body = SubstStmt(Pattern, TemplateArgs);
5084e5dd7070Spatrick
5085e5dd7070Spatrick if (Body.isInvalid())
5086e5dd7070Spatrick Function->setInvalidDecl();
5087e5dd7070Spatrick }
5088e5dd7070Spatrick // FIXME: finishing the function body while in an expression evaluation
5089e5dd7070Spatrick // context seems wrong. Investigate more.
5090e5dd7070Spatrick ActOnFinishFunctionBody(Function, Body.get(), /*IsInstantiation=*/true);
5091e5dd7070Spatrick
5092e5dd7070Spatrick PerformDependentDiagnostics(PatternDecl, TemplateArgs);
5093e5dd7070Spatrick
5094e5dd7070Spatrick if (auto *Listener = getASTMutationListener())
5095e5dd7070Spatrick Listener->FunctionDefinitionInstantiated(Function);
5096e5dd7070Spatrick
5097e5dd7070Spatrick savedContext.pop();
5098e5dd7070Spatrick }
5099e5dd7070Spatrick
5100e5dd7070Spatrick DeclGroupRef DG(Function);
5101e5dd7070Spatrick Consumer.HandleTopLevelDecl(DG);
5102e5dd7070Spatrick
5103e5dd7070Spatrick // This class may have local implicit instantiations that need to be
5104e5dd7070Spatrick // instantiation within this scope.
5105e5dd7070Spatrick LocalInstantiations.perform();
5106e5dd7070Spatrick Scope.Exit();
5107e5dd7070Spatrick GlobalInstantiations.perform();
5108e5dd7070Spatrick }
5109e5dd7070Spatrick
BuildVarTemplateInstantiation(VarTemplateDecl * VarTemplate,VarDecl * FromVar,const TemplateArgumentList & TemplateArgList,const TemplateArgumentListInfo & TemplateArgsInfo,SmallVectorImpl<TemplateArgument> & Converted,SourceLocation PointOfInstantiation,LateInstantiatedAttrVec * LateAttrs,LocalInstantiationScope * StartingScope)5110e5dd7070Spatrick VarTemplateSpecializationDecl *Sema::BuildVarTemplateInstantiation(
5111e5dd7070Spatrick VarTemplateDecl *VarTemplate, VarDecl *FromVar,
5112e5dd7070Spatrick const TemplateArgumentList &TemplateArgList,
5113e5dd7070Spatrick const TemplateArgumentListInfo &TemplateArgsInfo,
5114e5dd7070Spatrick SmallVectorImpl<TemplateArgument> &Converted,
5115*12c85518Srobert SourceLocation PointOfInstantiation, LateInstantiatedAttrVec *LateAttrs,
5116e5dd7070Spatrick LocalInstantiationScope *StartingScope) {
5117e5dd7070Spatrick if (FromVar->isInvalidDecl())
5118e5dd7070Spatrick return nullptr;
5119e5dd7070Spatrick
5120e5dd7070Spatrick InstantiatingTemplate Inst(*this, PointOfInstantiation, FromVar);
5121e5dd7070Spatrick if (Inst.isInvalid())
5122e5dd7070Spatrick return nullptr;
5123e5dd7070Spatrick
5124e5dd7070Spatrick // Instantiate the first declaration of the variable template: for a partial
5125e5dd7070Spatrick // specialization of a static data member template, the first declaration may
5126e5dd7070Spatrick // or may not be the declaration in the class; if it's in the class, we want
5127e5dd7070Spatrick // to instantiate a member in the class (a declaration), and if it's outside,
5128e5dd7070Spatrick // we want to instantiate a definition.
5129e5dd7070Spatrick //
5130e5dd7070Spatrick // If we're instantiating an explicitly-specialized member template or member
5131e5dd7070Spatrick // partial specialization, don't do this. The member specialization completely
5132e5dd7070Spatrick // replaces the original declaration in this case.
5133e5dd7070Spatrick bool IsMemberSpec = false;
5134*12c85518Srobert MultiLevelTemplateArgumentList MultiLevelList;
5135*12c85518Srobert if (auto *PartialSpec =
5136*12c85518Srobert dyn_cast<VarTemplatePartialSpecializationDecl>(FromVar)) {
5137e5dd7070Spatrick IsMemberSpec = PartialSpec->isMemberSpecialization();
5138*12c85518Srobert MultiLevelList.addOuterTemplateArguments(
5139*12c85518Srobert PartialSpec, TemplateArgList.asArray(), /*Final=*/false);
5140*12c85518Srobert } else {
5141*12c85518Srobert assert(VarTemplate == FromVar->getDescribedVarTemplate());
5142*12c85518Srobert IsMemberSpec = VarTemplate->isMemberSpecialization();
5143*12c85518Srobert MultiLevelList.addOuterTemplateArguments(
5144*12c85518Srobert VarTemplate, TemplateArgList.asArray(), /*Final=*/false);
5145*12c85518Srobert }
5146e5dd7070Spatrick if (!IsMemberSpec)
5147e5dd7070Spatrick FromVar = FromVar->getFirstDecl();
5148e5dd7070Spatrick
5149e5dd7070Spatrick TemplateDeclInstantiator Instantiator(*this, FromVar->getDeclContext(),
5150e5dd7070Spatrick MultiLevelList);
5151e5dd7070Spatrick
5152e5dd7070Spatrick // TODO: Set LateAttrs and StartingScope ...
5153e5dd7070Spatrick
5154e5dd7070Spatrick return cast_or_null<VarTemplateSpecializationDecl>(
5155e5dd7070Spatrick Instantiator.VisitVarTemplateSpecializationDecl(
5156a9ac8606Spatrick VarTemplate, FromVar, TemplateArgsInfo, Converted));
5157e5dd7070Spatrick }
5158e5dd7070Spatrick
5159e5dd7070Spatrick /// Instantiates a variable template specialization by completing it
5160e5dd7070Spatrick /// with appropriate type information and initializer.
CompleteVarTemplateSpecializationDecl(VarTemplateSpecializationDecl * VarSpec,VarDecl * PatternDecl,const MultiLevelTemplateArgumentList & TemplateArgs)5161e5dd7070Spatrick VarTemplateSpecializationDecl *Sema::CompleteVarTemplateSpecializationDecl(
5162e5dd7070Spatrick VarTemplateSpecializationDecl *VarSpec, VarDecl *PatternDecl,
5163e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs) {
5164e5dd7070Spatrick assert(PatternDecl->isThisDeclarationADefinition() &&
5165e5dd7070Spatrick "don't have a definition to instantiate from");
5166e5dd7070Spatrick
5167e5dd7070Spatrick // Do substitution on the type of the declaration
5168e5dd7070Spatrick TypeSourceInfo *DI =
5169e5dd7070Spatrick SubstType(PatternDecl->getTypeSourceInfo(), TemplateArgs,
5170e5dd7070Spatrick PatternDecl->getTypeSpecStartLoc(), PatternDecl->getDeclName());
5171e5dd7070Spatrick if (!DI)
5172e5dd7070Spatrick return nullptr;
5173e5dd7070Spatrick
5174e5dd7070Spatrick // Update the type of this variable template specialization.
5175e5dd7070Spatrick VarSpec->setType(DI->getType());
5176e5dd7070Spatrick
5177e5dd7070Spatrick // Convert the declaration into a definition now.
5178e5dd7070Spatrick VarSpec->setCompleteDefinition();
5179e5dd7070Spatrick
5180e5dd7070Spatrick // Instantiate the initializer.
5181e5dd7070Spatrick InstantiateVariableInitializer(VarSpec, PatternDecl, TemplateArgs);
5182e5dd7070Spatrick
5183ec727ea7Spatrick if (getLangOpts().OpenCL)
5184ec727ea7Spatrick deduceOpenCLAddressSpace(VarSpec);
5185ec727ea7Spatrick
5186e5dd7070Spatrick return VarSpec;
5187e5dd7070Spatrick }
5188e5dd7070Spatrick
5189e5dd7070Spatrick /// BuildVariableInstantiation - Used after a new variable has been created.
5190e5dd7070Spatrick /// Sets basic variable data and decides whether to postpone the
5191e5dd7070Spatrick /// variable instantiation.
BuildVariableInstantiation(VarDecl * NewVar,VarDecl * OldVar,const MultiLevelTemplateArgumentList & TemplateArgs,LateInstantiatedAttrVec * LateAttrs,DeclContext * Owner,LocalInstantiationScope * StartingScope,bool InstantiatingVarTemplate,VarTemplateSpecializationDecl * PrevDeclForVarTemplateSpecialization)5192e5dd7070Spatrick void Sema::BuildVariableInstantiation(
5193e5dd7070Spatrick VarDecl *NewVar, VarDecl *OldVar,
5194e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs,
5195e5dd7070Spatrick LateInstantiatedAttrVec *LateAttrs, DeclContext *Owner,
5196e5dd7070Spatrick LocalInstantiationScope *StartingScope,
5197e5dd7070Spatrick bool InstantiatingVarTemplate,
5198e5dd7070Spatrick VarTemplateSpecializationDecl *PrevDeclForVarTemplateSpecialization) {
5199e5dd7070Spatrick // Instantiating a partial specialization to produce a partial
5200e5dd7070Spatrick // specialization.
5201e5dd7070Spatrick bool InstantiatingVarTemplatePartialSpec =
5202e5dd7070Spatrick isa<VarTemplatePartialSpecializationDecl>(OldVar) &&
5203e5dd7070Spatrick isa<VarTemplatePartialSpecializationDecl>(NewVar);
5204e5dd7070Spatrick // Instantiating from a variable template (or partial specialization) to
5205e5dd7070Spatrick // produce a variable template specialization.
5206e5dd7070Spatrick bool InstantiatingSpecFromTemplate =
5207e5dd7070Spatrick isa<VarTemplateSpecializationDecl>(NewVar) &&
5208e5dd7070Spatrick (OldVar->getDescribedVarTemplate() ||
5209e5dd7070Spatrick isa<VarTemplatePartialSpecializationDecl>(OldVar));
5210e5dd7070Spatrick
5211e5dd7070Spatrick // If we are instantiating a local extern declaration, the
5212e5dd7070Spatrick // instantiation belongs lexically to the containing function.
5213e5dd7070Spatrick // If we are instantiating a static data member defined
5214e5dd7070Spatrick // out-of-line, the instantiation will have the same lexical
5215e5dd7070Spatrick // context (which will be a namespace scope) as the template.
5216e5dd7070Spatrick if (OldVar->isLocalExternDecl()) {
5217e5dd7070Spatrick NewVar->setLocalExternDecl();
5218e5dd7070Spatrick NewVar->setLexicalDeclContext(Owner);
5219e5dd7070Spatrick } else if (OldVar->isOutOfLine())
5220e5dd7070Spatrick NewVar->setLexicalDeclContext(OldVar->getLexicalDeclContext());
5221e5dd7070Spatrick NewVar->setTSCSpec(OldVar->getTSCSpec());
5222e5dd7070Spatrick NewVar->setInitStyle(OldVar->getInitStyle());
5223e5dd7070Spatrick NewVar->setCXXForRangeDecl(OldVar->isCXXForRangeDecl());
5224e5dd7070Spatrick NewVar->setObjCForDecl(OldVar->isObjCForDecl());
5225e5dd7070Spatrick NewVar->setConstexpr(OldVar->isConstexpr());
5226e5dd7070Spatrick NewVar->setInitCapture(OldVar->isInitCapture());
5227e5dd7070Spatrick NewVar->setPreviousDeclInSameBlockScope(
5228e5dd7070Spatrick OldVar->isPreviousDeclInSameBlockScope());
5229e5dd7070Spatrick NewVar->setAccess(OldVar->getAccess());
5230e5dd7070Spatrick
5231e5dd7070Spatrick if (!OldVar->isStaticDataMember()) {
5232e5dd7070Spatrick if (OldVar->isUsed(false))
5233e5dd7070Spatrick NewVar->setIsUsed();
5234e5dd7070Spatrick NewVar->setReferenced(OldVar->isReferenced());
5235e5dd7070Spatrick }
5236e5dd7070Spatrick
5237e5dd7070Spatrick InstantiateAttrs(TemplateArgs, OldVar, NewVar, LateAttrs, StartingScope);
5238e5dd7070Spatrick
5239e5dd7070Spatrick LookupResult Previous(
5240e5dd7070Spatrick *this, NewVar->getDeclName(), NewVar->getLocation(),
5241e5dd7070Spatrick NewVar->isLocalExternDecl() ? Sema::LookupRedeclarationWithLinkage
5242e5dd7070Spatrick : Sema::LookupOrdinaryName,
5243e5dd7070Spatrick NewVar->isLocalExternDecl() ? Sema::ForExternalRedeclaration
5244e5dd7070Spatrick : forRedeclarationInCurContext());
5245e5dd7070Spatrick
5246e5dd7070Spatrick if (NewVar->isLocalExternDecl() && OldVar->getPreviousDecl() &&
5247e5dd7070Spatrick (!OldVar->getPreviousDecl()->getDeclContext()->isDependentContext() ||
5248e5dd7070Spatrick OldVar->getPreviousDecl()->getDeclContext()==OldVar->getDeclContext())) {
5249e5dd7070Spatrick // We have a previous declaration. Use that one, so we merge with the
5250e5dd7070Spatrick // right type.
5251e5dd7070Spatrick if (NamedDecl *NewPrev = FindInstantiatedDecl(
5252e5dd7070Spatrick NewVar->getLocation(), OldVar->getPreviousDecl(), TemplateArgs))
5253e5dd7070Spatrick Previous.addDecl(NewPrev);
5254e5dd7070Spatrick } else if (!isa<VarTemplateSpecializationDecl>(NewVar) &&
5255e5dd7070Spatrick OldVar->hasLinkage()) {
5256e5dd7070Spatrick LookupQualifiedName(Previous, NewVar->getDeclContext(), false);
5257e5dd7070Spatrick } else if (PrevDeclForVarTemplateSpecialization) {
5258e5dd7070Spatrick Previous.addDecl(PrevDeclForVarTemplateSpecialization);
5259e5dd7070Spatrick }
5260e5dd7070Spatrick CheckVariableDeclaration(NewVar, Previous);
5261e5dd7070Spatrick
5262e5dd7070Spatrick if (!InstantiatingVarTemplate) {
5263e5dd7070Spatrick NewVar->getLexicalDeclContext()->addHiddenDecl(NewVar);
5264e5dd7070Spatrick if (!NewVar->isLocalExternDecl() || !NewVar->getPreviousDecl())
5265e5dd7070Spatrick NewVar->getDeclContext()->makeDeclVisibleInContext(NewVar);
5266e5dd7070Spatrick }
5267e5dd7070Spatrick
5268e5dd7070Spatrick if (!OldVar->isOutOfLine()) {
5269e5dd7070Spatrick if (NewVar->getDeclContext()->isFunctionOrMethod())
5270e5dd7070Spatrick CurrentInstantiationScope->InstantiatedLocal(OldVar, NewVar);
5271e5dd7070Spatrick }
5272e5dd7070Spatrick
5273e5dd7070Spatrick // Link instantiations of static data members back to the template from
5274e5dd7070Spatrick // which they were instantiated.
5275e5dd7070Spatrick //
5276e5dd7070Spatrick // Don't do this when instantiating a template (we link the template itself
5277e5dd7070Spatrick // back in that case) nor when instantiating a static data member template
5278e5dd7070Spatrick // (that's not a member specialization).
5279e5dd7070Spatrick if (NewVar->isStaticDataMember() && !InstantiatingVarTemplate &&
5280e5dd7070Spatrick !InstantiatingSpecFromTemplate)
5281e5dd7070Spatrick NewVar->setInstantiationOfStaticDataMember(OldVar,
5282e5dd7070Spatrick TSK_ImplicitInstantiation);
5283e5dd7070Spatrick
5284e5dd7070Spatrick // If the pattern is an (in-class) explicit specialization, then the result
5285e5dd7070Spatrick // is also an explicit specialization.
5286e5dd7070Spatrick if (VarTemplateSpecializationDecl *OldVTSD =
5287e5dd7070Spatrick dyn_cast<VarTemplateSpecializationDecl>(OldVar)) {
5288e5dd7070Spatrick if (OldVTSD->getSpecializationKind() == TSK_ExplicitSpecialization &&
5289e5dd7070Spatrick !isa<VarTemplatePartialSpecializationDecl>(OldVTSD))
5290e5dd7070Spatrick cast<VarTemplateSpecializationDecl>(NewVar)->setSpecializationKind(
5291e5dd7070Spatrick TSK_ExplicitSpecialization);
5292e5dd7070Spatrick }
5293e5dd7070Spatrick
5294e5dd7070Spatrick // Forward the mangling number from the template to the instantiated decl.
5295e5dd7070Spatrick Context.setManglingNumber(NewVar, Context.getManglingNumber(OldVar));
5296e5dd7070Spatrick Context.setStaticLocalNumber(NewVar, Context.getStaticLocalNumber(OldVar));
5297e5dd7070Spatrick
5298e5dd7070Spatrick // Figure out whether to eagerly instantiate the initializer.
5299e5dd7070Spatrick if (InstantiatingVarTemplate || InstantiatingVarTemplatePartialSpec) {
5300e5dd7070Spatrick // We're producing a template. Don't instantiate the initializer yet.
5301e5dd7070Spatrick } else if (NewVar->getType()->isUndeducedType()) {
5302e5dd7070Spatrick // We need the type to complete the declaration of the variable.
5303e5dd7070Spatrick InstantiateVariableInitializer(NewVar, OldVar, TemplateArgs);
5304e5dd7070Spatrick } else if (InstantiatingSpecFromTemplate ||
5305e5dd7070Spatrick (OldVar->isInline() && OldVar->isThisDeclarationADefinition() &&
5306e5dd7070Spatrick !NewVar->isThisDeclarationADefinition())) {
5307e5dd7070Spatrick // Delay instantiation of the initializer for variable template
5308e5dd7070Spatrick // specializations or inline static data members until a definition of the
5309e5dd7070Spatrick // variable is needed.
5310e5dd7070Spatrick } else {
5311e5dd7070Spatrick InstantiateVariableInitializer(NewVar, OldVar, TemplateArgs);
5312e5dd7070Spatrick }
5313e5dd7070Spatrick
5314e5dd7070Spatrick // Diagnose unused local variables with dependent types, where the diagnostic
5315e5dd7070Spatrick // will have been deferred.
5316e5dd7070Spatrick if (!NewVar->isInvalidDecl() &&
5317e5dd7070Spatrick NewVar->getDeclContext()->isFunctionOrMethod() &&
5318e5dd7070Spatrick OldVar->getType()->isDependentType())
5319e5dd7070Spatrick DiagnoseUnusedDecl(NewVar);
5320e5dd7070Spatrick }
5321e5dd7070Spatrick
5322e5dd7070Spatrick /// Instantiate the initializer of a variable.
InstantiateVariableInitializer(VarDecl * Var,VarDecl * OldVar,const MultiLevelTemplateArgumentList & TemplateArgs)5323e5dd7070Spatrick void Sema::InstantiateVariableInitializer(
5324e5dd7070Spatrick VarDecl *Var, VarDecl *OldVar,
5325e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs) {
5326e5dd7070Spatrick if (ASTMutationListener *L = getASTContext().getASTMutationListener())
5327e5dd7070Spatrick L->VariableDefinitionInstantiated(Var);
5328e5dd7070Spatrick
5329e5dd7070Spatrick // We propagate the 'inline' flag with the initializer, because it
5330e5dd7070Spatrick // would otherwise imply that the variable is a definition for a
5331e5dd7070Spatrick // non-static data member.
5332e5dd7070Spatrick if (OldVar->isInlineSpecified())
5333e5dd7070Spatrick Var->setInlineSpecified();
5334e5dd7070Spatrick else if (OldVar->isInline())
5335e5dd7070Spatrick Var->setImplicitlyInline();
5336e5dd7070Spatrick
5337e5dd7070Spatrick if (OldVar->getInit()) {
5338e5dd7070Spatrick EnterExpressionEvaluationContext Evaluated(
5339e5dd7070Spatrick *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated, Var);
5340e5dd7070Spatrick
5341e5dd7070Spatrick // Instantiate the initializer.
5342e5dd7070Spatrick ExprResult Init;
5343e5dd7070Spatrick
5344e5dd7070Spatrick {
5345e5dd7070Spatrick ContextRAII SwitchContext(*this, Var->getDeclContext());
5346e5dd7070Spatrick Init = SubstInitializer(OldVar->getInit(), TemplateArgs,
5347e5dd7070Spatrick OldVar->getInitStyle() == VarDecl::CallInit);
5348e5dd7070Spatrick }
5349e5dd7070Spatrick
5350e5dd7070Spatrick if (!Init.isInvalid()) {
5351e5dd7070Spatrick Expr *InitExpr = Init.get();
5352e5dd7070Spatrick
5353e5dd7070Spatrick if (Var->hasAttr<DLLImportAttr>() &&
5354e5dd7070Spatrick (!InitExpr ||
5355e5dd7070Spatrick !InitExpr->isConstantInitializer(getASTContext(), false))) {
5356e5dd7070Spatrick // Do not dynamically initialize dllimport variables.
5357e5dd7070Spatrick } else if (InitExpr) {
5358e5dd7070Spatrick bool DirectInit = OldVar->isDirectInit();
5359e5dd7070Spatrick AddInitializerToDecl(Var, InitExpr, DirectInit);
5360e5dd7070Spatrick } else
5361e5dd7070Spatrick ActOnUninitializedDecl(Var);
5362e5dd7070Spatrick } else {
5363e5dd7070Spatrick // FIXME: Not too happy about invalidating the declaration
5364e5dd7070Spatrick // because of a bogus initializer.
5365e5dd7070Spatrick Var->setInvalidDecl();
5366e5dd7070Spatrick }
5367e5dd7070Spatrick } else {
5368e5dd7070Spatrick // `inline` variables are a definition and declaration all in one; we won't
5369e5dd7070Spatrick // pick up an initializer from anywhere else.
5370e5dd7070Spatrick if (Var->isStaticDataMember() && !Var->isInline()) {
5371e5dd7070Spatrick if (!Var->isOutOfLine())
5372e5dd7070Spatrick return;
5373e5dd7070Spatrick
5374e5dd7070Spatrick // If the declaration inside the class had an initializer, don't add
5375e5dd7070Spatrick // another one to the out-of-line definition.
5376e5dd7070Spatrick if (OldVar->getFirstDecl()->hasInit())
5377e5dd7070Spatrick return;
5378e5dd7070Spatrick }
5379e5dd7070Spatrick
5380e5dd7070Spatrick // We'll add an initializer to a for-range declaration later.
5381e5dd7070Spatrick if (Var->isCXXForRangeDecl() || Var->isObjCForDecl())
5382e5dd7070Spatrick return;
5383e5dd7070Spatrick
5384e5dd7070Spatrick ActOnUninitializedDecl(Var);
5385e5dd7070Spatrick }
5386e5dd7070Spatrick
5387e5dd7070Spatrick if (getLangOpts().CUDA)
5388e5dd7070Spatrick checkAllowedCUDAInitializer(Var);
5389e5dd7070Spatrick }
5390e5dd7070Spatrick
5391e5dd7070Spatrick /// Instantiate the definition of the given variable from its
5392e5dd7070Spatrick /// template.
5393e5dd7070Spatrick ///
5394e5dd7070Spatrick /// \param PointOfInstantiation the point at which the instantiation was
5395e5dd7070Spatrick /// required. Note that this is not precisely a "point of instantiation"
5396e5dd7070Spatrick /// for the variable, but it's close.
5397e5dd7070Spatrick ///
5398e5dd7070Spatrick /// \param Var the already-instantiated declaration of a templated variable.
5399e5dd7070Spatrick ///
5400e5dd7070Spatrick /// \param Recursive if true, recursively instantiates any functions that
5401e5dd7070Spatrick /// are required by this instantiation.
5402e5dd7070Spatrick ///
5403e5dd7070Spatrick /// \param DefinitionRequired if true, then we are performing an explicit
5404e5dd7070Spatrick /// instantiation where a definition of the variable is required. Complain
5405e5dd7070Spatrick /// if there is no such definition.
InstantiateVariableDefinition(SourceLocation PointOfInstantiation,VarDecl * Var,bool Recursive,bool DefinitionRequired,bool AtEndOfTU)5406e5dd7070Spatrick void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation,
5407e5dd7070Spatrick VarDecl *Var, bool Recursive,
5408e5dd7070Spatrick bool DefinitionRequired, bool AtEndOfTU) {
5409e5dd7070Spatrick if (Var->isInvalidDecl())
5410e5dd7070Spatrick return;
5411e5dd7070Spatrick
5412e5dd7070Spatrick // Never instantiate an explicitly-specialized entity.
5413e5dd7070Spatrick TemplateSpecializationKind TSK =
5414e5dd7070Spatrick Var->getTemplateSpecializationKindForInstantiation();
5415e5dd7070Spatrick if (TSK == TSK_ExplicitSpecialization)
5416e5dd7070Spatrick return;
5417e5dd7070Spatrick
5418e5dd7070Spatrick // Find the pattern and the arguments to substitute into it.
5419e5dd7070Spatrick VarDecl *PatternDecl = Var->getTemplateInstantiationPattern();
5420e5dd7070Spatrick assert(PatternDecl && "no pattern for templated variable");
5421e5dd7070Spatrick MultiLevelTemplateArgumentList TemplateArgs =
5422e5dd7070Spatrick getTemplateInstantiationArgs(Var);
5423e5dd7070Spatrick
5424e5dd7070Spatrick VarTemplateSpecializationDecl *VarSpec =
5425e5dd7070Spatrick dyn_cast<VarTemplateSpecializationDecl>(Var);
5426e5dd7070Spatrick if (VarSpec) {
5427e5dd7070Spatrick // If this is a static data member template, there might be an
5428e5dd7070Spatrick // uninstantiated initializer on the declaration. If so, instantiate
5429e5dd7070Spatrick // it now.
5430e5dd7070Spatrick //
5431e5dd7070Spatrick // FIXME: This largely duplicates what we would do below. The difference
5432e5dd7070Spatrick // is that along this path we may instantiate an initializer from an
5433e5dd7070Spatrick // in-class declaration of the template and instantiate the definition
5434e5dd7070Spatrick // from a separate out-of-class definition.
5435e5dd7070Spatrick if (PatternDecl->isStaticDataMember() &&
5436e5dd7070Spatrick (PatternDecl = PatternDecl->getFirstDecl())->hasInit() &&
5437e5dd7070Spatrick !Var->hasInit()) {
5438e5dd7070Spatrick // FIXME: Factor out the duplicated instantiation context setup/tear down
5439e5dd7070Spatrick // code here.
5440e5dd7070Spatrick InstantiatingTemplate Inst(*this, PointOfInstantiation, Var);
5441e5dd7070Spatrick if (Inst.isInvalid() || Inst.isAlreadyInstantiating())
5442e5dd7070Spatrick return;
5443e5dd7070Spatrick PrettyDeclStackTraceEntry CrashInfo(Context, Var, SourceLocation(),
5444e5dd7070Spatrick "instantiating variable initializer");
5445e5dd7070Spatrick
5446e5dd7070Spatrick // The instantiation is visible here, even if it was first declared in an
5447e5dd7070Spatrick // unimported module.
5448e5dd7070Spatrick Var->setVisibleDespiteOwningModule();
5449e5dd7070Spatrick
5450e5dd7070Spatrick // If we're performing recursive template instantiation, create our own
5451e5dd7070Spatrick // queue of pending implicit instantiations that we will instantiate
5452e5dd7070Spatrick // later, while we're still within our own instantiation context.
5453e5dd7070Spatrick GlobalEagerInstantiationScope GlobalInstantiations(*this,
5454e5dd7070Spatrick /*Enabled=*/Recursive);
5455e5dd7070Spatrick LocalInstantiationScope Local(*this);
5456e5dd7070Spatrick LocalEagerInstantiationScope LocalInstantiations(*this);
5457e5dd7070Spatrick
5458e5dd7070Spatrick // Enter the scope of this instantiation. We don't use
5459e5dd7070Spatrick // PushDeclContext because we don't have a scope.
5460e5dd7070Spatrick ContextRAII PreviousContext(*this, Var->getDeclContext());
5461e5dd7070Spatrick InstantiateVariableInitializer(Var, PatternDecl, TemplateArgs);
5462e5dd7070Spatrick PreviousContext.pop();
5463e5dd7070Spatrick
5464e5dd7070Spatrick // This variable may have local implicit instantiations that need to be
5465e5dd7070Spatrick // instantiated within this scope.
5466e5dd7070Spatrick LocalInstantiations.perform();
5467e5dd7070Spatrick Local.Exit();
5468e5dd7070Spatrick GlobalInstantiations.perform();
5469e5dd7070Spatrick }
5470e5dd7070Spatrick } else {
5471e5dd7070Spatrick assert(Var->isStaticDataMember() && PatternDecl->isStaticDataMember() &&
5472e5dd7070Spatrick "not a static data member?");
5473e5dd7070Spatrick }
5474e5dd7070Spatrick
5475e5dd7070Spatrick VarDecl *Def = PatternDecl->getDefinition(getASTContext());
5476e5dd7070Spatrick
5477e5dd7070Spatrick // If we don't have a definition of the variable template, we won't perform
5478e5dd7070Spatrick // any instantiation. Rather, we rely on the user to instantiate this
5479e5dd7070Spatrick // definition (or provide a specialization for it) in another translation
5480e5dd7070Spatrick // unit.
5481e5dd7070Spatrick if (!Def && !DefinitionRequired) {
5482e5dd7070Spatrick if (TSK == TSK_ExplicitInstantiationDefinition) {
5483e5dd7070Spatrick PendingInstantiations.push_back(
5484e5dd7070Spatrick std::make_pair(Var, PointOfInstantiation));
5485e5dd7070Spatrick } else if (TSK == TSK_ImplicitInstantiation) {
5486e5dd7070Spatrick // Warn about missing definition at the end of translation unit.
5487e5dd7070Spatrick if (AtEndOfTU && !getDiagnostics().hasErrorOccurred() &&
5488e5dd7070Spatrick !getSourceManager().isInSystemHeader(PatternDecl->getBeginLoc())) {
5489e5dd7070Spatrick Diag(PointOfInstantiation, diag::warn_var_template_missing)
5490e5dd7070Spatrick << Var;
5491e5dd7070Spatrick Diag(PatternDecl->getLocation(), diag::note_forward_template_decl);
5492e5dd7070Spatrick if (getLangOpts().CPlusPlus11)
5493e5dd7070Spatrick Diag(PointOfInstantiation, diag::note_inst_declaration_hint) << Var;
5494e5dd7070Spatrick }
5495e5dd7070Spatrick return;
5496e5dd7070Spatrick }
5497e5dd7070Spatrick }
5498e5dd7070Spatrick
5499e5dd7070Spatrick // FIXME: We need to track the instantiation stack in order to know which
5500e5dd7070Spatrick // definitions should be visible within this instantiation.
5501e5dd7070Spatrick // FIXME: Produce diagnostics when Var->getInstantiatedFromStaticDataMember().
5502e5dd7070Spatrick if (DiagnoseUninstantiableTemplate(PointOfInstantiation, Var,
5503e5dd7070Spatrick /*InstantiatedFromMember*/false,
5504e5dd7070Spatrick PatternDecl, Def, TSK,
5505e5dd7070Spatrick /*Complain*/DefinitionRequired))
5506e5dd7070Spatrick return;
5507e5dd7070Spatrick
5508e5dd7070Spatrick // C++11 [temp.explicit]p10:
5509e5dd7070Spatrick // Except for inline functions, const variables of literal types, variables
5510e5dd7070Spatrick // of reference types, [...] explicit instantiation declarations
5511e5dd7070Spatrick // have the effect of suppressing the implicit instantiation of the entity
5512e5dd7070Spatrick // to which they refer.
5513e5dd7070Spatrick //
5514e5dd7070Spatrick // FIXME: That's not exactly the same as "might be usable in constant
5515e5dd7070Spatrick // expressions", which only allows constexpr variables and const integral
5516e5dd7070Spatrick // types, not arbitrary const literal types.
5517e5dd7070Spatrick if (TSK == TSK_ExplicitInstantiationDeclaration &&
5518e5dd7070Spatrick !Var->mightBeUsableInConstantExpressions(getASTContext()))
5519e5dd7070Spatrick return;
5520e5dd7070Spatrick
5521e5dd7070Spatrick // Make sure to pass the instantiated variable to the consumer at the end.
5522e5dd7070Spatrick struct PassToConsumerRAII {
5523e5dd7070Spatrick ASTConsumer &Consumer;
5524e5dd7070Spatrick VarDecl *Var;
5525e5dd7070Spatrick
5526e5dd7070Spatrick PassToConsumerRAII(ASTConsumer &Consumer, VarDecl *Var)
5527e5dd7070Spatrick : Consumer(Consumer), Var(Var) { }
5528e5dd7070Spatrick
5529e5dd7070Spatrick ~PassToConsumerRAII() {
5530e5dd7070Spatrick Consumer.HandleCXXStaticMemberVarInstantiation(Var);
5531e5dd7070Spatrick }
5532e5dd7070Spatrick } PassToConsumerRAII(Consumer, Var);
5533e5dd7070Spatrick
5534e5dd7070Spatrick // If we already have a definition, we're done.
5535e5dd7070Spatrick if (VarDecl *Def = Var->getDefinition()) {
5536e5dd7070Spatrick // We may be explicitly instantiating something we've already implicitly
5537e5dd7070Spatrick // instantiated.
5538e5dd7070Spatrick Def->setTemplateSpecializationKind(Var->getTemplateSpecializationKind(),
5539e5dd7070Spatrick PointOfInstantiation);
5540e5dd7070Spatrick return;
5541e5dd7070Spatrick }
5542e5dd7070Spatrick
5543e5dd7070Spatrick InstantiatingTemplate Inst(*this, PointOfInstantiation, Var);
5544e5dd7070Spatrick if (Inst.isInvalid() || Inst.isAlreadyInstantiating())
5545e5dd7070Spatrick return;
5546e5dd7070Spatrick PrettyDeclStackTraceEntry CrashInfo(Context, Var, SourceLocation(),
5547e5dd7070Spatrick "instantiating variable definition");
5548e5dd7070Spatrick
5549e5dd7070Spatrick // If we're performing recursive template instantiation, create our own
5550e5dd7070Spatrick // queue of pending implicit instantiations that we will instantiate later,
5551e5dd7070Spatrick // while we're still within our own instantiation context.
5552e5dd7070Spatrick GlobalEagerInstantiationScope GlobalInstantiations(*this,
5553e5dd7070Spatrick /*Enabled=*/Recursive);
5554e5dd7070Spatrick
5555e5dd7070Spatrick // Enter the scope of this instantiation. We don't use
5556e5dd7070Spatrick // PushDeclContext because we don't have a scope.
5557e5dd7070Spatrick ContextRAII PreviousContext(*this, Var->getDeclContext());
5558e5dd7070Spatrick LocalInstantiationScope Local(*this);
5559e5dd7070Spatrick
5560e5dd7070Spatrick LocalEagerInstantiationScope LocalInstantiations(*this);
5561e5dd7070Spatrick
5562e5dd7070Spatrick VarDecl *OldVar = Var;
5563e5dd7070Spatrick if (Def->isStaticDataMember() && !Def->isOutOfLine()) {
5564e5dd7070Spatrick // We're instantiating an inline static data member whose definition was
5565e5dd7070Spatrick // provided inside the class.
5566e5dd7070Spatrick InstantiateVariableInitializer(Var, Def, TemplateArgs);
5567e5dd7070Spatrick } else if (!VarSpec) {
5568e5dd7070Spatrick Var = cast_or_null<VarDecl>(SubstDecl(Def, Var->getDeclContext(),
5569e5dd7070Spatrick TemplateArgs));
5570e5dd7070Spatrick } else if (Var->isStaticDataMember() &&
5571e5dd7070Spatrick Var->getLexicalDeclContext()->isRecord()) {
5572e5dd7070Spatrick // We need to instantiate the definition of a static data member template,
5573e5dd7070Spatrick // and all we have is the in-class declaration of it. Instantiate a separate
5574e5dd7070Spatrick // declaration of the definition.
5575e5dd7070Spatrick TemplateDeclInstantiator Instantiator(*this, Var->getDeclContext(),
5576e5dd7070Spatrick TemplateArgs);
5577*12c85518Srobert
5578*12c85518Srobert TemplateArgumentListInfo TemplateArgInfo;
5579*12c85518Srobert if (const ASTTemplateArgumentListInfo *ArgInfo =
5580*12c85518Srobert VarSpec->getTemplateArgsInfo()) {
5581*12c85518Srobert TemplateArgInfo.setLAngleLoc(ArgInfo->getLAngleLoc());
5582*12c85518Srobert TemplateArgInfo.setRAngleLoc(ArgInfo->getRAngleLoc());
5583*12c85518Srobert for (const TemplateArgumentLoc &Arg : ArgInfo->arguments())
5584*12c85518Srobert TemplateArgInfo.addArgument(Arg);
5585*12c85518Srobert }
5586*12c85518Srobert
5587e5dd7070Spatrick Var = cast_or_null<VarDecl>(Instantiator.VisitVarTemplateSpecializationDecl(
5588*12c85518Srobert VarSpec->getSpecializedTemplate(), Def, TemplateArgInfo,
5589a9ac8606Spatrick VarSpec->getTemplateArgs().asArray(), VarSpec));
5590e5dd7070Spatrick if (Var) {
5591e5dd7070Spatrick llvm::PointerUnion<VarTemplateDecl *,
5592e5dd7070Spatrick VarTemplatePartialSpecializationDecl *> PatternPtr =
5593e5dd7070Spatrick VarSpec->getSpecializedTemplateOrPartial();
5594e5dd7070Spatrick if (VarTemplatePartialSpecializationDecl *Partial =
5595e5dd7070Spatrick PatternPtr.dyn_cast<VarTemplatePartialSpecializationDecl *>())
5596e5dd7070Spatrick cast<VarTemplateSpecializationDecl>(Var)->setInstantiationOf(
5597e5dd7070Spatrick Partial, &VarSpec->getTemplateInstantiationArgs());
5598e5dd7070Spatrick
5599e5dd7070Spatrick // Attach the initializer.
5600e5dd7070Spatrick InstantiateVariableInitializer(Var, Def, TemplateArgs);
5601e5dd7070Spatrick }
5602e5dd7070Spatrick } else
5603e5dd7070Spatrick // Complete the existing variable's definition with an appropriately
5604e5dd7070Spatrick // substituted type and initializer.
5605e5dd7070Spatrick Var = CompleteVarTemplateSpecializationDecl(VarSpec, Def, TemplateArgs);
5606e5dd7070Spatrick
5607e5dd7070Spatrick PreviousContext.pop();
5608e5dd7070Spatrick
5609e5dd7070Spatrick if (Var) {
5610e5dd7070Spatrick PassToConsumerRAII.Var = Var;
5611e5dd7070Spatrick Var->setTemplateSpecializationKind(OldVar->getTemplateSpecializationKind(),
5612e5dd7070Spatrick OldVar->getPointOfInstantiation());
5613e5dd7070Spatrick }
5614e5dd7070Spatrick
5615e5dd7070Spatrick // This variable may have local implicit instantiations that need to be
5616e5dd7070Spatrick // instantiated within this scope.
5617e5dd7070Spatrick LocalInstantiations.perform();
5618e5dd7070Spatrick Local.Exit();
5619e5dd7070Spatrick GlobalInstantiations.perform();
5620e5dd7070Spatrick }
5621e5dd7070Spatrick
5622e5dd7070Spatrick void
InstantiateMemInitializers(CXXConstructorDecl * New,const CXXConstructorDecl * Tmpl,const MultiLevelTemplateArgumentList & TemplateArgs)5623e5dd7070Spatrick Sema::InstantiateMemInitializers(CXXConstructorDecl *New,
5624e5dd7070Spatrick const CXXConstructorDecl *Tmpl,
5625e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs) {
5626e5dd7070Spatrick
5627e5dd7070Spatrick SmallVector<CXXCtorInitializer*, 4> NewInits;
5628e5dd7070Spatrick bool AnyErrors = Tmpl->isInvalidDecl();
5629e5dd7070Spatrick
5630e5dd7070Spatrick // Instantiate all the initializers.
5631e5dd7070Spatrick for (const auto *Init : Tmpl->inits()) {
5632e5dd7070Spatrick // Only instantiate written initializers, let Sema re-construct implicit
5633e5dd7070Spatrick // ones.
5634e5dd7070Spatrick if (!Init->isWritten())
5635e5dd7070Spatrick continue;
5636e5dd7070Spatrick
5637e5dd7070Spatrick SourceLocation EllipsisLoc;
5638e5dd7070Spatrick
5639e5dd7070Spatrick if (Init->isPackExpansion()) {
5640e5dd7070Spatrick // This is a pack expansion. We should expand it now.
5641e5dd7070Spatrick TypeLoc BaseTL = Init->getTypeSourceInfo()->getTypeLoc();
5642e5dd7070Spatrick SmallVector<UnexpandedParameterPack, 4> Unexpanded;
5643e5dd7070Spatrick collectUnexpandedParameterPacks(BaseTL, Unexpanded);
5644e5dd7070Spatrick collectUnexpandedParameterPacks(Init->getInit(), Unexpanded);
5645e5dd7070Spatrick bool ShouldExpand = false;
5646e5dd7070Spatrick bool RetainExpansion = false;
5647*12c85518Srobert std::optional<unsigned> NumExpansions;
5648e5dd7070Spatrick if (CheckParameterPacksForExpansion(Init->getEllipsisLoc(),
5649e5dd7070Spatrick BaseTL.getSourceRange(),
5650e5dd7070Spatrick Unexpanded,
5651e5dd7070Spatrick TemplateArgs, ShouldExpand,
5652e5dd7070Spatrick RetainExpansion,
5653e5dd7070Spatrick NumExpansions)) {
5654e5dd7070Spatrick AnyErrors = true;
5655e5dd7070Spatrick New->setInvalidDecl();
5656e5dd7070Spatrick continue;
5657e5dd7070Spatrick }
5658e5dd7070Spatrick assert(ShouldExpand && "Partial instantiation of base initializer?");
5659e5dd7070Spatrick
5660e5dd7070Spatrick // Loop over all of the arguments in the argument pack(s),
5661e5dd7070Spatrick for (unsigned I = 0; I != *NumExpansions; ++I) {
5662e5dd7070Spatrick Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, I);
5663e5dd7070Spatrick
5664e5dd7070Spatrick // Instantiate the initializer.
5665e5dd7070Spatrick ExprResult TempInit = SubstInitializer(Init->getInit(), TemplateArgs,
5666e5dd7070Spatrick /*CXXDirectInit=*/true);
5667e5dd7070Spatrick if (TempInit.isInvalid()) {
5668e5dd7070Spatrick AnyErrors = true;
5669e5dd7070Spatrick break;
5670e5dd7070Spatrick }
5671e5dd7070Spatrick
5672e5dd7070Spatrick // Instantiate the base type.
5673e5dd7070Spatrick TypeSourceInfo *BaseTInfo = SubstType(Init->getTypeSourceInfo(),
5674e5dd7070Spatrick TemplateArgs,
5675e5dd7070Spatrick Init->getSourceLocation(),
5676e5dd7070Spatrick New->getDeclName());
5677e5dd7070Spatrick if (!BaseTInfo) {
5678e5dd7070Spatrick AnyErrors = true;
5679e5dd7070Spatrick break;
5680e5dd7070Spatrick }
5681e5dd7070Spatrick
5682e5dd7070Spatrick // Build the initializer.
5683e5dd7070Spatrick MemInitResult NewInit = BuildBaseInitializer(BaseTInfo->getType(),
5684e5dd7070Spatrick BaseTInfo, TempInit.get(),
5685e5dd7070Spatrick New->getParent(),
5686e5dd7070Spatrick SourceLocation());
5687e5dd7070Spatrick if (NewInit.isInvalid()) {
5688e5dd7070Spatrick AnyErrors = true;
5689e5dd7070Spatrick break;
5690e5dd7070Spatrick }
5691e5dd7070Spatrick
5692e5dd7070Spatrick NewInits.push_back(NewInit.get());
5693e5dd7070Spatrick }
5694e5dd7070Spatrick
5695e5dd7070Spatrick continue;
5696e5dd7070Spatrick }
5697e5dd7070Spatrick
5698e5dd7070Spatrick // Instantiate the initializer.
5699e5dd7070Spatrick ExprResult TempInit = SubstInitializer(Init->getInit(), TemplateArgs,
5700e5dd7070Spatrick /*CXXDirectInit=*/true);
5701e5dd7070Spatrick if (TempInit.isInvalid()) {
5702e5dd7070Spatrick AnyErrors = true;
5703e5dd7070Spatrick continue;
5704e5dd7070Spatrick }
5705e5dd7070Spatrick
5706e5dd7070Spatrick MemInitResult NewInit;
5707e5dd7070Spatrick if (Init->isDelegatingInitializer() || Init->isBaseInitializer()) {
5708e5dd7070Spatrick TypeSourceInfo *TInfo = SubstType(Init->getTypeSourceInfo(),
5709e5dd7070Spatrick TemplateArgs,
5710e5dd7070Spatrick Init->getSourceLocation(),
5711e5dd7070Spatrick New->getDeclName());
5712e5dd7070Spatrick if (!TInfo) {
5713e5dd7070Spatrick AnyErrors = true;
5714e5dd7070Spatrick New->setInvalidDecl();
5715e5dd7070Spatrick continue;
5716e5dd7070Spatrick }
5717e5dd7070Spatrick
5718e5dd7070Spatrick if (Init->isBaseInitializer())
5719e5dd7070Spatrick NewInit = BuildBaseInitializer(TInfo->getType(), TInfo, TempInit.get(),
5720e5dd7070Spatrick New->getParent(), EllipsisLoc);
5721e5dd7070Spatrick else
5722e5dd7070Spatrick NewInit = BuildDelegatingInitializer(TInfo, TempInit.get(),
5723e5dd7070Spatrick cast<CXXRecordDecl>(CurContext->getParent()));
5724e5dd7070Spatrick } else if (Init->isMemberInitializer()) {
5725e5dd7070Spatrick FieldDecl *Member = cast_or_null<FieldDecl>(FindInstantiatedDecl(
5726e5dd7070Spatrick Init->getMemberLocation(),
5727e5dd7070Spatrick Init->getMember(),
5728e5dd7070Spatrick TemplateArgs));
5729e5dd7070Spatrick if (!Member) {
5730e5dd7070Spatrick AnyErrors = true;
5731e5dd7070Spatrick New->setInvalidDecl();
5732e5dd7070Spatrick continue;
5733e5dd7070Spatrick }
5734e5dd7070Spatrick
5735e5dd7070Spatrick NewInit = BuildMemberInitializer(Member, TempInit.get(),
5736e5dd7070Spatrick Init->getSourceLocation());
5737e5dd7070Spatrick } else if (Init->isIndirectMemberInitializer()) {
5738e5dd7070Spatrick IndirectFieldDecl *IndirectMember =
5739e5dd7070Spatrick cast_or_null<IndirectFieldDecl>(FindInstantiatedDecl(
5740e5dd7070Spatrick Init->getMemberLocation(),
5741e5dd7070Spatrick Init->getIndirectMember(), TemplateArgs));
5742e5dd7070Spatrick
5743e5dd7070Spatrick if (!IndirectMember) {
5744e5dd7070Spatrick AnyErrors = true;
5745e5dd7070Spatrick New->setInvalidDecl();
5746e5dd7070Spatrick continue;
5747e5dd7070Spatrick }
5748e5dd7070Spatrick
5749e5dd7070Spatrick NewInit = BuildMemberInitializer(IndirectMember, TempInit.get(),
5750e5dd7070Spatrick Init->getSourceLocation());
5751e5dd7070Spatrick }
5752e5dd7070Spatrick
5753e5dd7070Spatrick if (NewInit.isInvalid()) {
5754e5dd7070Spatrick AnyErrors = true;
5755e5dd7070Spatrick New->setInvalidDecl();
5756e5dd7070Spatrick } else {
5757e5dd7070Spatrick NewInits.push_back(NewInit.get());
5758e5dd7070Spatrick }
5759e5dd7070Spatrick }
5760e5dd7070Spatrick
5761e5dd7070Spatrick // Assign all the initializers to the new constructor.
5762e5dd7070Spatrick ActOnMemInitializers(New,
5763e5dd7070Spatrick /*FIXME: ColonLoc */
5764e5dd7070Spatrick SourceLocation(),
5765e5dd7070Spatrick NewInits,
5766e5dd7070Spatrick AnyErrors);
5767e5dd7070Spatrick }
5768e5dd7070Spatrick
5769e5dd7070Spatrick // TODO: this could be templated if the various decl types used the
5770e5dd7070Spatrick // same method name.
isInstantiationOf(ClassTemplateDecl * Pattern,ClassTemplateDecl * Instance)5771e5dd7070Spatrick static bool isInstantiationOf(ClassTemplateDecl *Pattern,
5772e5dd7070Spatrick ClassTemplateDecl *Instance) {
5773e5dd7070Spatrick Pattern = Pattern->getCanonicalDecl();
5774e5dd7070Spatrick
5775e5dd7070Spatrick do {
5776e5dd7070Spatrick Instance = Instance->getCanonicalDecl();
5777e5dd7070Spatrick if (Pattern == Instance) return true;
5778e5dd7070Spatrick Instance = Instance->getInstantiatedFromMemberTemplate();
5779e5dd7070Spatrick } while (Instance);
5780e5dd7070Spatrick
5781e5dd7070Spatrick return false;
5782e5dd7070Spatrick }
5783e5dd7070Spatrick
isInstantiationOf(FunctionTemplateDecl * Pattern,FunctionTemplateDecl * Instance)5784e5dd7070Spatrick static bool isInstantiationOf(FunctionTemplateDecl *Pattern,
5785e5dd7070Spatrick FunctionTemplateDecl *Instance) {
5786e5dd7070Spatrick Pattern = Pattern->getCanonicalDecl();
5787e5dd7070Spatrick
5788e5dd7070Spatrick do {
5789e5dd7070Spatrick Instance = Instance->getCanonicalDecl();
5790e5dd7070Spatrick if (Pattern == Instance) return true;
5791e5dd7070Spatrick Instance = Instance->getInstantiatedFromMemberTemplate();
5792e5dd7070Spatrick } while (Instance);
5793e5dd7070Spatrick
5794e5dd7070Spatrick return false;
5795e5dd7070Spatrick }
5796e5dd7070Spatrick
5797e5dd7070Spatrick static bool
isInstantiationOf(ClassTemplatePartialSpecializationDecl * Pattern,ClassTemplatePartialSpecializationDecl * Instance)5798e5dd7070Spatrick isInstantiationOf(ClassTemplatePartialSpecializationDecl *Pattern,
5799e5dd7070Spatrick ClassTemplatePartialSpecializationDecl *Instance) {
5800e5dd7070Spatrick Pattern
5801e5dd7070Spatrick = cast<ClassTemplatePartialSpecializationDecl>(Pattern->getCanonicalDecl());
5802e5dd7070Spatrick do {
5803e5dd7070Spatrick Instance = cast<ClassTemplatePartialSpecializationDecl>(
5804e5dd7070Spatrick Instance->getCanonicalDecl());
5805e5dd7070Spatrick if (Pattern == Instance)
5806e5dd7070Spatrick return true;
5807e5dd7070Spatrick Instance = Instance->getInstantiatedFromMember();
5808e5dd7070Spatrick } while (Instance);
5809e5dd7070Spatrick
5810e5dd7070Spatrick return false;
5811e5dd7070Spatrick }
5812e5dd7070Spatrick
isInstantiationOf(CXXRecordDecl * Pattern,CXXRecordDecl * Instance)5813e5dd7070Spatrick static bool isInstantiationOf(CXXRecordDecl *Pattern,
5814e5dd7070Spatrick CXXRecordDecl *Instance) {
5815e5dd7070Spatrick Pattern = Pattern->getCanonicalDecl();
5816e5dd7070Spatrick
5817e5dd7070Spatrick do {
5818e5dd7070Spatrick Instance = Instance->getCanonicalDecl();
5819e5dd7070Spatrick if (Pattern == Instance) return true;
5820e5dd7070Spatrick Instance = Instance->getInstantiatedFromMemberClass();
5821e5dd7070Spatrick } while (Instance);
5822e5dd7070Spatrick
5823e5dd7070Spatrick return false;
5824e5dd7070Spatrick }
5825e5dd7070Spatrick
isInstantiationOf(FunctionDecl * Pattern,FunctionDecl * Instance)5826e5dd7070Spatrick static bool isInstantiationOf(FunctionDecl *Pattern,
5827e5dd7070Spatrick FunctionDecl *Instance) {
5828e5dd7070Spatrick Pattern = Pattern->getCanonicalDecl();
5829e5dd7070Spatrick
5830e5dd7070Spatrick do {
5831e5dd7070Spatrick Instance = Instance->getCanonicalDecl();
5832e5dd7070Spatrick if (Pattern == Instance) return true;
5833e5dd7070Spatrick Instance = Instance->getInstantiatedFromMemberFunction();
5834e5dd7070Spatrick } while (Instance);
5835e5dd7070Spatrick
5836e5dd7070Spatrick return false;
5837e5dd7070Spatrick }
5838e5dd7070Spatrick
isInstantiationOf(EnumDecl * Pattern,EnumDecl * Instance)5839e5dd7070Spatrick static bool isInstantiationOf(EnumDecl *Pattern,
5840e5dd7070Spatrick EnumDecl *Instance) {
5841e5dd7070Spatrick Pattern = Pattern->getCanonicalDecl();
5842e5dd7070Spatrick
5843e5dd7070Spatrick do {
5844e5dd7070Spatrick Instance = Instance->getCanonicalDecl();
5845e5dd7070Spatrick if (Pattern == Instance) return true;
5846e5dd7070Spatrick Instance = Instance->getInstantiatedFromMemberEnum();
5847e5dd7070Spatrick } while (Instance);
5848e5dd7070Spatrick
5849e5dd7070Spatrick return false;
5850e5dd7070Spatrick }
5851e5dd7070Spatrick
isInstantiationOf(UsingShadowDecl * Pattern,UsingShadowDecl * Instance,ASTContext & C)5852e5dd7070Spatrick static bool isInstantiationOf(UsingShadowDecl *Pattern,
5853e5dd7070Spatrick UsingShadowDecl *Instance,
5854e5dd7070Spatrick ASTContext &C) {
5855e5dd7070Spatrick return declaresSameEntity(C.getInstantiatedFromUsingShadowDecl(Instance),
5856e5dd7070Spatrick Pattern);
5857e5dd7070Spatrick }
5858e5dd7070Spatrick
isInstantiationOf(UsingDecl * Pattern,UsingDecl * Instance,ASTContext & C)5859e5dd7070Spatrick static bool isInstantiationOf(UsingDecl *Pattern, UsingDecl *Instance,
5860e5dd7070Spatrick ASTContext &C) {
5861e5dd7070Spatrick return declaresSameEntity(C.getInstantiatedFromUsingDecl(Instance), Pattern);
5862e5dd7070Spatrick }
5863e5dd7070Spatrick
5864e5dd7070Spatrick template<typename T>
isInstantiationOfUnresolvedUsingDecl(T * Pattern,Decl * Other,ASTContext & Ctx)5865e5dd7070Spatrick static bool isInstantiationOfUnresolvedUsingDecl(T *Pattern, Decl *Other,
5866e5dd7070Spatrick ASTContext &Ctx) {
5867e5dd7070Spatrick // An unresolved using declaration can instantiate to an unresolved using
5868e5dd7070Spatrick // declaration, or to a using declaration or a using declaration pack.
5869e5dd7070Spatrick //
5870e5dd7070Spatrick // Multiple declarations can claim to be instantiated from an unresolved
5871e5dd7070Spatrick // using declaration if it's a pack expansion. We want the UsingPackDecl
5872e5dd7070Spatrick // in that case, not the individual UsingDecls within the pack.
5873e5dd7070Spatrick bool OtherIsPackExpansion;
5874e5dd7070Spatrick NamedDecl *OtherFrom;
5875e5dd7070Spatrick if (auto *OtherUUD = dyn_cast<T>(Other)) {
5876e5dd7070Spatrick OtherIsPackExpansion = OtherUUD->isPackExpansion();
5877e5dd7070Spatrick OtherFrom = Ctx.getInstantiatedFromUsingDecl(OtherUUD);
5878e5dd7070Spatrick } else if (auto *OtherUPD = dyn_cast<UsingPackDecl>(Other)) {
5879e5dd7070Spatrick OtherIsPackExpansion = true;
5880e5dd7070Spatrick OtherFrom = OtherUPD->getInstantiatedFromUsingDecl();
5881e5dd7070Spatrick } else if (auto *OtherUD = dyn_cast<UsingDecl>(Other)) {
5882e5dd7070Spatrick OtherIsPackExpansion = false;
5883e5dd7070Spatrick OtherFrom = Ctx.getInstantiatedFromUsingDecl(OtherUD);
5884e5dd7070Spatrick } else {
5885e5dd7070Spatrick return false;
5886e5dd7070Spatrick }
5887e5dd7070Spatrick return Pattern->isPackExpansion() == OtherIsPackExpansion &&
5888e5dd7070Spatrick declaresSameEntity(OtherFrom, Pattern);
5889e5dd7070Spatrick }
5890e5dd7070Spatrick
isInstantiationOfStaticDataMember(VarDecl * Pattern,VarDecl * Instance)5891e5dd7070Spatrick static bool isInstantiationOfStaticDataMember(VarDecl *Pattern,
5892e5dd7070Spatrick VarDecl *Instance) {
5893e5dd7070Spatrick assert(Instance->isStaticDataMember());
5894e5dd7070Spatrick
5895e5dd7070Spatrick Pattern = Pattern->getCanonicalDecl();
5896e5dd7070Spatrick
5897e5dd7070Spatrick do {
5898e5dd7070Spatrick Instance = Instance->getCanonicalDecl();
5899e5dd7070Spatrick if (Pattern == Instance) return true;
5900e5dd7070Spatrick Instance = Instance->getInstantiatedFromStaticDataMember();
5901e5dd7070Spatrick } while (Instance);
5902e5dd7070Spatrick
5903e5dd7070Spatrick return false;
5904e5dd7070Spatrick }
5905e5dd7070Spatrick
5906e5dd7070Spatrick // Other is the prospective instantiation
5907e5dd7070Spatrick // D is the prospective pattern
isInstantiationOf(ASTContext & Ctx,NamedDecl * D,Decl * Other)5908e5dd7070Spatrick static bool isInstantiationOf(ASTContext &Ctx, NamedDecl *D, Decl *Other) {
5909e5dd7070Spatrick if (auto *UUD = dyn_cast<UnresolvedUsingTypenameDecl>(D))
5910e5dd7070Spatrick return isInstantiationOfUnresolvedUsingDecl(UUD, Other, Ctx);
5911e5dd7070Spatrick
5912e5dd7070Spatrick if (auto *UUD = dyn_cast<UnresolvedUsingValueDecl>(D))
5913e5dd7070Spatrick return isInstantiationOfUnresolvedUsingDecl(UUD, Other, Ctx);
5914e5dd7070Spatrick
5915e5dd7070Spatrick if (D->getKind() != Other->getKind())
5916e5dd7070Spatrick return false;
5917e5dd7070Spatrick
5918e5dd7070Spatrick if (auto *Record = dyn_cast<CXXRecordDecl>(Other))
5919e5dd7070Spatrick return isInstantiationOf(cast<CXXRecordDecl>(D), Record);
5920e5dd7070Spatrick
5921e5dd7070Spatrick if (auto *Function = dyn_cast<FunctionDecl>(Other))
5922e5dd7070Spatrick return isInstantiationOf(cast<FunctionDecl>(D), Function);
5923e5dd7070Spatrick
5924e5dd7070Spatrick if (auto *Enum = dyn_cast<EnumDecl>(Other))
5925e5dd7070Spatrick return isInstantiationOf(cast<EnumDecl>(D), Enum);
5926e5dd7070Spatrick
5927e5dd7070Spatrick if (auto *Var = dyn_cast<VarDecl>(Other))
5928e5dd7070Spatrick if (Var->isStaticDataMember())
5929e5dd7070Spatrick return isInstantiationOfStaticDataMember(cast<VarDecl>(D), Var);
5930e5dd7070Spatrick
5931e5dd7070Spatrick if (auto *Temp = dyn_cast<ClassTemplateDecl>(Other))
5932e5dd7070Spatrick return isInstantiationOf(cast<ClassTemplateDecl>(D), Temp);
5933e5dd7070Spatrick
5934e5dd7070Spatrick if (auto *Temp = dyn_cast<FunctionTemplateDecl>(Other))
5935e5dd7070Spatrick return isInstantiationOf(cast<FunctionTemplateDecl>(D), Temp);
5936e5dd7070Spatrick
5937e5dd7070Spatrick if (auto *PartialSpec =
5938e5dd7070Spatrick dyn_cast<ClassTemplatePartialSpecializationDecl>(Other))
5939e5dd7070Spatrick return isInstantiationOf(cast<ClassTemplatePartialSpecializationDecl>(D),
5940e5dd7070Spatrick PartialSpec);
5941e5dd7070Spatrick
5942e5dd7070Spatrick if (auto *Field = dyn_cast<FieldDecl>(Other)) {
5943e5dd7070Spatrick if (!Field->getDeclName()) {
5944e5dd7070Spatrick // This is an unnamed field.
5945e5dd7070Spatrick return declaresSameEntity(Ctx.getInstantiatedFromUnnamedFieldDecl(Field),
5946e5dd7070Spatrick cast<FieldDecl>(D));
5947e5dd7070Spatrick }
5948e5dd7070Spatrick }
5949e5dd7070Spatrick
5950e5dd7070Spatrick if (auto *Using = dyn_cast<UsingDecl>(Other))
5951e5dd7070Spatrick return isInstantiationOf(cast<UsingDecl>(D), Using, Ctx);
5952e5dd7070Spatrick
5953e5dd7070Spatrick if (auto *Shadow = dyn_cast<UsingShadowDecl>(Other))
5954e5dd7070Spatrick return isInstantiationOf(cast<UsingShadowDecl>(D), Shadow, Ctx);
5955e5dd7070Spatrick
5956e5dd7070Spatrick return D->getDeclName() &&
5957e5dd7070Spatrick D->getDeclName() == cast<NamedDecl>(Other)->getDeclName();
5958e5dd7070Spatrick }
5959e5dd7070Spatrick
5960e5dd7070Spatrick template<typename ForwardIterator>
findInstantiationOf(ASTContext & Ctx,NamedDecl * D,ForwardIterator first,ForwardIterator last)5961e5dd7070Spatrick static NamedDecl *findInstantiationOf(ASTContext &Ctx,
5962e5dd7070Spatrick NamedDecl *D,
5963e5dd7070Spatrick ForwardIterator first,
5964e5dd7070Spatrick ForwardIterator last) {
5965e5dd7070Spatrick for (; first != last; ++first)
5966e5dd7070Spatrick if (isInstantiationOf(Ctx, D, *first))
5967e5dd7070Spatrick return cast<NamedDecl>(*first);
5968e5dd7070Spatrick
5969e5dd7070Spatrick return nullptr;
5970e5dd7070Spatrick }
5971e5dd7070Spatrick
5972e5dd7070Spatrick /// Finds the instantiation of the given declaration context
5973e5dd7070Spatrick /// within the current instantiation.
5974e5dd7070Spatrick ///
5975e5dd7070Spatrick /// \returns NULL if there was an error
FindInstantiatedContext(SourceLocation Loc,DeclContext * DC,const MultiLevelTemplateArgumentList & TemplateArgs)5976e5dd7070Spatrick DeclContext *Sema::FindInstantiatedContext(SourceLocation Loc, DeclContext* DC,
5977e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs) {
5978e5dd7070Spatrick if (NamedDecl *D = dyn_cast<NamedDecl>(DC)) {
5979e5dd7070Spatrick Decl* ID = FindInstantiatedDecl(Loc, D, TemplateArgs, true);
5980e5dd7070Spatrick return cast_or_null<DeclContext>(ID);
5981e5dd7070Spatrick } else return DC;
5982e5dd7070Spatrick }
5983e5dd7070Spatrick
5984ec727ea7Spatrick /// Determine whether the given context is dependent on template parameters at
5985ec727ea7Spatrick /// level \p Level or below.
5986ec727ea7Spatrick ///
5987ec727ea7Spatrick /// Sometimes we only substitute an inner set of template arguments and leave
5988ec727ea7Spatrick /// the outer templates alone. In such cases, contexts dependent only on the
5989ec727ea7Spatrick /// outer levels are not effectively dependent.
isDependentContextAtLevel(DeclContext * DC,unsigned Level)5990ec727ea7Spatrick static bool isDependentContextAtLevel(DeclContext *DC, unsigned Level) {
5991ec727ea7Spatrick if (!DC->isDependentContext())
5992ec727ea7Spatrick return false;
5993ec727ea7Spatrick if (!Level)
5994ec727ea7Spatrick return true;
5995ec727ea7Spatrick return cast<Decl>(DC)->getTemplateDepth() > Level;
5996ec727ea7Spatrick }
5997ec727ea7Spatrick
5998e5dd7070Spatrick /// Find the instantiation of the given declaration within the
5999e5dd7070Spatrick /// current instantiation.
6000e5dd7070Spatrick ///
6001e5dd7070Spatrick /// This routine is intended to be used when \p D is a declaration
6002e5dd7070Spatrick /// referenced from within a template, that needs to mapped into the
6003e5dd7070Spatrick /// corresponding declaration within an instantiation. For example,
6004e5dd7070Spatrick /// given:
6005e5dd7070Spatrick ///
6006e5dd7070Spatrick /// \code
6007e5dd7070Spatrick /// template<typename T>
6008e5dd7070Spatrick /// struct X {
6009e5dd7070Spatrick /// enum Kind {
6010e5dd7070Spatrick /// KnownValue = sizeof(T)
6011e5dd7070Spatrick /// };
6012e5dd7070Spatrick ///
6013e5dd7070Spatrick /// bool getKind() const { return KnownValue; }
6014e5dd7070Spatrick /// };
6015e5dd7070Spatrick ///
6016e5dd7070Spatrick /// template struct X<int>;
6017e5dd7070Spatrick /// \endcode
6018e5dd7070Spatrick ///
6019e5dd7070Spatrick /// In the instantiation of X<int>::getKind(), we need to map the \p
6020e5dd7070Spatrick /// EnumConstantDecl for \p KnownValue (which refers to
6021e5dd7070Spatrick /// X<T>::<Kind>::KnownValue) to its instantiation (X<int>::<Kind>::KnownValue).
6022e5dd7070Spatrick /// \p FindInstantiatedDecl performs this mapping from within the instantiation
6023e5dd7070Spatrick /// of X<int>.
FindInstantiatedDecl(SourceLocation Loc,NamedDecl * D,const MultiLevelTemplateArgumentList & TemplateArgs,bool FindingInstantiatedContext)6024e5dd7070Spatrick NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
6025e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs,
6026e5dd7070Spatrick bool FindingInstantiatedContext) {
6027e5dd7070Spatrick DeclContext *ParentDC = D->getDeclContext();
6028*12c85518Srobert // Determine whether our parent context depends on any of the template
6029ec727ea7Spatrick // arguments we're currently substituting.
6030ec727ea7Spatrick bool ParentDependsOnArgs = isDependentContextAtLevel(
6031ec727ea7Spatrick ParentDC, TemplateArgs.getNumRetainedOuterLevels());
6032*12c85518Srobert // FIXME: Parameters of pointer to functions (y below) that are themselves
6033e5dd7070Spatrick // parameters (p below) can have their ParentDC set to the translation-unit
6034e5dd7070Spatrick // - thus we can not consistently check if the ParentDC of such a parameter
6035e5dd7070Spatrick // is Dependent or/and a FunctionOrMethod.
6036e5dd7070Spatrick // For e.g. this code, during Template argument deduction tries to
6037e5dd7070Spatrick // find an instantiated decl for (T y) when the ParentDC for y is
6038e5dd7070Spatrick // the translation unit.
6039e5dd7070Spatrick // e.g. template <class T> void Foo(auto (*p)(T y) -> decltype(y())) {}
6040e5dd7070Spatrick // float baz(float(*)()) { return 0.0; }
6041e5dd7070Spatrick // Foo(baz);
6042e5dd7070Spatrick // The better fix here is perhaps to ensure that a ParmVarDecl, by the time
6043e5dd7070Spatrick // it gets here, always has a FunctionOrMethod as its ParentDC??
6044e5dd7070Spatrick // For now:
6045e5dd7070Spatrick // - as long as we have a ParmVarDecl whose parent is non-dependent and
6046e5dd7070Spatrick // whose type is not instantiation dependent, do nothing to the decl
6047e5dd7070Spatrick // - otherwise find its instantiated decl.
6048ec727ea7Spatrick if (isa<ParmVarDecl>(D) && !ParentDependsOnArgs &&
6049e5dd7070Spatrick !cast<ParmVarDecl>(D)->getType()->isInstantiationDependentType())
6050e5dd7070Spatrick return D;
6051e5dd7070Spatrick if (isa<ParmVarDecl>(D) || isa<NonTypeTemplateParmDecl>(D) ||
6052e5dd7070Spatrick isa<TemplateTypeParmDecl>(D) || isa<TemplateTemplateParmDecl>(D) ||
6053ec727ea7Spatrick (ParentDependsOnArgs && (ParentDC->isFunctionOrMethod() ||
6054e5dd7070Spatrick isa<OMPDeclareReductionDecl>(ParentDC) ||
6055ec727ea7Spatrick isa<OMPDeclareMapperDecl>(ParentDC))) ||
6056*12c85518Srobert (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda() &&
6057*12c85518Srobert cast<CXXRecordDecl>(D)->getTemplateDepth() >
6058*12c85518Srobert TemplateArgs.getNumRetainedOuterLevels())) {
6059e5dd7070Spatrick // D is a local of some kind. Look into the map of local
6060e5dd7070Spatrick // declarations to their instantiations.
6061e5dd7070Spatrick if (CurrentInstantiationScope) {
6062e5dd7070Spatrick if (auto Found = CurrentInstantiationScope->findInstantiationOf(D)) {
6063e5dd7070Spatrick if (Decl *FD = Found->dyn_cast<Decl *>())
6064e5dd7070Spatrick return cast<NamedDecl>(FD);
6065e5dd7070Spatrick
6066e5dd7070Spatrick int PackIdx = ArgumentPackSubstitutionIndex;
6067e5dd7070Spatrick assert(PackIdx != -1 &&
6068e5dd7070Spatrick "found declaration pack but not pack expanding");
6069e5dd7070Spatrick typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
6070e5dd7070Spatrick return cast<NamedDecl>((*Found->get<DeclArgumentPack *>())[PackIdx]);
6071e5dd7070Spatrick }
6072e5dd7070Spatrick }
6073e5dd7070Spatrick
6074e5dd7070Spatrick // If we're performing a partial substitution during template argument
6075e5dd7070Spatrick // deduction, we may not have values for template parameters yet. They
6076e5dd7070Spatrick // just map to themselves.
6077e5dd7070Spatrick if (isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D) ||
6078e5dd7070Spatrick isa<TemplateTemplateParmDecl>(D))
6079e5dd7070Spatrick return D;
6080e5dd7070Spatrick
6081e5dd7070Spatrick if (D->isInvalidDecl())
6082e5dd7070Spatrick return nullptr;
6083e5dd7070Spatrick
6084e5dd7070Spatrick // Normally this function only searches for already instantiated declaration
6085e5dd7070Spatrick // however we have to make an exclusion for local types used before
6086e5dd7070Spatrick // definition as in the code:
6087e5dd7070Spatrick //
6088e5dd7070Spatrick // template<typename T> void f1() {
6089e5dd7070Spatrick // void g1(struct x1);
6090e5dd7070Spatrick // struct x1 {};
6091e5dd7070Spatrick // }
6092e5dd7070Spatrick //
6093e5dd7070Spatrick // In this case instantiation of the type of 'g1' requires definition of
6094e5dd7070Spatrick // 'x1', which is defined later. Error recovery may produce an enum used
6095e5dd7070Spatrick // before definition. In these cases we need to instantiate relevant
6096e5dd7070Spatrick // declarations here.
6097e5dd7070Spatrick bool NeedInstantiate = false;
6098e5dd7070Spatrick if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
6099e5dd7070Spatrick NeedInstantiate = RD->isLocalClass();
6100ec727ea7Spatrick else if (isa<TypedefNameDecl>(D) &&
6101ec727ea7Spatrick isa<CXXDeductionGuideDecl>(D->getDeclContext()))
6102ec727ea7Spatrick NeedInstantiate = true;
6103e5dd7070Spatrick else
6104e5dd7070Spatrick NeedInstantiate = isa<EnumDecl>(D);
6105e5dd7070Spatrick if (NeedInstantiate) {
6106e5dd7070Spatrick Decl *Inst = SubstDecl(D, CurContext, TemplateArgs);
6107e5dd7070Spatrick CurrentInstantiationScope->InstantiatedLocal(D, Inst);
6108e5dd7070Spatrick return cast<TypeDecl>(Inst);
6109e5dd7070Spatrick }
6110e5dd7070Spatrick
6111e5dd7070Spatrick // If we didn't find the decl, then we must have a label decl that hasn't
6112e5dd7070Spatrick // been found yet. Lazily instantiate it and return it now.
6113e5dd7070Spatrick assert(isa<LabelDecl>(D));
6114e5dd7070Spatrick
6115e5dd7070Spatrick Decl *Inst = SubstDecl(D, CurContext, TemplateArgs);
6116e5dd7070Spatrick assert(Inst && "Failed to instantiate label??");
6117e5dd7070Spatrick
6118e5dd7070Spatrick CurrentInstantiationScope->InstantiatedLocal(D, Inst);
6119e5dd7070Spatrick return cast<LabelDecl>(Inst);
6120e5dd7070Spatrick }
6121e5dd7070Spatrick
6122e5dd7070Spatrick if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) {
6123e5dd7070Spatrick if (!Record->isDependentContext())
6124e5dd7070Spatrick return D;
6125e5dd7070Spatrick
6126e5dd7070Spatrick // Determine whether this record is the "templated" declaration describing
6127e5dd7070Spatrick // a class template or class template partial specialization.
6128e5dd7070Spatrick ClassTemplateDecl *ClassTemplate = Record->getDescribedClassTemplate();
6129e5dd7070Spatrick if (ClassTemplate)
6130e5dd7070Spatrick ClassTemplate = ClassTemplate->getCanonicalDecl();
6131e5dd7070Spatrick else if (ClassTemplatePartialSpecializationDecl *PartialSpec
6132e5dd7070Spatrick = dyn_cast<ClassTemplatePartialSpecializationDecl>(Record))
6133e5dd7070Spatrick ClassTemplate = PartialSpec->getSpecializedTemplate()->getCanonicalDecl();
6134e5dd7070Spatrick
6135e5dd7070Spatrick // Walk the current context to find either the record or an instantiation of
6136e5dd7070Spatrick // it.
6137e5dd7070Spatrick DeclContext *DC = CurContext;
6138e5dd7070Spatrick while (!DC->isFileContext()) {
6139e5dd7070Spatrick // If we're performing substitution while we're inside the template
6140e5dd7070Spatrick // definition, we'll find our own context. We're done.
6141e5dd7070Spatrick if (DC->Equals(Record))
6142e5dd7070Spatrick return Record;
6143e5dd7070Spatrick
6144e5dd7070Spatrick if (CXXRecordDecl *InstRecord = dyn_cast<CXXRecordDecl>(DC)) {
6145e5dd7070Spatrick // Check whether we're in the process of instantiating a class template
6146e5dd7070Spatrick // specialization of the template we're mapping.
6147e5dd7070Spatrick if (ClassTemplateSpecializationDecl *InstSpec
6148e5dd7070Spatrick = dyn_cast<ClassTemplateSpecializationDecl>(InstRecord)){
6149e5dd7070Spatrick ClassTemplateDecl *SpecTemplate = InstSpec->getSpecializedTemplate();
6150e5dd7070Spatrick if (ClassTemplate && isInstantiationOf(ClassTemplate, SpecTemplate))
6151e5dd7070Spatrick return InstRecord;
6152e5dd7070Spatrick }
6153e5dd7070Spatrick
6154e5dd7070Spatrick // Check whether we're in the process of instantiating a member class.
6155e5dd7070Spatrick if (isInstantiationOf(Record, InstRecord))
6156e5dd7070Spatrick return InstRecord;
6157e5dd7070Spatrick }
6158e5dd7070Spatrick
6159e5dd7070Spatrick // Move to the outer template scope.
6160e5dd7070Spatrick if (FunctionDecl *FD = dyn_cast<FunctionDecl>(DC)) {
6161*12c85518Srobert if (FD->getFriendObjectKind() &&
6162*12c85518Srobert FD->getNonTransparentDeclContext()->isFileContext()) {
6163e5dd7070Spatrick DC = FD->getLexicalDeclContext();
6164e5dd7070Spatrick continue;
6165e5dd7070Spatrick }
6166e5dd7070Spatrick // An implicit deduction guide acts as if it's within the class template
6167e5dd7070Spatrick // specialization described by its name and first N template params.
6168e5dd7070Spatrick auto *Guide = dyn_cast<CXXDeductionGuideDecl>(FD);
6169e5dd7070Spatrick if (Guide && Guide->isImplicit()) {
6170e5dd7070Spatrick TemplateDecl *TD = Guide->getDeducedTemplate();
6171e5dd7070Spatrick // Convert the arguments to an "as-written" list.
6172e5dd7070Spatrick TemplateArgumentListInfo Args(Loc, Loc);
6173e5dd7070Spatrick for (TemplateArgument Arg : TemplateArgs.getInnermost().take_front(
6174e5dd7070Spatrick TD->getTemplateParameters()->size())) {
6175e5dd7070Spatrick ArrayRef<TemplateArgument> Unpacked(Arg);
6176e5dd7070Spatrick if (Arg.getKind() == TemplateArgument::Pack)
6177e5dd7070Spatrick Unpacked = Arg.pack_elements();
6178e5dd7070Spatrick for (TemplateArgument UnpackedArg : Unpacked)
6179e5dd7070Spatrick Args.addArgument(
6180e5dd7070Spatrick getTrivialTemplateArgumentLoc(UnpackedArg, QualType(), Loc));
6181e5dd7070Spatrick }
6182e5dd7070Spatrick QualType T = CheckTemplateIdType(TemplateName(TD), Loc, Args);
6183e5dd7070Spatrick if (T.isNull())
6184e5dd7070Spatrick return nullptr;
6185e5dd7070Spatrick auto *SubstRecord = T->getAsCXXRecordDecl();
6186e5dd7070Spatrick assert(SubstRecord && "class template id not a class type?");
6187e5dd7070Spatrick // Check that this template-id names the primary template and not a
6188e5dd7070Spatrick // partial or explicit specialization. (In the latter cases, it's
6189e5dd7070Spatrick // meaningless to attempt to find an instantiation of D within the
6190e5dd7070Spatrick // specialization.)
6191e5dd7070Spatrick // FIXME: The standard doesn't say what should happen here.
6192e5dd7070Spatrick if (FindingInstantiatedContext &&
6193e5dd7070Spatrick usesPartialOrExplicitSpecialization(
6194e5dd7070Spatrick Loc, cast<ClassTemplateSpecializationDecl>(SubstRecord))) {
6195e5dd7070Spatrick Diag(Loc, diag::err_specialization_not_primary_template)
6196e5dd7070Spatrick << T << (SubstRecord->getTemplateSpecializationKind() ==
6197e5dd7070Spatrick TSK_ExplicitSpecialization);
6198e5dd7070Spatrick return nullptr;
6199e5dd7070Spatrick }
6200e5dd7070Spatrick DC = SubstRecord;
6201e5dd7070Spatrick continue;
6202e5dd7070Spatrick }
6203e5dd7070Spatrick }
6204e5dd7070Spatrick
6205e5dd7070Spatrick DC = DC->getParent();
6206e5dd7070Spatrick }
6207e5dd7070Spatrick
6208e5dd7070Spatrick // Fall through to deal with other dependent record types (e.g.,
6209e5dd7070Spatrick // anonymous unions in class templates).
6210e5dd7070Spatrick }
6211e5dd7070Spatrick
6212ec727ea7Spatrick if (!ParentDependsOnArgs)
6213e5dd7070Spatrick return D;
6214e5dd7070Spatrick
6215e5dd7070Spatrick ParentDC = FindInstantiatedContext(Loc, ParentDC, TemplateArgs);
6216e5dd7070Spatrick if (!ParentDC)
6217e5dd7070Spatrick return nullptr;
6218e5dd7070Spatrick
6219e5dd7070Spatrick if (ParentDC != D->getDeclContext()) {
6220e5dd7070Spatrick // We performed some kind of instantiation in the parent context,
6221e5dd7070Spatrick // so now we need to look into the instantiated parent context to
6222e5dd7070Spatrick // find the instantiation of the declaration D.
6223e5dd7070Spatrick
6224e5dd7070Spatrick // If our context used to be dependent, we may need to instantiate
6225e5dd7070Spatrick // it before performing lookup into that context.
6226e5dd7070Spatrick bool IsBeingInstantiated = false;
6227e5dd7070Spatrick if (CXXRecordDecl *Spec = dyn_cast<CXXRecordDecl>(ParentDC)) {
6228e5dd7070Spatrick if (!Spec->isDependentContext()) {
6229e5dd7070Spatrick QualType T = Context.getTypeDeclType(Spec);
6230e5dd7070Spatrick const RecordType *Tag = T->getAs<RecordType>();
6231e5dd7070Spatrick assert(Tag && "type of non-dependent record is not a RecordType");
6232e5dd7070Spatrick if (Tag->isBeingDefined())
6233e5dd7070Spatrick IsBeingInstantiated = true;
6234e5dd7070Spatrick if (!Tag->isBeingDefined() &&
6235e5dd7070Spatrick RequireCompleteType(Loc, T, diag::err_incomplete_type))
6236e5dd7070Spatrick return nullptr;
6237e5dd7070Spatrick
6238e5dd7070Spatrick ParentDC = Tag->getDecl();
6239e5dd7070Spatrick }
6240e5dd7070Spatrick }
6241e5dd7070Spatrick
6242e5dd7070Spatrick NamedDecl *Result = nullptr;
6243e5dd7070Spatrick // FIXME: If the name is a dependent name, this lookup won't necessarily
6244e5dd7070Spatrick // find it. Does that ever matter?
6245e5dd7070Spatrick if (auto Name = D->getDeclName()) {
6246e5dd7070Spatrick DeclarationNameInfo NameInfo(Name, D->getLocation());
6247e5dd7070Spatrick DeclarationNameInfo NewNameInfo =
6248e5dd7070Spatrick SubstDeclarationNameInfo(NameInfo, TemplateArgs);
6249e5dd7070Spatrick Name = NewNameInfo.getName();
6250e5dd7070Spatrick if (!Name)
6251e5dd7070Spatrick return nullptr;
6252e5dd7070Spatrick DeclContext::lookup_result Found = ParentDC->lookup(Name);
6253e5dd7070Spatrick
6254e5dd7070Spatrick Result = findInstantiationOf(Context, D, Found.begin(), Found.end());
6255e5dd7070Spatrick } else {
6256e5dd7070Spatrick // Since we don't have a name for the entity we're looking for,
6257e5dd7070Spatrick // our only option is to walk through all of the declarations to
6258e5dd7070Spatrick // find that name. This will occur in a few cases:
6259e5dd7070Spatrick //
6260e5dd7070Spatrick // - anonymous struct/union within a template
6261e5dd7070Spatrick // - unnamed class/struct/union/enum within a template
6262e5dd7070Spatrick //
6263e5dd7070Spatrick // FIXME: Find a better way to find these instantiations!
6264e5dd7070Spatrick Result = findInstantiationOf(Context, D,
6265e5dd7070Spatrick ParentDC->decls_begin(),
6266e5dd7070Spatrick ParentDC->decls_end());
6267e5dd7070Spatrick }
6268e5dd7070Spatrick
6269e5dd7070Spatrick if (!Result) {
6270e5dd7070Spatrick if (isa<UsingShadowDecl>(D)) {
6271e5dd7070Spatrick // UsingShadowDecls can instantiate to nothing because of using hiding.
6272a9ac8606Spatrick } else if (hasUncompilableErrorOccurred()) {
6273ec727ea7Spatrick // We've already complained about some ill-formed code, so most likely
6274ec727ea7Spatrick // this declaration failed to instantiate. There's no point in
6275ec727ea7Spatrick // complaining further, since this is normal in invalid code.
6276ec727ea7Spatrick // FIXME: Use more fine-grained 'invalid' tracking for this.
6277e5dd7070Spatrick } else if (IsBeingInstantiated) {
6278e5dd7070Spatrick // The class in which this member exists is currently being
6279e5dd7070Spatrick // instantiated, and we haven't gotten around to instantiating this
6280e5dd7070Spatrick // member yet. This can happen when the code uses forward declarations
6281e5dd7070Spatrick // of member classes, and introduces ordering dependencies via
6282e5dd7070Spatrick // template instantiation.
6283e5dd7070Spatrick Diag(Loc, diag::err_member_not_yet_instantiated)
6284e5dd7070Spatrick << D->getDeclName()
6285e5dd7070Spatrick << Context.getTypeDeclType(cast<CXXRecordDecl>(ParentDC));
6286e5dd7070Spatrick Diag(D->getLocation(), diag::note_non_instantiated_member_here);
6287e5dd7070Spatrick } else if (EnumConstantDecl *ED = dyn_cast<EnumConstantDecl>(D)) {
6288e5dd7070Spatrick // This enumeration constant was found when the template was defined,
6289e5dd7070Spatrick // but can't be found in the instantiation. This can happen if an
6290e5dd7070Spatrick // unscoped enumeration member is explicitly specialized.
6291e5dd7070Spatrick EnumDecl *Enum = cast<EnumDecl>(ED->getLexicalDeclContext());
6292e5dd7070Spatrick EnumDecl *Spec = cast<EnumDecl>(FindInstantiatedDecl(Loc, Enum,
6293e5dd7070Spatrick TemplateArgs));
6294e5dd7070Spatrick assert(Spec->getTemplateSpecializationKind() ==
6295e5dd7070Spatrick TSK_ExplicitSpecialization);
6296e5dd7070Spatrick Diag(Loc, diag::err_enumerator_does_not_exist)
6297e5dd7070Spatrick << D->getDeclName()
6298e5dd7070Spatrick << Context.getTypeDeclType(cast<TypeDecl>(Spec->getDeclContext()));
6299e5dd7070Spatrick Diag(Spec->getLocation(), diag::note_enum_specialized_here)
6300e5dd7070Spatrick << Context.getTypeDeclType(Spec);
6301e5dd7070Spatrick } else {
6302e5dd7070Spatrick // We should have found something, but didn't.
6303e5dd7070Spatrick llvm_unreachable("Unable to find instantiation of declaration!");
6304e5dd7070Spatrick }
6305e5dd7070Spatrick }
6306e5dd7070Spatrick
6307e5dd7070Spatrick D = Result;
6308e5dd7070Spatrick }
6309e5dd7070Spatrick
6310e5dd7070Spatrick return D;
6311e5dd7070Spatrick }
6312e5dd7070Spatrick
6313e5dd7070Spatrick /// Performs template instantiation for all implicit template
6314e5dd7070Spatrick /// instantiations we have seen until this point.
PerformPendingInstantiations(bool LocalOnly)6315e5dd7070Spatrick void Sema::PerformPendingInstantiations(bool LocalOnly) {
6316ec727ea7Spatrick std::deque<PendingImplicitInstantiation> delayedPCHInstantiations;
6317e5dd7070Spatrick while (!PendingLocalImplicitInstantiations.empty() ||
6318e5dd7070Spatrick (!LocalOnly && !PendingInstantiations.empty())) {
6319e5dd7070Spatrick PendingImplicitInstantiation Inst;
6320e5dd7070Spatrick
6321e5dd7070Spatrick if (PendingLocalImplicitInstantiations.empty()) {
6322e5dd7070Spatrick Inst = PendingInstantiations.front();
6323e5dd7070Spatrick PendingInstantiations.pop_front();
6324e5dd7070Spatrick } else {
6325e5dd7070Spatrick Inst = PendingLocalImplicitInstantiations.front();
6326e5dd7070Spatrick PendingLocalImplicitInstantiations.pop_front();
6327e5dd7070Spatrick }
6328e5dd7070Spatrick
6329e5dd7070Spatrick // Instantiate function definitions
6330e5dd7070Spatrick if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Inst.first)) {
6331e5dd7070Spatrick bool DefinitionRequired = Function->getTemplateSpecializationKind() ==
6332e5dd7070Spatrick TSK_ExplicitInstantiationDefinition;
6333e5dd7070Spatrick if (Function->isMultiVersion()) {
6334e5dd7070Spatrick getASTContext().forEachMultiversionedFunctionVersion(
6335e5dd7070Spatrick Function, [this, Inst, DefinitionRequired](FunctionDecl *CurFD) {
6336e5dd7070Spatrick InstantiateFunctionDefinition(/*FIXME:*/ Inst.second, CurFD, true,
6337e5dd7070Spatrick DefinitionRequired, true);
6338e5dd7070Spatrick if (CurFD->isDefined())
6339e5dd7070Spatrick CurFD->setInstantiationIsPending(false);
6340e5dd7070Spatrick });
6341e5dd7070Spatrick } else {
6342e5dd7070Spatrick InstantiateFunctionDefinition(/*FIXME:*/ Inst.second, Function, true,
6343e5dd7070Spatrick DefinitionRequired, true);
6344e5dd7070Spatrick if (Function->isDefined())
6345e5dd7070Spatrick Function->setInstantiationIsPending(false);
6346e5dd7070Spatrick }
6347ec727ea7Spatrick // Definition of a PCH-ed template declaration may be available only in the TU.
6348ec727ea7Spatrick if (!LocalOnly && LangOpts.PCHInstantiateTemplates &&
6349ec727ea7Spatrick TUKind == TU_Prefix && Function->instantiationIsPending())
6350ec727ea7Spatrick delayedPCHInstantiations.push_back(Inst);
6351e5dd7070Spatrick continue;
6352e5dd7070Spatrick }
6353e5dd7070Spatrick
6354e5dd7070Spatrick // Instantiate variable definitions
6355e5dd7070Spatrick VarDecl *Var = cast<VarDecl>(Inst.first);
6356e5dd7070Spatrick
6357e5dd7070Spatrick assert((Var->isStaticDataMember() ||
6358e5dd7070Spatrick isa<VarTemplateSpecializationDecl>(Var)) &&
6359e5dd7070Spatrick "Not a static data member, nor a variable template"
6360e5dd7070Spatrick " specialization?");
6361e5dd7070Spatrick
6362e5dd7070Spatrick // Don't try to instantiate declarations if the most recent redeclaration
6363e5dd7070Spatrick // is invalid.
6364e5dd7070Spatrick if (Var->getMostRecentDecl()->isInvalidDecl())
6365e5dd7070Spatrick continue;
6366e5dd7070Spatrick
6367e5dd7070Spatrick // Check if the most recent declaration has changed the specialization kind
6368e5dd7070Spatrick // and removed the need for implicit instantiation.
6369e5dd7070Spatrick switch (Var->getMostRecentDecl()
6370e5dd7070Spatrick ->getTemplateSpecializationKindForInstantiation()) {
6371e5dd7070Spatrick case TSK_Undeclared:
6372e5dd7070Spatrick llvm_unreachable("Cannot instantitiate an undeclared specialization.");
6373e5dd7070Spatrick case TSK_ExplicitInstantiationDeclaration:
6374e5dd7070Spatrick case TSK_ExplicitSpecialization:
6375e5dd7070Spatrick continue; // No longer need to instantiate this type.
6376e5dd7070Spatrick case TSK_ExplicitInstantiationDefinition:
6377e5dd7070Spatrick // We only need an instantiation if the pending instantiation *is* the
6378e5dd7070Spatrick // explicit instantiation.
6379e5dd7070Spatrick if (Var != Var->getMostRecentDecl())
6380e5dd7070Spatrick continue;
6381e5dd7070Spatrick break;
6382e5dd7070Spatrick case TSK_ImplicitInstantiation:
6383e5dd7070Spatrick break;
6384e5dd7070Spatrick }
6385e5dd7070Spatrick
6386e5dd7070Spatrick PrettyDeclStackTraceEntry CrashInfo(Context, Var, SourceLocation(),
6387e5dd7070Spatrick "instantiating variable definition");
6388e5dd7070Spatrick bool DefinitionRequired = Var->getTemplateSpecializationKind() ==
6389e5dd7070Spatrick TSK_ExplicitInstantiationDefinition;
6390e5dd7070Spatrick
6391e5dd7070Spatrick // Instantiate static data member definitions or variable template
6392e5dd7070Spatrick // specializations.
6393e5dd7070Spatrick InstantiateVariableDefinition(/*FIXME:*/ Inst.second, Var, true,
6394e5dd7070Spatrick DefinitionRequired, true);
6395e5dd7070Spatrick }
6396ec727ea7Spatrick
6397ec727ea7Spatrick if (!LocalOnly && LangOpts.PCHInstantiateTemplates)
6398ec727ea7Spatrick PendingInstantiations.swap(delayedPCHInstantiations);
6399e5dd7070Spatrick }
6400e5dd7070Spatrick
PerformDependentDiagnostics(const DeclContext * Pattern,const MultiLevelTemplateArgumentList & TemplateArgs)6401e5dd7070Spatrick void Sema::PerformDependentDiagnostics(const DeclContext *Pattern,
6402e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs) {
6403*12c85518Srobert for (auto *DD : Pattern->ddiags()) {
6404e5dd7070Spatrick switch (DD->getKind()) {
6405e5dd7070Spatrick case DependentDiagnostic::Access:
6406e5dd7070Spatrick HandleDependentAccessCheck(*DD, TemplateArgs);
6407e5dd7070Spatrick break;
6408e5dd7070Spatrick }
6409e5dd7070Spatrick }
6410e5dd7070Spatrick }
6411