Go to the documentation of this file.
12 #ifndef LLVM_CLANG_SEMA_TEMPLATE_H
13 #define LLVM_CLANG_SEMA_TEMPLATE_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"
42 class TypedefNameDecl;
80 struct ArgumentListLevel {
81 llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndFinal;
86 using ArgListsIterator = ContainerType::iterator;
87 using ConstArgListsIterator = ContainerType::const_iterator;
95 unsigned NumRetainedOuterLevels = 0;
124 return TemplateArgumentLists.size() + NumRetainedOuterLevels;
130 return TemplateArgumentLists.size();
140 return NumRetainedOuterLevels;
146 if (OldDepth < NumRetainedOuterLevels)
149 return NumRetainedOuterLevels;
150 return OldDepth - TemplateArgumentLists.size();
167 .AssociatedDeclAndFinal;
168 return {AD.getPointer(), AD.getInt()};
178 if (
Depth < NumRetainedOuterLevels)
185 return !(*this)(
Depth, Index).isNull();
189 for (ArgumentListLevel ListLevel : TemplateArgumentLists)
212 assert(!NumRetainedOuterLevels &&
213 "substituted args outside retained args?");
215 TemplateArgumentLists.push_back(
220 assert(!NumRetainedOuterLevels &&
221 "substituted args outside retained args?");
223 TemplateArgumentLists.push_back({{}, Args});
227 assert(!NumRetainedOuterLevels &&
228 "substituted args outside retained args?");
229 TemplateArgumentLists.push_back({});
236 assert(TemplateArgumentLists.size() > 0 &&
"Replacing in an empty list?");
237 TemplateArgumentLists[0].Args = Args;
244 ++NumRetainedOuterLevels;
247 NumRetainedOuterLevels += Num;
252 return TemplateArgumentLists.front().Args;
256 return TemplateArgumentLists.back().Args;
258 ArgListsIterator
begin() {
return TemplateArgumentLists.begin(); }
259 ConstArgListsIterator
begin()
const {
260 return TemplateArgumentLists.begin();
262 ArgListsIterator
end() {
return TemplateArgumentLists.end(); }
263 ConstArgListsIterator
end()
const {
return TemplateArgumentLists.end(); }
299 bool DeducedFromArrayBound =
false;
305 bool DeducedFromArrayBound =
false)
313 bool DeducedFromArrayBound)
315 DeducedFromArrayBound(DeducedFromArrayBound) {}
324 DeducedFromArrayBound = Deduced;
344 using LocalDeclsMap =
345 llvm::SmallDenseMap<
const Decl *,
346 llvm::PointerUnion<Decl *, DeclArgumentPack *>, 4>;
366 LocalDeclsMap LocalDecls;
381 bool CombineWithOuterScope;
385 NamedDecl *PartiallySubstitutedPack =
nullptr;
394 unsigned NumArgsInPartiallySubstitutedPack;
398 : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope),
399 CombineWithOuterScope(CombineWithOuterScope) {
418 for (
unsigned I = 0, N = ArgumentPacks.size(); I != N; ++I)
419 delete ArgumentPacks[I];
428 if (
this == Outermost)
return this;
437 newScope->Outer =
nullptr;
441 newScope->PartiallySubstitutedPack = PartiallySubstitutedPack;
442 newScope->ArgsInPartiallySubstitutedPack = ArgsInPartiallySubstitutedPack;
443 newScope->NumArgsInPartiallySubstitutedPack =
444 NumArgsInPartiallySubstitutedPack;
446 for (LocalDeclsMap::iterator I = LocalDecls.begin(), E = LocalDecls.end();
448 const Decl *D = I->first;
449 llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored =
450 newScope->LocalDecls[D];
451 if (I->second.is<
Decl *>()) {
452 Stored = I->second.get<
Decl *>();
457 newScope->ArgumentPacks.push_back(NewPack);
484 llvm::PointerUnion<Decl *, DeclArgumentPack *> *
505 unsigned NumExplicitArgs);
510 assert(PartiallySubstitutedPack &&
"No partially-substituted pack");
511 PartiallySubstitutedPack =
nullptr;
512 ArgsInPartiallySubstitutedPack =
nullptr;
513 NumArgsInPartiallySubstitutedPack = 0;
521 unsigned *NumExplicitArgs =
nullptr)
const;
528 :
public DeclVisitor<TemplateDeclInstantiator, Decl *>
536 bool EvaluateConstraints =
true;
543 OutOfLinePartialSpecs;
550 std::pair<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>, 4>
551 OutOfLineVarPartialSpecs;
557 SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex),
558 Owner(Owner), TemplateArgs(TemplateArgs) {}
561 EvaluateConstraints = B;
564 return EvaluateConstraints;
568 #define DECL(DERIVED, BASE) \
569 Decl *Visit ## DERIVED ## Decl(DERIVED ## Decl *D);
570 #define ABSTRACT_DECL(DECL)
573 #define OBJCCONTAINER(DERIVED, BASE)
574 #define FILESCOPEASM(DERIVED, BASE)
575 #define TOPLEVELSTMT(DERIVED, BASE)
576 #define IMPORT(DERIVED, BASE)
577 #define EXPORT(DERIVED, BASE)
578 #define LINKAGESPEC(DERIVED, BASE)
579 #define OBJCCOMPATIBLEALIAS(DERIVED, BASE)
580 #define OBJCMETHOD(DERIVED, BASE)
581 #define OBJCTYPEPARAM(DERIVED, BASE)
582 #define OBJCIVAR(DERIVED, BASE)
583 #define OBJCPROPERTY(DERIVED, BASE)
584 #define OBJCPROPERTYIMPL(DERIVED, BASE)
585 #define EMPTY(DERIVED, BASE)
586 #define LIFETIMEEXTENDEDTEMPORARY(DERIVED, BASE)
589 #define BLOCK(DERIVED, BASE)
590 #define CAPTURED(DERIVED, BASE)
591 #define IMPLICITPARAM(DERIVED, BASE)
593 #include "clang/AST/DeclNodes.inc"
604 std::optional<const ASTTemplateArgumentListInfo *>
605 ClassScopeSpecializationArgs = std::nullopt,
626 StartingScope =
nullptr;
642 return OutOfLinePartialSpecs.begin();
646 return OutOfLineVarPartialSpecs.begin();
654 return OutOfLinePartialSpecs.end();
658 return OutOfLineVarPartialSpecs.end();
696 Decl *instantiateUnresolvedUsingDecl(T *D,
697 bool InstantiatingPackElement =
false);
702 #endif // LLVM_CLANG_SEMA_TEMPLATE_H
void setArgument(unsigned Depth, unsigned Index, TemplateArgument Arg)
Clear out a specific template argument.
Decl * VisitVarTemplateSpecializationDecl(VarTemplateDecl *VarTemplate, VarDecl *FromVar, const TemplateArgumentListInfo &TemplateArgsInfo, ArrayRef< TemplateArgument > Converted, VarTemplateSpecializationDecl *PrevDecl=nullptr)
delayed_var_partial_spec_iterator delayed_var_partial_spec_begin()
void addOuterTemplateArguments(ArgList Args)
MultiLevelTemplateArgumentList(Decl *D, ArgList Args, bool Final)
Construct a single-level template argument list.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
void addOuterTemplateArguments(std::nullopt_t)
@ TPOC_Conversion
Partial ordering of function templates for a call to a conversion function.
This represents a decl that may have a name.
A (possibly-)qualified type.
TemplateSubstitutionKind getKind() const
Determine the kind of template substitution being performed.
TemplateParameterList * SubstTemplateParams(TemplateParameterList *List)
Instantiates a nested template parameter list in the current instantiation context.
@ Rewrite
We are substituting template parameters for (typically) other template parameters in order to rewrite...
Represents the results of name lookup.
SmallVectorImpl< std::pair< VarTemplateDecl *, VarTemplatePartialSpecializationDecl * > >::iterator delayed_var_partial_spec_iterator
DeducedTemplateArgument(const TemplateArgument &Arg, bool DeducedFromArrayBound=false)
@ RewriteSpaceshipAsEqualEqual
@ Specialization
We are substituting template parameters for template arguments in order to form a template specializa...
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.
std::pair< Decl *, bool > getAssociatedDecl(unsigned Depth) const
A template-like entity which owns the whole pattern being substituted.
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...
Captures a template argument whose value has been deduced via c++ template argument deduction.
static void deleteScopes(LocalInstantiationScope *Scope, LocalInstantiationScope *Outermost)
deletes the given scope, and all outer scopes, down to the given outermost scope.
const ArgList & getOutermost() const
Retrieve the outermost template argument list.
void disableLateAttributeInstantiation()
Represents a variable template specialization, which refers to a variable template with a given set o...
@ TPOC_Other
Partial ordering of function templates in other contexts, e.g., taking the address of a function temp...
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
bool SubstDefaultedFunction(FunctionDecl *New, FunctionDecl *Tmpl)
A convenient class for passing around template argument information.
RAII object used to change the argument pack substitution index within a Sema object.
bool getEvaluateConstraints()
Scope - A scope is a transient data structure that is used while parsing the program.
void addOuterTemplateArguments(Decl *AssociatedDecl, ArgList Args, bool Final)
Add a new outmost level to the multi-level template argument list.
Decl * VisitCXXMethodDecl(CXXMethodDecl *D, TemplateParameterList *TemplateParams, std::optional< const ASTTemplateArgumentListInfo * > ClassScopeSpecializationArgs=std::nullopt, RewriteKind RK=RewriteKind::None)
void adjustForRewrite(RewriteKind RK, FunctionDecl *Orig, QualType &T, TypeSourceInfo *&TInfo, DeclarationNameInfo &NameInfo)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
void Exit()
Exit this local instantiation scope early.
void setDeducedFromArrayBound(bool Deduced)
Specify whether the given non-type template argument was deduced from an array bound.
Represents a template argument.
Data structure that captures multiple levels of template argument lists for use in template instantia...
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
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.
Represents a variable declaration or definition.
Represents the declaration of a struct/union/class/enum.
Stores a list of template parameters for a TemplateDecl and its derived classes.
void setEvaluateConstraints(bool B)
unsigned getNumLevels() const
Determine the number of levels in this template argument list.
bool wasDeducedFromArrayBound() const
For a non-type template argument, determine whether the template argument was deduced from an array b...
Decl * VisitBaseUsingDecls(BaseUsingDecl *D, BaseUsingDecl *Inst, LookupResult *Lookup)
SmallVector< VarDecl *, 4 > DeclArgumentPack
A set of declarations.
unsigned getNumRetainedOuterLevels() const
~LocalInstantiationScope()
Decl * InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias)
bool isAnyArgInstantiationDependent() const
delayed_var_partial_spec_iterator delayed_var_partial_spec_end()
delayed_partial_spec_iterator delayed_partial_spec_begin()
Return an iterator to the beginning of the set of "delayed" partial specializations,...
bool SubstQualifier(const DeclaratorDecl *OldDecl, DeclaratorDecl *NewDecl)
NamedDecl * getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs=nullptr, unsigned *NumExplicitArgs=nullptr) const
Retrieve the partially-substitued template parameter pack.
LocalInstantiationScope * cloneScopes(LocalInstantiationScope *Outermost)
Clone this scope, and all outer scopes, down to the given outermost scope.
bool hasTemplateArgument(unsigned Depth, unsigned Index) const
Determine whether there is a non-NULL template argument at the given depth and index.
Declaration of a class template.
ConstArgListsIterator end() const
const Sema & getSema() const
TemplateSubstitutionKind
The kind of template substitution being performed.
void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern)
LocalInstantiationScope & operator=(const LocalInstantiationScope &)=delete
unsigned getNumSubsitutedArgs(unsigned Depth) const
Decl - This represents one declaration (or definition), e.g.
Represents a ValueDecl that came out of a declarator.
const ArgList & getInnermost() const
Retrieve the innermost template argument list.
Sema - This implements semantic analysis and AST building for C.
bool isInstantiationDependent() const
Whether this template argument is dependent on a template parameter.
Decl * VisitDecl(Decl *D)
bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl)
Initializes common fields of an instantiated method declaration (New) from the corresponding fields o...
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
bool InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl)
Initializes the common fields of an instantiation function declaration (New) from the corresponding f...
DeducedTemplateArgument()=default
unsigned getNewDepth(unsigned OldDepth) const
Determine how many of the OldDepth outermost template parameter lists would be removed by substitutin...
void addOuterRetainedLevels(unsigned Num)
void setKind(TemplateSubstitutionKind K)
void SetPartiallySubstitutedPack(NamedDecl *Pack, const TemplateArgument *ExplicitArgs, unsigned NumExplicitArgs)
Note that the given parameter pack has been partially substituted via explicit specification of templ...
ConstArgListsIterator begin() const
unsigned getNumSubstitutedLevels() const
Determine the number of substituted levels in this template argument list.
TPOC
The context in which partial ordering of function templates occurs.
const TemplateArgument & operator()(unsigned Depth, unsigned Index) const
Retrieve the template argument at a given depth and index.
TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner, const MultiLevelTemplateArgumentList &TemplateArgs)
LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope=false)
A simple visitor class that helps create declaration visitors.
@ TPOC_Call
Partial ordering of function templates for a function call.
A container of type source information.
VarTemplatePartialSpecializationDecl * InstantiateVarTemplatePartialSpecialization(VarTemplateDecl *VarTemplate, VarTemplatePartialSpecializationDecl *PartialSpec)
Instantiate the declaration of a variable template partial specialization.
A stack-allocated class that identifies which local variable declaration instantiations are present i...
void ResetPartiallySubstitutedPack()
Reset the partially-substituted pack when it is no longer of interest.
void InstantiatedLocalPackArg(const Decl *D, VarDecl *Inst)
Base class for declarations which introduce a typedef-name.
SmallVectorImpl< std::pair< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > >::iterator delayed_partial_spec_iterator
TemplatePartialOrderingContext(TPOC Value)
ClassTemplatePartialSpecializationDecl * InstantiateClassTemplatePartialSpecialization(ClassTemplateDecl *ClassTemplate, ClassTemplatePartialSpecializationDecl *PartialSpec)
Instantiate the declaration of a class template partial specialization.
void replaceInnermostTemplateArguments(ArgList Args)
Replaces the current 'innermost' level with the provided argument list.
TypeSourceInfo * SubstFunctionType(FunctionDecl *D, SmallVectorImpl< ParmVarDecl * > &Params)
MultiLevelTemplateArgumentList()=default
Construct an empty set of template argument lists.
bool isRewrite() const
Determine whether we are rewriting template parameters rather than substituting for them.
LocalInstantiationScope * getStartingScope() const
Declaration of a variable template.
Represents a C++ declaration that introduces decls from somewhere else.
void addOuterRetainedLevel()
Add an outermost level that we are not substituting.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
bool isLocalPackExpansion(const Decl *D)
Determine whether D is a pack expansion created in this scope.
Represents a function declaration or definition.
void MakeInstantiatedLocalArgPack(const Decl *D)
llvm::PointerUnion< Decl *, DeclArgumentPack * > * findInstantiationOf(const Decl *D)
Find the instantiation of the declaration D within the current instantiation scope.
Represents a static or instance method of a struct/union/class.
Decl * VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate, ArrayRef< BindingDecl * > *Bindings=nullptr)
void enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec *LA)
void InstantiatedLocal(const Decl *D, Decl *Inst)