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

source code of clang/include/clang/Sema/Template.h