clang 20.0.0git
Template.h
Go to the documentation of this file.
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
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.
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.
77 /// The template argument list at a certain template depth
78
80 struct ArgumentListLevel {
81 llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndFinal;
82 ArgList Args;
83 };
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.
99
100 public:
101 /// Construct an empty set of template argument lists.
103
104 /// Construct a single-level template argument list.
106 addOuterTemplateArguments(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 {
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
189 for (ArgumentListLevel ListLevel : TemplateArgumentLists)
190 for (const TemplateArgument &TA : ListLevel.Args)
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?");
215 TemplateArgumentLists.push_back(
216 {{AssociatedDecl ? AssociatedDecl->getCanonicalDecl() : nullptr,
217 Final},
218 Args});
219 }
220
222 assert(!NumRetainedOuterLevels &&
223 "substituted args outside retained args?");
225 TemplateArgumentLists.push_back({{}, Args});
226 }
227
228 void addOuterTemplateArguments(std::nullopt_t) {
229 assert(!NumRetainedOuterLevels &&
230 "substituted args outside retained args?");
231 TemplateArgumentLists.push_back({});
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 {{AssociatedDecl, /*Final=*/false}, 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.
258 ++NumRetainedOuterLevels;
259 }
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 << ": ";
290 llvm::errs(),
291 TemplateArgumentLists[getNumLevels() - Depth - 1].Args, 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.
301
302 /// Partial ordering of function templates for a call to a
303 /// conversion function.
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.
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).
317 TPOC Value;
318
319 public:
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.
328 /// For a non-type template argument, whether the value was
329 /// deduced from an array bound.
330 bool DeducedFromArrayBound = false;
331
332 public:
334
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.
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.
366 public:
367 /// A set of declarations.
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.
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).
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 /// Whether this scope is being used to instantiate a lambda or block
415 /// expression, in which case it should be reused for instantiating the
416 /// lambda's FunctionProtoType.
417 bool InstantiatingLambdaOrBlock = false;
418
419 /// If non-NULL, the template parameter pack that has been
420 /// partially substituted per C++0x [temp.arg.explicit]p9.
421 NamedDecl *PartiallySubstitutedPack = nullptr;
422
423 /// If \c PartiallySubstitutedPack is non-null, the set of
424 /// explicitly-specified template arguments in that pack.
425 const TemplateArgument *ArgsInPartiallySubstitutedPack;
426
427 /// If \c PartiallySubstitutedPack, the number of
428 /// explicitly-specified template arguments in
429 /// ArgsInPartiallySubstitutedPack.
430 unsigned NumArgsInPartiallySubstitutedPack;
431
432 public:
433 LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false,
434 bool InstantiatingLambdaOrBlock = false)
435 : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope),
436 CombineWithOuterScope(CombineWithOuterScope),
437 InstantiatingLambdaOrBlock(InstantiatingLambdaOrBlock) {
438 SemaRef.CurrentInstantiationScope = this;
439 }
440
444
446 Exit();
447 }
448
449 const Sema &getSema() const { return SemaRef; }
450
451 /// Exit this local instantiation scope early.
452 void Exit() {
453 if (Exited)
454 return;
455
456 for (unsigned I = 0, N = ArgumentPacks.size(); I != N; ++I)
457 delete ArgumentPacks[I];
458
459 SemaRef.CurrentInstantiationScope = Outer;
460 Exited = true;
461 }
462
463 /// Clone this scope, and all outer scopes, down to the given
464 /// outermost scope.
466 if (this == Outermost) return this;
467
468 // Save the current scope from SemaRef since the LocalInstantiationScope
469 // will overwrite it on construction
471
472 LocalInstantiationScope *newScope =
473 new LocalInstantiationScope(SemaRef, CombineWithOuterScope);
474
475 newScope->Outer = nullptr;
476 if (Outer)
477 newScope->Outer = Outer->cloneScopes(Outermost);
478
479 newScope->PartiallySubstitutedPack = PartiallySubstitutedPack;
480 newScope->ArgsInPartiallySubstitutedPack = ArgsInPartiallySubstitutedPack;
481 newScope->NumArgsInPartiallySubstitutedPack =
482 NumArgsInPartiallySubstitutedPack;
483
484 for (LocalDeclsMap::iterator I = LocalDecls.begin(), E = LocalDecls.end();
485 I != E; ++I) {
486 const Decl *D = I->first;
487 llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored =
488 newScope->LocalDecls[D];
489 if (auto *D2 = dyn_cast<Decl *>(I->second)) {
490 Stored = D2;
491 } else {
492 DeclArgumentPack *OldPack = cast<DeclArgumentPack *>(I->second);
493 DeclArgumentPack *NewPack = new DeclArgumentPack(*OldPack);
494 Stored = NewPack;
495 newScope->ArgumentPacks.push_back(NewPack);
496 }
497 }
498 // Restore the saved scope to SemaRef
499 SemaRef.CurrentInstantiationScope = oldScope;
500 return newScope;
501 }
502
503 /// deletes the given scope, and all outer scopes, down to the
504 /// given outermost scope.
506 LocalInstantiationScope *Outermost) {
507 while (Scope && Scope != Outermost) {
508 LocalInstantiationScope *Out = Scope->Outer;
509 delete Scope;
510 Scope = Out;
511 }
512 }
513
514 /// Find the instantiation of the declaration D within the current
515 /// instantiation scope.
516 ///
517 /// \param D The declaration whose instantiation we are searching for.
518 ///
519 /// \returns A pointer to the declaration or argument pack of declarations
520 /// to which the declaration \c D is instantiated, if found. Otherwise,
521 /// returns NULL.
522 llvm::PointerUnion<Decl *, DeclArgumentPack *> *
523 findInstantiationOf(const Decl *D);
524
525 /// Similar to \p findInstantiationOf(), but it wouldn't assert if the
526 /// instantiation was not found within the current instantiation scope. This
527 /// is helpful for on-demand declaration instantiation.
528 llvm::PointerUnion<Decl *, DeclArgumentPack *> *
530
531 void InstantiatedLocal(const Decl *D, Decl *Inst);
532 void InstantiatedLocalPackArg(const Decl *D, VarDecl *Inst);
534
535 /// Note that the given parameter pack has been partially substituted
536 /// via explicit specification of template arguments
537 /// (C++0x [temp.arg.explicit]p9).
538 ///
539 /// \param Pack The parameter pack, which will always be a template
540 /// parameter pack.
541 ///
542 /// \param ExplicitArgs The explicitly-specified template arguments provided
543 /// for this parameter pack.
544 ///
545 /// \param NumExplicitArgs The number of explicitly-specified template
546 /// arguments provided for this parameter pack.
548 const TemplateArgument *ExplicitArgs,
549 unsigned NumExplicitArgs);
550
551 /// Reset the partially-substituted pack when it is no longer of
552 /// interest.
554 assert(PartiallySubstitutedPack && "No partially-substituted pack");
555 PartiallySubstitutedPack = nullptr;
556 ArgsInPartiallySubstitutedPack = nullptr;
557 NumArgsInPartiallySubstitutedPack = 0;
558 }
559
560 /// Retrieve the partially-substitued template parameter pack.
561 ///
562 /// If there is no partially-substituted parameter pack, returns NULL.
563 NamedDecl *
564 getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs = nullptr,
565 unsigned *NumExplicitArgs = nullptr) const;
566
567 /// Determine whether D is a pack expansion created in this scope.
568 bool isLocalPackExpansion(const Decl *D);
569
570 /// Determine whether this scope is for instantiating a lambda or block.
571 bool isLambdaOrBlock() const { return InstantiatingLambdaOrBlock; }
572 };
573
575 : public DeclVisitor<TemplateDeclInstantiator, Decl *>
576 {
577 Sema &SemaRef;
579 DeclContext *Owner;
580 const MultiLevelTemplateArgumentList &TemplateArgs;
581 Sema::LateInstantiatedAttrVec* LateAttrs = nullptr;
582 LocalInstantiationScope *StartingScope = nullptr;
583 // Whether to evaluate the C++20 constraints or simply substitute into them.
584 bool EvaluateConstraints = true;
585
586 /// A list of out-of-line class template partial
587 /// specializations that will need to be instantiated after the
588 /// enclosing class's instantiation is complete.
589 SmallVector<std::pair<ClassTemplateDecl *,
591 OutOfLinePartialSpecs;
592
593 /// A list of out-of-line variable template partial
594 /// specializations that will need to be instantiated after the
595 /// enclosing variable's instantiation is complete.
596 /// FIXME: Verify that this is needed.
598 std::pair<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>, 4>
599 OutOfLineVarPartialSpecs;
600
601 public:
603 const MultiLevelTemplateArgumentList &TemplateArgs)
604 : SemaRef(SemaRef),
605 SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex),
606 Owner(Owner), TemplateArgs(TemplateArgs) {}
607
609 EvaluateConstraints = B;
610 }
612 return EvaluateConstraints;
613 }
614
615// Define all the decl visitors using DeclNodes.inc
616#define DECL(DERIVED, BASE) \
617 Decl *Visit ## DERIVED ## Decl(DERIVED ## Decl *D);
618#define ABSTRACT_DECL(DECL)
619
620// Decls which never appear inside a class or function.
621#define OBJCCONTAINER(DERIVED, BASE)
622#define FILESCOPEASM(DERIVED, BASE)
623#define TOPLEVELSTMT(DERIVED, BASE)
624#define IMPORT(DERIVED, BASE)
625#define EXPORT(DERIVED, BASE)
626#define LINKAGESPEC(DERIVED, BASE)
627#define OBJCCOMPATIBLEALIAS(DERIVED, BASE)
628#define OBJCMETHOD(DERIVED, BASE)
629#define OBJCTYPEPARAM(DERIVED, BASE)
630#define OBJCIVAR(DERIVED, BASE)
631#define OBJCPROPERTY(DERIVED, BASE)
632#define OBJCPROPERTYIMPL(DERIVED, BASE)
633#define EMPTY(DERIVED, BASE)
634#define LIFETIMEEXTENDEDTEMPORARY(DERIVED, BASE)
635
636 // Decls which use special-case instantiation code.
637#define BLOCK(DERIVED, BASE)
638#define CAPTURED(DERIVED, BASE)
639#define IMPLICITPARAM(DERIVED, BASE)
640
641#include "clang/AST/DeclNodes.inc"
642
644
646 TypeSourceInfo *&TInfo,
647 DeclarationNameInfo &NameInfo);
648
649 // A few supplemental visitor functions.
651 TemplateParameterList *TemplateParams,
654 TemplateParameterList *TemplateParams,
656 Decl *VisitDecl(Decl *D);
657 Decl *VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate,
660 LookupResult *Lookup);
661
662 // Enable late instantiation of attributes. Late instantiated attributes
663 // will be stored in LA.
665 LateAttrs = LA;
666 StartingScope = SemaRef.CurrentInstantiationScope;
667 }
668
669 // Disable late instantiation of attributes.
671 LateAttrs = nullptr;
672 StartingScope = nullptr;
673 }
674
675 LocalInstantiationScope *getStartingScope() const { return StartingScope; }
676
679
682
683 /// Return an iterator to the beginning of the set of
684 /// "delayed" partial specializations, which must be passed to
685 /// InstantiateClassTemplatePartialSpecialization once the class
686 /// definition has been completed.
688 return OutOfLinePartialSpecs.begin();
689 }
690
692 return OutOfLineVarPartialSpecs.begin();
693 }
694
695 /// Return an iterator to the end of the set of
696 /// "delayed" partial specializations, which must be passed to
697 /// InstantiateClassTemplatePartialSpecialization once the class
698 /// definition has been completed.
700 return OutOfLinePartialSpecs.end();
701 }
702
704 return OutOfLineVarPartialSpecs.end();
705 }
706
707 // Helper functions for instantiating methods.
712
714
717
718 bool SubstQualifier(const DeclaratorDecl *OldDecl,
719 DeclaratorDecl *NewDecl);
720 bool SubstQualifier(const TagDecl *OldDecl,
721 TagDecl *NewDecl);
722
724 VarTemplateDecl *VarTemplate, VarDecl *FromVar,
725 const TemplateArgumentListInfo &TemplateArgsInfo,
727 VarTemplateSpecializationDecl *PrevDecl = nullptr);
728
733 ClassTemplateDecl *ClassTemplate,
737 VarTemplateDecl *VarTemplate,
740
741 private:
742 template<typename T>
743 Decl *instantiateUnresolvedUsingDecl(T *D,
744 bool InstantiatingPackElement = false);
745 };
746
747} // namespace clang
748
749#endif // LLVM_CLANG_SEMA_TEMPLATE_H
const Decl * D
Expr * E
Defines the C++ template declaration subclasses.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
Represents a C++ declaration that introduces decls from somewhere else.
Definition: DeclCXX.h:3435
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2078
Declaration of a class template.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1435
A simple visitor class that helps create declaration visitors.
Definition: DeclVisitor.h:67
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:967
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:735
Captures a template argument whose value has been deduced via c++ template argument deduction.
Definition: Template.h:327
void setDeducedFromArrayBound(bool Deduced)
Specify whether the given non-type template argument was deduced from an array bound.
Definition: Template.h:354
DeducedTemplateArgument(const TemplateArgument &Arg, bool DeducedFromArrayBound=false)
Definition: Template.h:335
DeducedTemplateArgument(ASTContext &Ctx, const llvm::APSInt &Value, QualType ValueType, bool DeducedFromArrayBound)
Construct an integral non-type template argument that has been deduced, possibly from an array bound.
Definition: Template.h:341
bool wasDeducedFromArrayBound() const
For a non-type template argument, determine whether the template argument was deduced from an array b...
Definition: Template.h:350
Represents an enum.
Definition: Decl.h:3847
Represents a function declaration or definition.
Definition: Decl.h:1935
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:499
A stack-allocated class that identifies which local variable declaration instantiations are present i...
Definition: Template.h:365
LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope=false, bool InstantiatingLambdaOrBlock=false)
Definition: Template.h:433
LocalInstantiationScope & operator=(const LocalInstantiationScope &)=delete
LocalInstantiationScope(const LocalInstantiationScope &)=delete
void SetPartiallySubstitutedPack(NamedDecl *Pack, const TemplateArgument *ExplicitArgs, unsigned NumExplicitArgs)
Note that the given parameter pack has been partially substituted via explicit specification of templ...
NamedDecl * getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs=nullptr, unsigned *NumExplicitArgs=nullptr) const
Retrieve the partially-substitued template parameter pack.
void Exit()
Exit this local instantiation scope early.
Definition: Template.h:452
SmallVector< VarDecl *, 4 > DeclArgumentPack
A set of declarations.
Definition: Template.h:368
bool isLocalPackExpansion(const Decl *D)
Determine whether D is a pack expansion created in this scope.
llvm::PointerUnion< Decl *, DeclArgumentPack * > * findInstantiationUnsafe(const Decl *D)
Similar to findInstantiationOf(), but it wouldn't assert if the instantiation was not found within th...
static void deleteScopes(LocalInstantiationScope *Scope, LocalInstantiationScope *Outermost)
deletes the given scope, and all outer scopes, down to the given outermost scope.
Definition: Template.h:505
const Sema & getSema() const
Definition: Template.h:449
void InstantiatedLocal(const Decl *D, Decl *Inst)
void InstantiatedLocalPackArg(const Decl *D, VarDecl *Inst)
void ResetPartiallySubstitutedPack()
Reset the partially-substituted pack when it is no longer of interest.
Definition: Template.h:553
bool isLambdaOrBlock() const
Determine whether this scope is for instantiating a lambda or block.
Definition: Template.h:571
LocalInstantiationScope * cloneScopes(LocalInstantiationScope *Outermost)
Clone this scope, and all outer scopes, down to the given outermost scope.
Definition: Template.h:465
llvm::PointerUnion< Decl *, DeclArgumentPack * > * findInstantiationOf(const Decl *D)
Find the instantiation of the declaration D within the current instantiation scope.
Represents the results of name lookup.
Definition: Lookup.h:46
Data structure that captures multiple levels of template argument lists for use in template instantia...
Definition: Template.h:76
bool hasTemplateArgument(unsigned Depth, unsigned Index) const
Determine whether there is a non-NULL template argument at the given depth and index.
Definition: Template.h:175
ConstArgListsIterator end() const
Definition: Template.h:277
const ArgList & getInnermost() const
Retrieve the innermost template argument list.
Definition: Template.h:265
unsigned getNumSubsitutedArgs(unsigned Depth) const
Definition: Template.h:134
std::pair< Decl *, bool > getAssociatedDecl(unsigned Depth) const
A template-like entity which owns the whole pattern being substituted.
Definition: Template.h:164
void addOuterRetainedLevel()
Add an outermost level that we are not substituting.
Definition: Template.h:257
ConstArgListsIterator begin() const
Definition: Template.h:273
LLVM_DUMP_METHOD void dump() const
Definition: Template.h:279
MultiLevelTemplateArgumentList(Decl *D, ArgList Args, bool Final)
Construct a single-level template argument list.
Definition: Template.h:105
TemplateSubstitutionKind getKind() const
Determine the kind of template substitution being performed.
Definition: Template.h:112
void addOuterTemplateArguments(Decl *AssociatedDecl, ArgList Args, bool Final)
Add a new outmost level to the multi-level template argument list.
Definition: Template.h:210
unsigned getNumLevels() const
Determine the number of levels in this template argument list.
Definition: Template.h:123
void setKind(TemplateSubstitutionKind K)
Definition: Template.h:109
void replaceInnermostTemplateArguments(Decl *AssociatedDecl, ArgList Args)
Replaces the current 'innermost' level with the provided argument list.
Definition: Template.h:237
unsigned getNumSubstitutedLevels() const
Determine the number of substituted levels in this template argument list.
Definition: Template.h:129
const TemplateArgument & operator()(unsigned Depth, unsigned Index) const
Retrieve the template argument at a given depth and index.
Definition: Template.h:154
const ArgList & getOutermost() const
Retrieve the outermost template argument list.
Definition: Template.h:269
void addOuterRetainedLevels(unsigned Num)
Definition: Template.h:260
MultiLevelTemplateArgumentList()=default
Construct an empty set of template argument lists.
unsigned getNumRetainedOuterLevels() const
Definition: Template.h:139
unsigned getNewDepth(unsigned OldDepth) const
Determine how many of the OldDepth outermost template parameter lists would be removed by substitutin...
Definition: Template.h:145
void setArgument(unsigned Depth, unsigned Index, TemplateArgument Arg)
Clear out a specific template argument.
Definition: Template.h:197
void addOuterTemplateArguments(std::nullopt_t)
Definition: Template.h:228
void addOuterTemplateArguments(ArgList Args)
Definition: Template.h:221
bool isRewrite() const
Determine whether we are rewriting template parameters rather than substituting for them.
Definition: Template.h:117
This represents a decl that may have a name.
Definition: Decl.h:253
A (possibly-)qualified type.
Definition: Type.h:929
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:41
RAII object used to change the argument pack substitution index within a Sema object.
Definition: Sema.h:13212
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:464
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
Definition: Sema.h:12643
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3564
A convenient class for passing around template argument information.
Definition: TemplateBase.h:632
Represents a template argument.
Definition: TemplateBase.h:61
bool isInstantiationDependent() const
Whether this template argument is dependent on a template parameter.
void enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec *LA)
Definition: Template.h:664
delayed_var_partial_spec_iterator delayed_var_partial_spec_end()
Definition: Template.h:703
delayed_partial_spec_iterator delayed_partial_spec_begin()
Return an iterator to the beginning of the set of "delayed" partial specializations,...
Definition: Template.h:687
void setEvaluateConstraints(bool B)
Definition: Template.h:608
TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner, const MultiLevelTemplateArgumentList &TemplateArgs)
Definition: Template.h:602
SmallVectorImpl< std::pair< VarTemplateDecl *, VarTemplatePartialSpecializationDecl * > >::iterator delayed_var_partial_spec_iterator
Definition: Template.h:681
Decl * VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate, ArrayRef< BindingDecl * > *Bindings=nullptr)
bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl)
Initializes common fields of an instantiated method declaration (New) from the corresponding fields o...
LocalInstantiationScope * getStartingScope() const
Definition: Template.h:675
bool InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl)
Initializes the common fields of an instantiation function declaration (New) from the corresponding f...
VarTemplatePartialSpecializationDecl * InstantiateVarTemplatePartialSpecialization(VarTemplateDecl *VarTemplate, VarTemplatePartialSpecializationDecl *PartialSpec)
Instantiate the declaration of a variable template partial specialization.
void adjustForRewrite(RewriteKind RK, FunctionDecl *Orig, QualType &T, TypeSourceInfo *&TInfo, DeclarationNameInfo &NameInfo)
TypeSourceInfo * SubstFunctionType(FunctionDecl *D, SmallVectorImpl< ParmVarDecl * > &Params)
SmallVectorImpl< std::pair< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > >::iterator delayed_partial_spec_iterator
Definition: Template.h:678
Decl * VisitVarTemplateSpecializationDecl(VarTemplateDecl *VarTemplate, VarDecl *FromVar, const TemplateArgumentListInfo &TemplateArgsInfo, ArrayRef< TemplateArgument > Converted, VarTemplateSpecializationDecl *PrevDecl=nullptr)
void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern)
Decl * VisitFunctionDecl(FunctionDecl *D, TemplateParameterList *TemplateParams, RewriteKind RK=RewriteKind::None)
Normal class members are of more specific types and therefore don't make it here.
Decl * VisitCXXMethodDecl(CXXMethodDecl *D, TemplateParameterList *TemplateParams, RewriteKind RK=RewriteKind::None)
Decl * InstantiateTypeAliasTemplateDecl(TypeAliasTemplateDecl *D)
delayed_partial_spec_iterator delayed_partial_spec_end()
Return an iterator to the end of the set of "delayed" partial specializations, which must be passed t...
Definition: Template.h:699
Decl * VisitBaseUsingDecls(BaseUsingDecl *D, BaseUsingDecl *Inst, LookupResult *Lookup)
bool SubstQualifier(const DeclaratorDecl *OldDecl, DeclaratorDecl *NewDecl)
TemplateParameterList * SubstTemplateParams(TemplateParameterList *List)
Instantiates a nested template parameter list in the current instantiation context.
Decl * InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias)
delayed_var_partial_spec_iterator delayed_var_partial_spec_begin()
Definition: Template.h:691
ClassTemplatePartialSpecializationDecl * InstantiateClassTemplatePartialSpecialization(ClassTemplateDecl *ClassTemplate, ClassTemplatePartialSpecializationDecl *PartialSpec)
Instantiate the declaration of a class template partial specialization.
bool SubstDefaultedFunction(FunctionDecl *New, FunctionDecl *Tmpl)
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:73
Declaration of an alias template.
A container of type source information.
Definition: Type.h:7902
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3413
Represents a variable declaration or definition.
Definition: Decl.h:882
Declaration of a variable template.
Represents a variable template specialization, which refers to a variable template with a given set o...
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
The JSON file list parser is used to communicate input to InstallAPI.
TemplateSubstitutionKind
The kind of template substitution being performed.
Definition: Template.h:47
@ Rewrite
We are substituting template parameters for (typically) other template parameters in order to rewrite...
@ Specialization
We are substituting template parameters for template arguments in order to form a template specializa...
const FunctionProtoType * T
void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL=nullptr)
Print a template argument list, including the '<' and '>' enclosing the template arguments.
TPOC
The context in which partial ordering of function templates occurs.
Definition: Template.h:298
@ TPOC_Conversion
Partial ordering of function templates for a call to a conversion function.
Definition: Template.h:304
@ TPOC_Other
Partial ordering of function templates in other contexts, e.g., taking the address of a function temp...
Definition: Template.h:309
@ TPOC_Call
Partial ordering of function templates for a function call.
Definition: Template.h:300
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57