1//===- SemaTemplate.h - C++ Templates ---------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//===----------------------------------------------------------------------===//
7//
8// This file provides types used in the semantic analysis of C++ templates.
9//
10//===----------------------------------------------------------------------===//
11
12#ifndef LLVM_CLANG_SEMA_TEMPLATE_H
13#define LLVM_CLANG_SEMA_TEMPLATE_H
14
15#include "clang/AST/DeclTemplate.h"
16#include "clang/AST/DeclVisitor.h"
17#include "clang/AST/TemplateBase.h"
18#include "clang/AST/Type.h"
19#include "clang/Basic/LLVM.h"
20#include "clang/Sema/Sema.h"
21#include "llvm/ADT/ArrayRef.h"
22#include "llvm/ADT/DenseMap.h"
23#include "llvm/ADT/PointerUnion.h"
24#include "llvm/ADT/SmallVector.h"
25#include <cassert>
26#include <optional>
27#include <utility>
28
29namespace clang {
30
31class ASTContext;
32class BindingDecl;
33class CXXMethodDecl;
34class Decl;
35class DeclaratorDecl;
36class DeclContext;
37class EnumDecl;
38class FunctionDecl;
39class NamedDecl;
40class ParmVarDecl;
41class TagDecl;
42class TypedefNameDecl;
43class TypeSourceInfo;
44class VarDecl;
45
46/// The kind of template substitution being performed.
47enum class TemplateSubstitutionKind : char {
48 /// We are substituting template parameters for template arguments in order
49 /// to form a template specialization.
50 Specialization,
51 /// We are substituting template parameters for (typically) other template
52 /// parameters in order to rewrite a declaration as a different declaration
53 /// (for example, when forming a deduction guide from a constructor).
54 Rewrite,
55};
56
57 /// Data structure that captures multiple levels of template argument
58 /// lists for use in template instantiation.
59 ///
60 /// Multiple levels of template arguments occur when instantiating the
61 /// definitions of member templates. For example:
62 ///
63 /// \code
64 /// template<typename T>
65 /// struct X {
66 /// template<T Value>
67 /// struct Y {
68 /// void f();
69 /// };
70 /// };
71 /// \endcode
72 ///
73 /// When instantiating X<int>::Y<17>::f, the multi-level template argument
74 /// list will contain a template argument list (int) at depth 0 and a
75 /// template argument list (17) at depth 1.
76 class MultiLevelTemplateArgumentList {
77 /// The template argument list at a certain template depth
78
79 using ArgList = ArrayRef<TemplateArgument>;
80 struct ArgumentListLevel {
81 llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndFinal;
82 ArgList Args;
83 };
84 using ContainerType = SmallVector<ArgumentListLevel, 4>;
85
86 using ArgListsIterator = ContainerType::iterator;
87 using ConstArgListsIterator = ContainerType::const_iterator;
88
89 /// The template argument lists, stored from the innermost template
90 /// argument list (first) to the outermost template argument list (last).
91 ContainerType TemplateArgumentLists;
92
93 /// The number of outer levels of template arguments that are not
94 /// being substituted.
95 unsigned NumRetainedOuterLevels = 0;
96
97 /// The kind of substitution described by this argument list.
98 TemplateSubstitutionKind Kind = TemplateSubstitutionKind::Specialization;
99
100 bool RetainInnerDepths = false;
101
102 public:
103 /// Construct an empty set of template argument lists.
104 MultiLevelTemplateArgumentList() = default;
105
106 /// Construct a single-level template argument list.
107 MultiLevelTemplateArgumentList(Decl *D, ArgList Args, bool Final) {
108 addOuterTemplateArguments(AssociatedDecl: D, Args, Final);
109 }
110
111 void setKind(TemplateSubstitutionKind K) { Kind = K; }
112
113 void setRetainInnerDepths() { RetainInnerDepths = true; }
114
115 bool retainInnerDepths() const { return RetainInnerDepths; }
116
117 /// Determine the kind of template substitution being performed.
118 TemplateSubstitutionKind getKind() const { return Kind; }
119
120 /// Determine whether we are rewriting template parameters rather than
121 /// substituting for them. If so, we should not leave references to the
122 /// original template parameters behind.
123 bool isRewrite() const {
124 return Kind == TemplateSubstitutionKind::Rewrite;
125 }
126
127 /// Determine the number of levels in this template argument
128 /// list.
129 unsigned getNumLevels() const {
130 return TemplateArgumentLists.size() + NumRetainedOuterLevels;
131 }
132
133 /// Determine the number of substituted levels in this template
134 /// argument list.
135 unsigned getNumSubstitutedLevels() const {
136 return TemplateArgumentLists.size();
137 }
138
139 // Determine the number of substituted args at 'Depth'.
140 unsigned getNumSubsitutedArgs(unsigned Depth) const {
141 assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
142 return TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size();
143 }
144
145 unsigned getNumRetainedOuterLevels() const {
146 return NumRetainedOuterLevels;
147 }
148
149 /// Determine how many of the \p OldDepth outermost template parameter
150 /// lists would be removed by substituting these arguments.
151 unsigned getNewDepth(unsigned OldDepth) const {
152 if (OldDepth < NumRetainedOuterLevels)
153 return OldDepth;
154 if (OldDepth < getNumLevels())
155 return NumRetainedOuterLevels;
156 return OldDepth - TemplateArgumentLists.size();
157 }
158
159 /// Retrieve the template argument at a given depth and index.
160 const TemplateArgument &operator()(unsigned Depth, unsigned Index) const {
161 assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
162 assert(Index <
163 TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size());
164 return TemplateArgumentLists[getNumLevels() - Depth - 1].Args[Index];
165 }
166
167 /// A template-like entity which owns the whole pattern being substituted.
168 /// This will usually own a set of template parameters, or in some
169 /// cases might even be a template parameter itself.
170 std::pair<Decl *, bool> getAssociatedDecl(unsigned Depth) const {
171 assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
172 auto AD = TemplateArgumentLists[getNumLevels() - Depth - 1]
173 .AssociatedDeclAndFinal;
174 return {AD.getPointer(), AD.getInt()};
175 }
176
177 /// Determine whether there is a non-NULL template argument at the
178 /// given depth and index.
179 ///
180 /// There must exist a template argument list at the given depth.
181 bool hasTemplateArgument(unsigned Depth, unsigned Index) const {
182 assert(Depth < getNumLevels());
183
184 if (Depth < NumRetainedOuterLevels)
185 return false;
186
187 if (Index >=
188 TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size())
189 return false;
190
191 return !(*this)(Depth, Index).isNull();
192 }
193
194 bool isAnyArgInstantiationDependent() const {
195 for (ArgumentListLevel ListLevel : TemplateArgumentLists)
196 for (const TemplateArgument &TA : ListLevel.Args)
197 // There might be null template arguments representing unused template
198 // parameter mappings in an MLTAL during concept checking.
199 if (!TA.isNull() && TA.isInstantiationDependent())
200 return true;
201 return false;
202 }
203
204 /// Clear out a specific template argument.
205 void setArgument(unsigned Depth, unsigned Index,
206 TemplateArgument Arg) {
207 assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
208 assert(Index <
209 TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size());
210 const_cast<TemplateArgument &>(
211 TemplateArgumentLists[getNumLevels() - Depth - 1].Args[Index]) = Arg;
212 }
213
214 /// Add a new outmost level to the multi-level template argument
215 /// list.
216 /// A 'Final' substitution means that these Args don't need to be
217 /// resugared later.
218 void addOuterTemplateArguments(Decl *AssociatedDecl, ArgList Args,
219 bool Final) {
220 assert(!NumRetainedOuterLevels &&
221 "substituted args outside retained args?");
222 assert(getKind() == TemplateSubstitutionKind::Specialization);
223 TemplateArgumentLists.push_back(
224 Elt: {.AssociatedDeclAndFinal: {AssociatedDecl ? AssociatedDecl->getCanonicalDecl() : nullptr,
225 Final},
226 .Args: Args});
227 }
228
229 void addOuterTemplateArguments(ArgList Args) {
230 assert(!NumRetainedOuterLevels &&
231 "substituted args outside retained args?");
232 assert(getKind() == TemplateSubstitutionKind::Rewrite);
233 TemplateArgumentLists.push_back(Elt: {.AssociatedDeclAndFinal: {}, .Args: Args});
234 }
235
236 void addOuterTemplateArguments(std::nullopt_t) {
237 assert(!NumRetainedOuterLevels &&
238 "substituted args outside retained args?");
239 TemplateArgumentLists.push_back(Elt: {});
240 }
241
242 /// Replaces the current 'innermost' level with the provided argument list.
243 /// This is useful for type deduction cases where we need to get the entire
244 /// list from the AST, but then add the deduced innermost list.
245 void replaceInnermostTemplateArguments(Decl *AssociatedDecl, ArgList Args,
246 bool Final = false) {
247 assert((!TemplateArgumentLists.empty() || NumRetainedOuterLevels) &&
248 "Replacing in an empty list?");
249
250 if (!TemplateArgumentLists.empty()) {
251 TemplateArgumentLists[0].Args = Args;
252 return;
253 }
254 --NumRetainedOuterLevels;
255 TemplateArgumentLists.push_back(
256 Elt: {.AssociatedDeclAndFinal: {AssociatedDecl, /*Final=*/Final}, .Args: Args});
257 }
258
259 void replaceOutermostTemplateArguments(Decl *AssociatedDecl, ArgList Args) {
260 assert((!TemplateArgumentLists.empty()) && "Replacing in an empty list?");
261 TemplateArgumentLists.back().AssociatedDeclAndFinal.setPointer(
262 AssociatedDecl);
263 TemplateArgumentLists.back().Args = Args;
264 }
265
266 /// Add an outermost level that we are not substituting. We have no
267 /// arguments at this level, and do not remove it from the depth of inner
268 /// template parameters that we instantiate.
269 void addOuterRetainedLevel() {
270 ++NumRetainedOuterLevels;
271 }
272 void addOuterRetainedLevels(unsigned Num) {
273 NumRetainedOuterLevels += Num;
274 }
275
276 /// Retrieve the innermost template argument list.
277 const ArgList &getInnermost() const {
278 return TemplateArgumentLists.front().Args;
279 }
280 /// Retrieve the outermost template argument list.
281 const ArgList &getOutermost() const {
282 return TemplateArgumentLists.back().Args;
283 }
284 ArgListsIterator begin() { return TemplateArgumentLists.begin(); }
285 ConstArgListsIterator begin() const {
286 return TemplateArgumentLists.begin();
287 }
288 ArgListsIterator end() { return TemplateArgumentLists.end(); }
289 ConstArgListsIterator end() const { return TemplateArgumentLists.end(); }
290
291 LLVM_DUMP_METHOD void dump() const {
292 LangOptions LO;
293 LO.CPlusPlus = true;
294 LO.Bool = true;
295 PrintingPolicy PP(LO);
296 llvm::errs() << "NumRetainedOuterLevels: " << NumRetainedOuterLevels
297 << "\n";
298 for (unsigned Depth = NumRetainedOuterLevels; Depth < getNumLevels();
299 ++Depth) {
300 llvm::errs() << Depth << ": ";
301 printTemplateArgumentList(
302 OS&: llvm::errs(),
303 Args: TemplateArgumentLists[getNumLevels() - Depth - 1].Args, Policy: PP);
304 llvm::errs() << "\n";
305 }
306 }
307 };
308
309 /// The context in which partial ordering of function templates occurs.
310 enum TPOC {
311 /// Partial ordering of function templates for a function call.
312 TPOC_Call,
313
314 /// Partial ordering of function templates for a call to a
315 /// conversion function.
316 TPOC_Conversion,
317
318 /// Partial ordering of function templates in other contexts, e.g.,
319 /// taking the address of a function template or matching a function
320 /// template specialization to a function template.
321 TPOC_Other
322 };
323
324 // This is lame but unavoidable in a world without forward
325 // declarations of enums. The alternatives are to either pollute
326 // Sema.h (by including this file) or sacrifice type safety (by
327 // making Sema.h declare things as enums).
328 class TemplatePartialOrderingContext {
329 TPOC Value;
330
331 public:
332 TemplatePartialOrderingContext(TPOC Value) : Value(Value) {}
333
334 operator TPOC() const { return Value; }
335 };
336
337 /// Captures a template argument whose value has been deduced
338 /// via c++ template argument deduction.
339 class DeducedTemplateArgument : public TemplateArgument {
340 /// For a non-type template argument, whether the value was
341 /// deduced from an array bound.
342 bool DeducedFromArrayBound = false;
343
344 public:
345 DeducedTemplateArgument() = default;
346
347 DeducedTemplateArgument(const TemplateArgument &Arg,
348 bool DeducedFromArrayBound = false)
349 : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) {}
350
351 /// Construct an integral non-type template argument that
352 /// has been deduced, possibly from an array bound.
353 DeducedTemplateArgument(ASTContext &Ctx,
354 const llvm::APSInt &Value,
355 QualType ValueType,
356 bool DeducedFromArrayBound)
357 : TemplateArgument(Ctx, Value, ValueType),
358 DeducedFromArrayBound(DeducedFromArrayBound) {}
359
360 /// For a non-type template argument, determine whether the
361 /// template argument was deduced from an array bound.
362 bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; }
363
364 /// Specify whether the given non-type template argument
365 /// was deduced from an array bound.
366 void setDeducedFromArrayBound(bool Deduced) {
367 DeducedFromArrayBound = Deduced;
368 }
369 };
370
371 /// A stack-allocated class that identifies which local
372 /// variable declaration instantiations are present in this scope.
373 ///
374 /// A new instance of this class type will be created whenever we
375 /// instantiate a new function declaration, which will have its own
376 /// set of parameter declarations.
377 class LocalInstantiationScope {
378 public:
379 /// A set of declarations.
380 using DeclArgumentPack = SmallVector<ValueDecl *, 4>;
381
382 private:
383 /// Reference to the semantic analysis that is performing
384 /// this template instantiation.
385 Sema &SemaRef;
386
387 using LocalDeclsMap =
388 llvm::SmallDenseMap<const Decl *,
389 llvm::PointerUnion<Decl *, DeclArgumentPack *>, 4>;
390
391 /// A mapping from local declarations that occur
392 /// within a template to their instantiations.
393 ///
394 /// This mapping is used during instantiation to keep track of,
395 /// e.g., function parameter and variable declarations. For example,
396 /// given:
397 ///
398 /// \code
399 /// template<typename T> T add(T x, T y) { return x + y; }
400 /// \endcode
401 ///
402 /// when we instantiate add<int>, we will introduce a mapping from
403 /// the ParmVarDecl for 'x' that occurs in the template to the
404 /// instantiated ParmVarDecl for 'x'.
405 ///
406 /// For a parameter pack, the local instantiation scope may contain a
407 /// set of instantiated parameters. This is stored as a DeclArgumentPack
408 /// pointer.
409 LocalDeclsMap LocalDecls;
410
411 /// The set of argument packs we've allocated.
412 SmallVector<DeclArgumentPack *, 1> ArgumentPacks;
413
414 /// The outer scope, which contains local variable
415 /// definitions from some other instantiation (that may not be
416 /// relevant to this particular scope).
417 LocalInstantiationScope *Outer;
418
419 /// Whether we have already exited this scope.
420 bool Exited = false;
421
422 /// Whether to combine this scope with the outer scope, such that
423 /// lookup will search our outer scope.
424 bool CombineWithOuterScope;
425
426 /// Whether this scope is being used to instantiate a lambda or block
427 /// expression, in which case it should be reused for instantiating the
428 /// lambda's FunctionProtoType.
429 bool InstantiatingLambdaOrBlock = false;
430
431 /// If non-NULL, the template parameter pack that has been
432 /// partially substituted per C++0x [temp.arg.explicit]p9.
433 NamedDecl *PartiallySubstitutedPack = nullptr;
434
435 /// If \c PartiallySubstitutedPack is non-null, the set of
436 /// explicitly-specified template arguments in that pack.
437 const TemplateArgument *ArgsInPartiallySubstitutedPack;
438
439 /// If \c PartiallySubstitutedPack, the number of
440 /// explicitly-specified template arguments in
441 /// ArgsInPartiallySubstitutedPack.
442 unsigned NumArgsInPartiallySubstitutedPack;
443
444 public:
445 LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false,
446 bool InstantiatingLambdaOrBlock = false)
447 : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope),
448 CombineWithOuterScope(CombineWithOuterScope),
449 InstantiatingLambdaOrBlock(InstantiatingLambdaOrBlock) {
450 SemaRef.CurrentInstantiationScope = this;
451 }
452
453 LocalInstantiationScope(const LocalInstantiationScope &) = delete;
454 LocalInstantiationScope &
455 operator=(const LocalInstantiationScope &) = delete;
456
457 ~LocalInstantiationScope() {
458 Exit();
459 }
460
461 const Sema &getSema() const { return SemaRef; }
462
463 /// Exit this local instantiation scope early.
464 void Exit() {
465 if (Exited)
466 return;
467
468 for (unsigned I = 0, N = ArgumentPacks.size(); I != N; ++I)
469 delete ArgumentPacks[I];
470
471 SemaRef.CurrentInstantiationScope = Outer;
472 Exited = true;
473 }
474
475 /// Clone this scope, and all outer scopes, down to the given
476 /// outermost scope.
477 LocalInstantiationScope *cloneScopes(LocalInstantiationScope *Outermost) {
478 if (this == Outermost) return this;
479
480 // Save the current scope from SemaRef since the LocalInstantiationScope
481 // will overwrite it on construction
482 LocalInstantiationScope *oldScope = SemaRef.CurrentInstantiationScope;
483
484 LocalInstantiationScope *newScope =
485 new LocalInstantiationScope(SemaRef, CombineWithOuterScope);
486
487 newScope->Outer = nullptr;
488 if (Outer)
489 newScope->Outer = Outer->cloneScopes(Outermost);
490
491 newScope->PartiallySubstitutedPack = PartiallySubstitutedPack;
492 newScope->ArgsInPartiallySubstitutedPack = ArgsInPartiallySubstitutedPack;
493 newScope->NumArgsInPartiallySubstitutedPack =
494 NumArgsInPartiallySubstitutedPack;
495
496 for (LocalDeclsMap::iterator I = LocalDecls.begin(), E = LocalDecls.end();
497 I != E; ++I) {
498 const Decl *D = I->first;
499 llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored =
500 newScope->LocalDecls[D];
501 if (auto *D2 = dyn_cast<Decl *>(Val&: I->second)) {
502 Stored = D2;
503 } else {
504 DeclArgumentPack *OldPack = cast<DeclArgumentPack *>(Val&: I->second);
505 DeclArgumentPack *NewPack = new DeclArgumentPack(*OldPack);
506 Stored = NewPack;
507 newScope->ArgumentPacks.push_back(Elt: NewPack);
508 }
509 }
510 // Restore the saved scope to SemaRef
511 SemaRef.CurrentInstantiationScope = oldScope;
512 return newScope;
513 }
514
515 /// deletes the given scope, and all outer scopes, down to the
516 /// given outermost scope.
517 static void deleteScopes(LocalInstantiationScope *Scope,
518 LocalInstantiationScope *Outermost) {
519 while (Scope && Scope != Outermost) {
520 LocalInstantiationScope *Out = Scope->Outer;
521 delete Scope;
522 Scope = Out;
523 }
524 }
525
526 /// Find the instantiation of the declaration D within the current
527 /// instantiation scope.
528 ///
529 /// \param D The declaration whose instantiation we are searching for.
530 ///
531 /// \returns A pointer to the declaration or argument pack of declarations
532 /// to which the declaration \c D is instantiated, if found. Otherwise,
533 /// returns NULL.
534 llvm::PointerUnion<Decl *, DeclArgumentPack *> *
535 findInstantiationOf(const Decl *D);
536
537 /// Similar to \p findInstantiationOf(), but it wouldn't assert if the
538 /// instantiation was not found within the current instantiation scope. This
539 /// is helpful for on-demand declaration instantiation.
540 llvm::PointerUnion<Decl *, DeclArgumentPack *> *
541 getInstantiationOfIfExists(const Decl *D);
542
543 void InstantiatedLocal(const Decl *D, Decl *Inst);
544 void InstantiatedLocalPackArg(const Decl *D, VarDecl *Inst);
545 void MakeInstantiatedLocalArgPack(const Decl *D);
546
547 /// Note that the given parameter pack has been partially substituted
548 /// via explicit specification of template arguments
549 /// (C++0x [temp.arg.explicit]p9).
550 ///
551 /// \param Pack The parameter pack, which will always be a template
552 /// parameter pack.
553 ///
554 /// \param ExplicitArgs The explicitly-specified template arguments provided
555 /// for this parameter pack.
556 ///
557 /// \param NumExplicitArgs The number of explicitly-specified template
558 /// arguments provided for this parameter pack.
559 void SetPartiallySubstitutedPack(NamedDecl *Pack,
560 const TemplateArgument *ExplicitArgs,
561 unsigned NumExplicitArgs);
562
563 /// Reset the partially-substituted pack when it is no longer of
564 /// interest.
565 void ResetPartiallySubstitutedPack() {
566 assert(PartiallySubstitutedPack && "No partially-substituted pack");
567 PartiallySubstitutedPack = nullptr;
568 ArgsInPartiallySubstitutedPack = nullptr;
569 NumArgsInPartiallySubstitutedPack = 0;
570 }
571
572 /// Retrieve the partially-substitued template parameter pack.
573 ///
574 /// If there is no partially-substituted parameter pack, returns NULL.
575 NamedDecl *
576 getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs = nullptr,
577 unsigned *NumExplicitArgs = nullptr) const;
578
579 /// Determine whether D is a pack expansion created in this scope.
580 bool isLocalPackExpansion(const Decl *D);
581
582 /// Determine whether this scope is for instantiating a lambda or block.
583 bool isLambdaOrBlock() const { return InstantiatingLambdaOrBlock; }
584 };
585
586 class TemplateDeclInstantiator
587 : public DeclVisitor<TemplateDeclInstantiator, Decl *>
588 {
589 Sema &SemaRef;
590 Sema::ArgPackSubstIndexRAII SubstIndex;
591 DeclContext *Owner;
592 const MultiLevelTemplateArgumentList &TemplateArgs;
593 Sema::LateInstantiatedAttrVec* LateAttrs = nullptr;
594 LocalInstantiationScope *StartingScope = nullptr;
595 // Whether to evaluate the C++20 constraints or simply substitute into them.
596 bool EvaluateConstraints = true;
597
598 /// A list of out-of-line class template partial
599 /// specializations that will need to be instantiated after the
600 /// enclosing class's instantiation is complete.
601 SmallVector<std::pair<ClassTemplateDecl *,
602 ClassTemplatePartialSpecializationDecl *>,
603 1>
604 OutOfLinePartialSpecs;
605
606 /// A list of out-of-line variable template partial
607 /// specializations that will need to be instantiated after the
608 /// enclosing variable's instantiation is complete.
609 /// FIXME: Verify that this is needed.
610 SmallVector<
611 std::pair<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>, 1>
612 OutOfLineVarPartialSpecs;
613
614 public:
615 TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner,
616 const MultiLevelTemplateArgumentList &TemplateArgs)
617 : SemaRef(SemaRef), SubstIndex(SemaRef, SemaRef.ArgPackSubstIndex),
618 Owner(Owner), TemplateArgs(TemplateArgs) {}
619
620 void setEvaluateConstraints(bool B) {
621 EvaluateConstraints = B;
622 }
623 bool getEvaluateConstraints() {
624 return EvaluateConstraints;
625 }
626
627// Define all the decl visitors using DeclNodes.inc
628#define DECL(DERIVED, BASE) \
629 Decl *Visit ## DERIVED ## Decl(DERIVED ## Decl *D);
630#define ABSTRACT_DECL(DECL)
631
632// Decls which never appear inside a class or function.
633#define OBJCCONTAINER(DERIVED, BASE)
634#define FILESCOPEASM(DERIVED, BASE)
635#define TOPLEVELSTMT(DERIVED, BASE)
636#define IMPORT(DERIVED, BASE)
637#define EXPORT(DERIVED, BASE)
638#define LINKAGESPEC(DERIVED, BASE)
639#define OBJCCOMPATIBLEALIAS(DERIVED, BASE)
640#define OBJCMETHOD(DERIVED, BASE)
641#define OBJCTYPEPARAM(DERIVED, BASE)
642#define OBJCIVAR(DERIVED, BASE)
643#define OBJCPROPERTY(DERIVED, BASE)
644#define OBJCPROPERTYIMPL(DERIVED, BASE)
645#define EMPTY(DERIVED, BASE)
646#define LIFETIMEEXTENDEDTEMPORARY(DERIVED, BASE)
647
648// Decls which never appear inside a template.
649#define OUTLINEDFUNCTION(DERIVED, BASE)
650
651// Decls which use special-case instantiation code.
652#define BLOCK(DERIVED, BASE)
653#define CAPTURED(DERIVED, BASE)
654#define IMPLICITPARAM(DERIVED, BASE)
655
656#include "clang/AST/DeclNodes.inc"
657
658 enum class RewriteKind { None, RewriteSpaceshipAsEqualEqual };
659
660 void adjustForRewrite(RewriteKind RK, FunctionDecl *Orig, QualType &T,
661 TypeSourceInfo *&TInfo,
662 DeclarationNameInfo &NameInfo);
663
664 // A few supplemental visitor functions.
665 Decl *VisitCXXMethodDecl(CXXMethodDecl *D,
666 TemplateParameterList *TemplateParams,
667 RewriteKind RK = RewriteKind::None);
668 Decl *VisitFunctionDecl(FunctionDecl *D,
669 TemplateParameterList *TemplateParams,
670 RewriteKind RK = RewriteKind::None);
671 Decl *VisitDecl(Decl *D);
672 Decl *VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate,
673 ArrayRef<BindingDecl *> *Bindings = nullptr);
674 Decl *VisitBaseUsingDecls(BaseUsingDecl *D, BaseUsingDecl *Inst,
675 LookupResult *Lookup);
676
677 // Enable late instantiation of attributes. Late instantiated attributes
678 // will be stored in LA.
679 void enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec *LA) {
680 LateAttrs = LA;
681 StartingScope = SemaRef.CurrentInstantiationScope;
682 }
683
684 // Disable late instantiation of attributes.
685 void disableLateAttributeInstantiation() {
686 LateAttrs = nullptr;
687 StartingScope = nullptr;
688 }
689
690 LocalInstantiationScope *getStartingScope() const { return StartingScope; }
691
692 using delayed_partial_spec_iterator = SmallVectorImpl<std::pair<
693 ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl *>>::iterator;
694
695 using delayed_var_partial_spec_iterator = SmallVectorImpl<std::pair<
696 VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>>::iterator;
697
698 /// Return an iterator to the beginning of the set of
699 /// "delayed" partial specializations, which must be passed to
700 /// InstantiateClassTemplatePartialSpecialization once the class
701 /// definition has been completed.
702 delayed_partial_spec_iterator delayed_partial_spec_begin() {
703 return OutOfLinePartialSpecs.begin();
704 }
705
706 delayed_var_partial_spec_iterator delayed_var_partial_spec_begin() {
707 return OutOfLineVarPartialSpecs.begin();
708 }
709
710 /// Return an iterator to the end of the set of
711 /// "delayed" partial specializations, which must be passed to
712 /// InstantiateClassTemplatePartialSpecialization once the class
713 /// definition has been completed.
714 delayed_partial_spec_iterator delayed_partial_spec_end() {
715 return OutOfLinePartialSpecs.end();
716 }
717
718 delayed_var_partial_spec_iterator delayed_var_partial_spec_end() {
719 return OutOfLineVarPartialSpecs.end();
720 }
721
722 // Helper functions for instantiating methods.
723 TypeSourceInfo *SubstFunctionType(FunctionDecl *D,
724 SmallVectorImpl<ParmVarDecl *> &Params);
725 bool InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl);
726 bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl);
727
728 bool SubstDefaultedFunction(FunctionDecl *New, FunctionDecl *Tmpl);
729
730 TemplateParameterList *
731 SubstTemplateParams(TemplateParameterList *List);
732
733 bool SubstQualifier(const DeclaratorDecl *OldDecl,
734 DeclaratorDecl *NewDecl);
735 bool SubstQualifier(const TagDecl *OldDecl,
736 TagDecl *NewDecl);
737
738 VarTemplateSpecializationDecl *VisitVarTemplateSpecializationDecl(
739 VarTemplateDecl *VarTemplate, VarDecl *FromVar,
740 ArrayRef<TemplateArgument> Converted,
741 VarTemplateSpecializationDecl *PrevDecl = nullptr);
742
743 Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias);
744 Decl *InstantiateTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
745 ClassTemplatePartialSpecializationDecl *
746 InstantiateClassTemplatePartialSpecialization(
747 ClassTemplateDecl *ClassTemplate,
748 ClassTemplatePartialSpecializationDecl *PartialSpec);
749 VarTemplatePartialSpecializationDecl *
750 InstantiateVarTemplatePartialSpecialization(
751 VarTemplateDecl *VarTemplate,
752 VarTemplatePartialSpecializationDecl *PartialSpec);
753 void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern);
754
755 private:
756 template<typename T>
757 Decl *instantiateUnresolvedUsingDecl(T *D,
758 bool InstantiatingPackElement = false);
759 };
760
761} // namespace clang
762
763#endif // LLVM_CLANG_SEMA_TEMPLATE_H
764