clang 17.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->getCanonicalDecl(), Final}, Args});
217 }
218
220 assert(!NumRetainedOuterLevels &&
221 "substituted args outside retained args?");
223 TemplateArgumentLists.push_back({{}, Args});
224 }
225
226 void addOuterTemplateArguments(std::nullopt_t) {
227 assert(!NumRetainedOuterLevels &&
228 "substituted args outside retained args?");
229 TemplateArgumentLists.push_back({});
230 }
231
232 /// Replaces the current 'innermost' level with the provided argument list.
233 /// This is useful for type deduction cases where we need to get the entire
234 /// list from the AST, but then add the deduced innermost list.
235 void replaceInnermostTemplateArguments(Decl *AssociatedDecl, ArgList Args) {
236 assert((!TemplateArgumentLists.empty() || NumRetainedOuterLevels) &&
237 "Replacing in an empty list?");
238
239 if (!TemplateArgumentLists.empty()) {
240 assert((TemplateArgumentLists[0].AssociatedDeclAndFinal.getPointer() ||
241 TemplateArgumentLists[0].AssociatedDeclAndFinal.getPointer() ==
242 AssociatedDecl) &&
243 "Trying to change incorrect declaration?");
244 TemplateArgumentLists[0].Args = Args;
245 } else {
246 --NumRetainedOuterLevels;
247 TemplateArgumentLists.push_back(
248 {{AssociatedDecl, /*Final=*/false}, Args});
249 }
250 }
251
252 /// Add an outermost level that we are not substituting. We have no
253 /// arguments at this level, and do not remove it from the depth of inner
254 /// template parameters that we instantiate.
256 ++NumRetainedOuterLevels;
257 }
258 void addOuterRetainedLevels(unsigned Num) {
259 NumRetainedOuterLevels += Num;
260 }
261
262 /// Retrieve the innermost template argument list.
263 const ArgList &getInnermost() const {
264 return TemplateArgumentLists.front().Args;
265 }
266 /// Retrieve the outermost template argument list.
267 const ArgList &getOutermost() const {
268 return TemplateArgumentLists.back().Args;
269 }
270 ArgListsIterator begin() { return TemplateArgumentLists.begin(); }
271 ConstArgListsIterator begin() const {
272 return TemplateArgumentLists.begin();
273 }
274 ArgListsIterator end() { return TemplateArgumentLists.end(); }
275 ConstArgListsIterator end() const { return TemplateArgumentLists.end(); }
276
277 LLVM_DUMP_METHOD void dump() const {
278 LangOptions LO;
279 LO.CPlusPlus = true;
280 LO.Bool = true;
281 PrintingPolicy PP(LO);
282 llvm::errs() << "NumRetainedOuterLevels: " << NumRetainedOuterLevels
283 << "\n";
284 for (unsigned Depth = NumRetainedOuterLevels; Depth < getNumLevels();
285 ++Depth) {
286 llvm::errs() << Depth << ": ";
288 llvm::errs(),
289 TemplateArgumentLists[getNumLevels() - Depth - 1].Args, PP);
290 llvm::errs() << "\n";
291 }
292 }
293 };
294
295 /// The context in which partial ordering of function templates occurs.
296 enum TPOC {
297 /// Partial ordering of function templates for a function call.
299
300 /// Partial ordering of function templates for a call to a
301 /// conversion function.
303
304 /// Partial ordering of function templates in other contexts, e.g.,
305 /// taking the address of a function template or matching a function
306 /// template specialization to a function template.
308 };
309
310 // This is lame but unavoidable in a world without forward
311 // declarations of enums. The alternatives are to either pollute
312 // Sema.h (by including this file) or sacrifice type safety (by
313 // making Sema.h declare things as enums).
315 TPOC Value;
316
317 public:
319
320 operator TPOC() const { return Value; }
321 };
322
323 /// Captures a template argument whose value has been deduced
324 /// via c++ template argument deduction.
326 /// For a non-type template argument, whether the value was
327 /// deduced from an array bound.
328 bool DeducedFromArrayBound = false;
329
330 public:
332
334 bool DeducedFromArrayBound = false)
335 : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) {}
336
337 /// Construct an integral non-type template argument that
338 /// has been deduced, possibly from an array bound.
340 const llvm::APSInt &Value,
341 QualType ValueType,
342 bool DeducedFromArrayBound)
343 : TemplateArgument(Ctx, Value, ValueType),
344 DeducedFromArrayBound(DeducedFromArrayBound) {}
345
346 /// For a non-type template argument, determine whether the
347 /// template argument was deduced from an array bound.
348 bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; }
349
350 /// Specify whether the given non-type template argument
351 /// was deduced from an array bound.
352 void setDeducedFromArrayBound(bool Deduced) {
353 DeducedFromArrayBound = Deduced;
354 }
355 };
356
357 /// A stack-allocated class that identifies which local
358 /// variable declaration instantiations are present in this scope.
359 ///
360 /// A new instance of this class type will be created whenever we
361 /// instantiate a new function declaration, which will have its own
362 /// set of parameter declarations.
364 public:
365 /// A set of declarations.
367
368 private:
369 /// Reference to the semantic analysis that is performing
370 /// this template instantiation.
371 Sema &SemaRef;
372
373 using LocalDeclsMap =
374 llvm::SmallDenseMap<const Decl *,
375 llvm::PointerUnion<Decl *, DeclArgumentPack *>, 4>;
376
377 /// A mapping from local declarations that occur
378 /// within a template to their instantiations.
379 ///
380 /// This mapping is used during instantiation to keep track of,
381 /// e.g., function parameter and variable declarations. For example,
382 /// given:
383 ///
384 /// \code
385 /// template<typename T> T add(T x, T y) { return x + y; }
386 /// \endcode
387 ///
388 /// when we instantiate add<int>, we will introduce a mapping from
389 /// the ParmVarDecl for 'x' that occurs in the template to the
390 /// instantiated ParmVarDecl for 'x'.
391 ///
392 /// For a parameter pack, the local instantiation scope may contain a
393 /// set of instantiated parameters. This is stored as a DeclArgumentPack
394 /// pointer.
395 LocalDeclsMap LocalDecls;
396
397 /// The set of argument packs we've allocated.
399
400 /// The outer scope, which contains local variable
401 /// definitions from some other instantiation (that may not be
402 /// relevant to this particular scope).
404
405 /// Whether we have already exited this scope.
406 bool Exited = false;
407
408 /// Whether to combine this scope with the outer scope, such that
409 /// lookup will search our outer scope.
410 bool CombineWithOuterScope;
411
412 /// If non-NULL, the template parameter pack that has been
413 /// partially substituted per C++0x [temp.arg.explicit]p9.
414 NamedDecl *PartiallySubstitutedPack = nullptr;
415
416 /// If \c PartiallySubstitutedPack is non-null, the set of
417 /// explicitly-specified template arguments in that pack.
418 const TemplateArgument *ArgsInPartiallySubstitutedPack;
419
420 /// If \c PartiallySubstitutedPack, the number of
421 /// explicitly-specified template arguments in
422 /// ArgsInPartiallySubstitutedPack.
423 unsigned NumArgsInPartiallySubstitutedPack;
424
425 public:
426 LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false)
427 : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope),
428 CombineWithOuterScope(CombineWithOuterScope) {
429 SemaRef.CurrentInstantiationScope = this;
430 }
431
435
437 Exit();
438 }
439
440 const Sema &getSema() const { return SemaRef; }
441
442 /// Exit this local instantiation scope early.
443 void Exit() {
444 if (Exited)
445 return;
446
447 for (unsigned I = 0, N = ArgumentPacks.size(); I != N; ++I)
448 delete ArgumentPacks[I];
449
450 SemaRef.CurrentInstantiationScope = Outer;
451 Exited = true;
452 }
453
454 /// Clone this scope, and all outer scopes, down to the given
455 /// outermost scope.
457 if (this == Outermost) return this;
458
459 // Save the current scope from SemaRef since the LocalInstantiationScope
460 // will overwrite it on construction
462
463 LocalInstantiationScope *newScope =
464 new LocalInstantiationScope(SemaRef, CombineWithOuterScope);
465
466 newScope->Outer = nullptr;
467 if (Outer)
468 newScope->Outer = Outer->cloneScopes(Outermost);
469
470 newScope->PartiallySubstitutedPack = PartiallySubstitutedPack;
471 newScope->ArgsInPartiallySubstitutedPack = ArgsInPartiallySubstitutedPack;
472 newScope->NumArgsInPartiallySubstitutedPack =
473 NumArgsInPartiallySubstitutedPack;
474
475 for (LocalDeclsMap::iterator I = LocalDecls.begin(), E = LocalDecls.end();
476 I != E; ++I) {
477 const Decl *D = I->first;
478 llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored =
479 newScope->LocalDecls[D];
480 if (I->second.is<Decl *>()) {
481 Stored = I->second.get<Decl *>();
482 } else {
483 DeclArgumentPack *OldPack = I->second.get<DeclArgumentPack *>();
484 DeclArgumentPack *NewPack = new DeclArgumentPack(*OldPack);
485 Stored = NewPack;
486 newScope->ArgumentPacks.push_back(NewPack);
487 }
488 }
489 // Restore the saved scope to SemaRef
490 SemaRef.CurrentInstantiationScope = oldScope;
491 return newScope;
492 }
493
494 /// deletes the given scope, and all outer scopes, down to the
495 /// given outermost scope.
497 LocalInstantiationScope *Outermost) {
498 while (Scope && Scope != Outermost) {
499 LocalInstantiationScope *Out = Scope->Outer;
500 delete Scope;
501 Scope = Out;
502 }
503 }
504
505 /// Find the instantiation of the declaration D within the current
506 /// instantiation scope.
507 ///
508 /// \param D The declaration whose instantiation we are searching for.
509 ///
510 /// \returns A pointer to the declaration or argument pack of declarations
511 /// to which the declaration \c D is instantiated, if found. Otherwise,
512 /// returns NULL.
513 llvm::PointerUnion<Decl *, DeclArgumentPack *> *
514 findInstantiationOf(const Decl *D);
515
516 void InstantiatedLocal(const Decl *D, Decl *Inst);
517 void InstantiatedLocalPackArg(const Decl *D, VarDecl *Inst);
518 void MakeInstantiatedLocalArgPack(const Decl *D);
519
520 /// Note that the given parameter pack has been partially substituted
521 /// via explicit specification of template arguments
522 /// (C++0x [temp.arg.explicit]p9).
523 ///
524 /// \param Pack The parameter pack, which will always be a template
525 /// parameter pack.
526 ///
527 /// \param ExplicitArgs The explicitly-specified template arguments provided
528 /// for this parameter pack.
529 ///
530 /// \param NumExplicitArgs The number of explicitly-specified template
531 /// arguments provided for this parameter pack.
533 const TemplateArgument *ExplicitArgs,
534 unsigned NumExplicitArgs);
535
536 /// Reset the partially-substituted pack when it is no longer of
537 /// interest.
539 assert(PartiallySubstitutedPack && "No partially-substituted pack");
540 PartiallySubstitutedPack = nullptr;
541 ArgsInPartiallySubstitutedPack = nullptr;
542 NumArgsInPartiallySubstitutedPack = 0;
543 }
544
545 /// Retrieve the partially-substitued template parameter pack.
546 ///
547 /// If there is no partially-substituted parameter pack, returns NULL.
548 NamedDecl *
549 getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs = nullptr,
550 unsigned *NumExplicitArgs = nullptr) const;
551
552 /// Determine whether D is a pack expansion created in this scope.
553 bool isLocalPackExpansion(const Decl *D);
554 };
555
557 : public DeclVisitor<TemplateDeclInstantiator, Decl *>
558 {
559 Sema &SemaRef;
561 DeclContext *Owner;
562 const MultiLevelTemplateArgumentList &TemplateArgs;
563 Sema::LateInstantiatedAttrVec* LateAttrs = nullptr;
564 LocalInstantiationScope *StartingScope = nullptr;
565 bool EvaluateConstraints = true;
566
567 /// A list of out-of-line class template partial
568 /// specializations that will need to be instantiated after the
569 /// enclosing class's instantiation is complete.
570 SmallVector<std::pair<ClassTemplateDecl *,
572 OutOfLinePartialSpecs;
573
574 /// A list of out-of-line variable template partial
575 /// specializations that will need to be instantiated after the
576 /// enclosing variable's instantiation is complete.
577 /// FIXME: Verify that this is needed.
579 std::pair<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>, 4>
580 OutOfLineVarPartialSpecs;
581
582 public:
584 const MultiLevelTemplateArgumentList &TemplateArgs)
585 : SemaRef(SemaRef),
586 SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex),
587 Owner(Owner), TemplateArgs(TemplateArgs) {}
588
590 EvaluateConstraints = B;
591 }
593 return EvaluateConstraints;
594 }
595
596// Define all the decl visitors using DeclNodes.inc
597#define DECL(DERIVED, BASE) \
598 Decl *Visit ## DERIVED ## Decl(DERIVED ## Decl *D);
599#define ABSTRACT_DECL(DECL)
600
601// Decls which never appear inside a class or function.
602#define OBJCCONTAINER(DERIVED, BASE)
603#define FILESCOPEASM(DERIVED, BASE)
604#define TOPLEVELSTMT(DERIVED, BASE)
605#define IMPORT(DERIVED, BASE)
606#define EXPORT(DERIVED, BASE)
607#define LINKAGESPEC(DERIVED, BASE)
608#define OBJCCOMPATIBLEALIAS(DERIVED, BASE)
609#define OBJCMETHOD(DERIVED, BASE)
610#define OBJCTYPEPARAM(DERIVED, BASE)
611#define OBJCIVAR(DERIVED, BASE)
612#define OBJCPROPERTY(DERIVED, BASE)
613#define OBJCPROPERTYIMPL(DERIVED, BASE)
614#define EMPTY(DERIVED, BASE)
615#define LIFETIMEEXTENDEDTEMPORARY(DERIVED, BASE)
616
617 // Decls which use special-case instantiation code.
618#define BLOCK(DERIVED, BASE)
619#define CAPTURED(DERIVED, BASE)
620#define IMPLICITPARAM(DERIVED, BASE)
621
622#include "clang/AST/DeclNodes.inc"
623
625
627 TypeSourceInfo *&TInfo,
628 DeclarationNameInfo &NameInfo);
629
630 // A few supplemental visitor functions.
632 TemplateParameterList *TemplateParams,
633 std::optional<const ASTTemplateArgumentListInfo *>
634 ClassScopeSpecializationArgs = std::nullopt,
637 TemplateParameterList *TemplateParams,
639 Decl *VisitDecl(Decl *D);
640 Decl *VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate,
643 LookupResult *Lookup);
644
645 // Enable late instantiation of attributes. Late instantiated attributes
646 // will be stored in LA.
648 LateAttrs = LA;
649 StartingScope = SemaRef.CurrentInstantiationScope;
650 }
651
652 // Disable late instantiation of attributes.
654 LateAttrs = nullptr;
655 StartingScope = nullptr;
656 }
657
658 LocalInstantiationScope *getStartingScope() const { return StartingScope; }
659
662
665
666 /// Return an iterator to the beginning of the set of
667 /// "delayed" partial specializations, which must be passed to
668 /// InstantiateClassTemplatePartialSpecialization once the class
669 /// definition has been completed.
671 return OutOfLinePartialSpecs.begin();
672 }
673
675 return OutOfLineVarPartialSpecs.begin();
676 }
677
678 /// Return an iterator to the end of the set of
679 /// "delayed" partial specializations, which must be passed to
680 /// InstantiateClassTemplatePartialSpecialization once the class
681 /// definition has been completed.
683 return OutOfLinePartialSpecs.end();
684 }
685
687 return OutOfLineVarPartialSpecs.end();
688 }
689
690 // Helper functions for instantiating methods.
695
697
700
701 bool SubstQualifier(const DeclaratorDecl *OldDecl,
702 DeclaratorDecl *NewDecl);
703 bool SubstQualifier(const TagDecl *OldDecl,
704 TagDecl *NewDecl);
705
707 VarTemplateDecl *VarTemplate, VarDecl *FromVar,
708 const TemplateArgumentListInfo &TemplateArgsInfo,
710 VarTemplateSpecializationDecl *PrevDecl = nullptr);
711
712 Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias);
715 ClassTemplateDecl *ClassTemplate,
719 VarTemplateDecl *VarTemplate,
722
723 private:
724 template<typename T>
725 Decl *instantiateUnresolvedUsingDecl(T *D,
726 bool InstantiatingPackElement = false);
727 };
728
729} // namespace clang
730
731#endif // LLVM_CLANG_SEMA_TEMPLATE_H
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:182
Represents a C++ declaration that introduces decls from somewhere else.
Definition: DeclCXX.h:3371
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2035
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:1402
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:83
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:946
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:765
Captures a template argument whose value has been deduced via c++ template argument deduction.
Definition: Template.h:325
void setDeducedFromArrayBound(bool Deduced)
Specify whether the given non-type template argument was deduced from an array bound.
Definition: Template.h:352
DeducedTemplateArgument(const TemplateArgument &Arg, bool DeducedFromArrayBound=false)
Definition: Template.h:333
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:339
bool wasDeducedFromArrayBound() const
For a non-type template argument, determine whether the template argument was deduced from an array b...
Definition: Template.h:348
Represents an enum.
Definition: Decl.h:3734
Represents a function declaration or definition.
Definition: Decl.h:1917
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:82
A stack-allocated class that identifies which local variable declaration instantiations are present i...
Definition: Template.h:363
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:443
SmallVector< VarDecl *, 4 > DeclArgumentPack
A set of declarations.
Definition: Template.h:366
bool isLocalPackExpansion(const Decl *D)
Determine whether D is a pack expansion created in this scope.
static void deleteScopes(LocalInstantiationScope *Scope, LocalInstantiationScope *Outermost)
deletes the given scope, and all outer scopes, down to the given outermost scope.
Definition: Template.h:496
const Sema & getSema() const
Definition: Template.h:440
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:538
LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope=false)
Definition: Template.h:426
LocalInstantiationScope * cloneScopes(LocalInstantiationScope *Outermost)
Clone this scope, and all outer scopes, down to the given outermost scope.
Definition: Template.h:456
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:275
const ArgList & getInnermost() const
Retrieve the innermost template argument list.
Definition: Template.h:263
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:255
ConstArgListsIterator begin() const
Definition: Template.h:271
LLVM_DUMP_METHOD void dump() const
Definition: Template.h:277
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:235
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:267
void addOuterRetainedLevels(unsigned Num)
Definition: Template.h:258
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:226
void addOuterTemplateArguments(ArgList Args)
Definition: Template.h:219
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:247
A (possibly-)qualified type.
Definition: Type.h:736
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:9478
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:356
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
Definition: Sema.h:9838
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3454
A convenient class for passing around template argument information.
Definition: TemplateBase.h:590
Represents a template argument.
Definition: TemplateBase.h:60
bool isInstantiationDependent() const
Whether this template argument is dependent on a template parameter.
void enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec *LA)
Definition: Template.h:647
delayed_var_partial_spec_iterator delayed_var_partial_spec_end()
Definition: Template.h:686
delayed_partial_spec_iterator delayed_partial_spec_begin()
Return an iterator to the beginning of the set of "delayed" partial specializations,...
Definition: Template.h:670
void setEvaluateConstraints(bool B)
Definition: Template.h:589
TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner, const MultiLevelTemplateArgumentList &TemplateArgs)
Definition: Template.h:583
SmallVectorImpl< std::pair< VarTemplateDecl *, VarTemplatePartialSpecializationDecl * > >::iterator delayed_var_partial_spec_iterator
Definition: Template.h:664
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:658
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:661
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, std::optional< const ASTTemplateArgumentListInfo * > ClassScopeSpecializationArgs=std::nullopt, RewriteKind RK=RewriteKind::None)
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:682
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:674
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
A container of type source information.
Definition: Type.h:6635
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3304
Represents a variable declaration or definition.
Definition: Decl.h:913
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 ...
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...
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:296
@ TPOC_Conversion
Partial ordering of function templates for a call to a conversion function.
Definition: Template.h:302
@ TPOC_Other
Partial ordering of function templates in other contexts, e.g., taking the address of a function temp...
Definition: Template.h:307
@ TPOC_Call
Partial ordering of function templates for a function call.
Definition: Template.h:298
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