26#include "llvm/ADT/ArrayRef.h"
27#include "llvm/ADT/FoldingSet.h"
28#include "llvm/Support/Compiler.h"
29#include "llvm/Support/raw_ostream.h"
36DeducedTemplateStorage::DeducedTemplateStorage(
TemplateName Underlying,
40 Underlying(Underlying) {
55 ID.AddInteger(DefArgs.
Args.size());
67 return cast<TemplateTemplateParmDecl>(
74 return cast<TemplateTemplateParmDecl>(
87 Replacement.Profile(ID);
88 ID.AddPointer(AssociatedDecl);
99 Arguments(ArgPack.data()), AssociatedDeclAndFinal(AssociatedDecl, Final) {
100 assert(AssociatedDecl !=
nullptr);
110 return AssociatedDeclAndFinal.getPointer();
114 return AssociatedDeclAndFinal.getInt();
118 llvm::FoldingSetNodeID &ID,
ASTContext &Context,
122 ID.AddPointer(AssociatedDecl);
123 ID.AddInteger(Index);
124 ID.AddBoolean(Final);
129 : PtrOrOp(reinterpret_cast<
uintptr_t>(II)) {
131 "NUM_OVERLOADED_OPERATORS is too large");
144 ID.AddBoolean(
false);
153 Storage = StorageType::getFromOpaqueValue(Ptr);
158 : Storage(Storage) {}
160 : Storage(Storage) {}
162 : Storage(Storage) {}
164 : Storage(Storage) {}
169 : Storage(Deduced) {}
174 if (
auto *ND = dyn_cast<Decl *>(Storage)) {
175 if (isa<UsingShadowDecl>(ND))
177 assert(isa<TemplateDecl>(ND));
181 if (isa<DependentTemplateName *>(Storage))
183 if (isa<QualifiedTemplateName *>(Storage))
187 cast<UncommonTemplateNameStorage *>(Storage);
203 while (std::optional<TemplateName> UnderlyingOrNone =
204 Name.desugar(IgnoreDeduced))
205 Name = *UnderlyingOrNone;
208 assert(Name.getAsDeducedTemplateName() ==
nullptr &&
209 "Unexpected canonical DeducedTemplateName; Did you mean to use "
210 "getTemplateDeclAndDefaultArgs instead?");
212 return cast_if_present<TemplateDecl>(
213 dyn_cast_if_present<Decl *>(Name.Storage));
216std::pair<TemplateDecl *, DefaultArguments>
229 if (std::optional<TemplateName> UnderlyingOrNone =
230 Name.desugar(
false)) {
231 Name = *UnderlyingOrNone;
234 return {cast_if_present<TemplateDecl>(Name.Storage.dyn_cast<
Decl *>()), {}};
239 if (
Decl *
D = dyn_cast_if_present<Decl *>(Storage)) {
240 if (
auto *USD = dyn_cast<UsingShadowDecl>(
D))
245 return QTN->getUnderlyingTemplate();
247 return S->getReplacement();
250 return S->getUnderlying();
273 dyn_cast_if_present<UncommonTemplateNameStorage *>(Storage))
289 return dyn_cast_if_present<QualifiedTemplateName *>(Storage);
296std::tuple<NestedNameSpecifier, bool>
298 for (std::optional<TemplateName> Cur = *
this; Cur;
299 Cur = Cur->desugar(
true)) {
301 return {N->getQualifier(), N->hasTemplateKeyword()};
303 return {N->getQualifier(), N->hasTemplateKeyword()};
304 if (Cur->getAsSubstTemplateTemplateParm() ||
305 Cur->getAsSubstTemplateTemplateParmPack())
308 return {std::nullopt,
false};
312 if (
Decl *
D = Storage.dyn_cast<
Decl *>())
316 return QTN->getUnderlyingTemplate().getAsUsingShadowDecl();
322 bool HasTemplateKeyword)
323 : Qualifier(Qualifier, HasTemplateKeyword), Name(Name) {
324 assert((!Qualifier || Qualifier.isDependent()) &&
325 "Qualifier must be dependent");
330 TemplateNameDependence::DependentInstantiation;
349 dyn_cast_if_present<UncommonTemplateNameStorage *>(Storage))
360 auto D = TemplateNameDependence::None;
361 if (
auto *TTP = dyn_cast<TemplateTemplateParmDecl>(
Template)) {
362 D |= TemplateNameDependence::DependentInstantiation;
363 if (TTP->isParameterPack())
364 D |= TemplateNameDependence::UnexpandedPack;
371 Template->getDeclContext()->isDependentContext())
372 D |= TemplateNameDependence::DependentInstantiation;
377 TemplateNameDependence
D = S->getUnderlyingTemplate().getDependence();
384 TemplateNameDependence::DependentInstantiation;
388 return S->getReplacement().getDependence();
391 return TemplateNameDependence::UnexpandedPack |
392 TemplateNameDependence::DependentInstantiation;
401 return TemplateNameDependence::DependentInstantiation;
403 llvm_unreachable(
"overloaded templates shouldn't survive to here.");
405 llvm_unreachable(
"Unknown TemplateName kind");
413 return getDependence() & TemplateNameDependence::Instantiation;
417 return getDependence() & TemplateNameDependence::UnexpandedPack;
422 auto handleAnonymousTTP = [&](
TemplateDecl *TD, raw_ostream &OS) {
425 OS <<
"template-parameter-" << TTP->getDepth() <<
"-" << TTP->getIndex();
444 if (handleAnonymousTTP(
Template, OS))
450 isa<TemplateTemplateParmDecl>(
Template))
451 OS << II->deuglifiedName();
457 Template->printQualifiedName(OS, NestedNamePolicy);
461 QTN->getUnderlyingTemplate().print(OS, Policy, Qual);
465 QTN->getQualifier().print(OS, Policy);
466 if (QTN->hasTemplateKeyword())
475 if (handleAnonymousTTP(UTD, OS))
480 DTN->
print(OS, Policy);
483 subst->getReplacement().print(OS, Policy, Qual);
486 OS << *SubstPack->getParameterPack();
488 Assumed->getDeclName().print(OS, Policy);
490 Deduced->getUnderlying().print(OS, Policy);
497 (*OTS->
begin())->printName(OS, Policy);
504 llvm::raw_string_ostream OS(NameStr);
511 return DB << NameStr;
Defines the Diagnostic-related interfaces.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
Defines an enumeration for C++ overloaded operators.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
A structure for storing the information associated with a name that has been assumed to be a template...
Decl - This represents one declaration (or definition), e.g.
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
TemplateName getUnderlying() const
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const
DefaultArguments getDefaultArguments() const
void print(raw_ostream &OS, const PrintingPolicy &Policy) const
IdentifierOrOverloadedOperator getName() const
NestedNameSpecifier getQualifier() const
Return the nested name specifier that qualifies this name.
DependentTemplateStorage(NestedNameSpecifier Qualifier, IdentifierOrOverloadedOperator Name, bool HasTemplateKeyword)
TemplateNameDependence getDependence() const
bool hasTemplateKeyword() const
Was this template name was preceeded by the template keyword?
One of these records is kept for each identifier that is lexed.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool ResolveTemplateArguments=false, bool PrintFinalScopeResOp=true) const
Print this nested name specifier to the given output stream.
A structure for storing the information associated with an overloaded template name.
Represents a template name as written in source code.
The streaming interface shared between DiagnosticBuilder and PartialDiagnostic.
A structure for storing an already-substituted template template parameter pack.
Decl * getAssociatedDecl() const
A template-like entity which owns the whole pattern being substituted.
void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context)
TemplateTemplateParmDecl * getParameterPack() const
Retrieve the template template parameter pack being substituted.
TemplateArgument getArgumentPack() const
Retrieve the template template argument pack with which this parameter was substituted.
unsigned getIndex() const
Returns the index of the replaced parameter in the associated declaration.
SubstTemplateTemplateParmPackStorage(ArrayRef< TemplateArgument > ArgPack, Decl *AssociatedDecl, unsigned Index, bool Final)
A structure for storing the information associated with a substituted template template parameter.
void Profile(llvm::FoldingSetNodeID &ID)
TemplateTemplateParmDecl * getParameter() const
UnsignedOrNone getPackIndex() const
unsigned getIndex() const
Returns the index of the replaced parameter in the associated declaration.
Decl * getAssociatedDecl() const
A template-like entity which owns the whole pattern being substituted.
Represents a template argument.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const
Used to insert TemplateArguments into FoldingSets.
The base class of all kinds of template declarations (e.g., class, function, etc.).
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a C++ template name within the type system.
TemplateNameDependence getDependence() const
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
DeducedTemplateStorage * getAsDeducedTemplateName() const
Retrieve the deduced template info, if any.
bool isNull() const
Determine whether this template name is NULL.
DependentTemplateName * getAsDependentTemplateName() const
Retrieve the underlying dependent template name structure, if any.
QualifiedTemplateName * getAsQualifiedTemplateName() const
Retrieve the underlying qualified template name structure, if any.
std::optional< TemplateName > desugar(bool IgnoreDeduced) const
void print(raw_ostream &OS, const PrintingPolicy &Policy, Qualified Qual=Qualified::AsWritten) const
Print the template name.
OverloadedTemplateStorage * getAsOverloadedTemplate() const
Retrieve the underlying, overloaded function template declarations that this template name refers to,...
bool containsUnexpandedParameterPack() const
Determines whether this template name contains an unexpanded parameter pack (for C++0x variadic templ...
AssumedTemplateStorage * getAsAssumedTemplateName() const
Retrieve information on a name that has been assumed to be a template-name in order to permit a call ...
@ UsingTemplate
A template name that refers to a template declaration found through a specific using shadow declarati...
@ OverloadedTemplate
A set of overloaded template declarations.
@ Template
A single template declaration.
@ DependentTemplate
A dependent template name that has not been resolved to a template (or set of templates).
@ SubstTemplateTemplateParm
A template template parameter that has been substituted for some other template name.
@ SubstTemplateTemplateParmPack
A template template parameter pack that has been substituted for a template template argument pack,...
@ DeducedTemplate
A template name that refers to another TemplateName with deduced default arguments.
@ QualifiedTemplate
A qualified template name, where the qualification is kept to describe the source code as written.
@ AssumedTemplate
An unqualified-id that has been assumed to name a function template that will be found by ADL.
UsingShadowDecl * getAsUsingShadowDecl() const
Retrieve the using shadow declaration through which the underlying template declaration is introduced...
SubstTemplateTemplateParmPackStorage * getAsSubstTemplateTemplateParmPack() const
Retrieve the substituted template template parameter pack, if known.
void Profile(llvm::FoldingSetNodeID &ID)
bool isDependent() const
Determines whether this is a dependent template name.
std::pair< TemplateDecl *, DefaultArguments > getTemplateDeclAndDefaultArgs() const
Retrieves the underlying template declaration that this template name refers to, along with the deduc...
SubstTemplateTemplateParmStorage * getAsSubstTemplateTemplateParm() const
Retrieve the substituted template template parameter, if known.
bool isInstantiationDependent() const
Determines whether this is a template name that somehow depends on a template parameter.
std::tuple< NestedNameSpecifier, bool > getQualifierAndTemplateKeyword() const
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
Implementation class used to describe either a set of overloaded template names or an already-substit...
SubstTemplateTemplateParmPackStorage * getAsSubstTemplateTemplateParmPack()
SubstTemplateTemplateParmStorage * getAsSubstTemplateTemplateParm()
AssumedTemplateStorage * getAsAssumedTemplateName()
DeducedTemplateStorage * getAsDeducedTemplateName()
OverloadedTemplateStorage * getAsOverloadedStorage()
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ OO_None
Not an overloaded operator.
@ NUM_OVERLOADED_OPERATORS
TemplateNameDependence toTemplateNameDependence(NestedNameSpecifierDependence D)
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ASTContext::SectionInfo &Section)
Insertion operator for diagnostics.
@ Template
We are parsing a template declaration.
TemplateParameterList * getReplacedTemplateParameterList(const Decl *D)
Internal helper used by Subst* nodes to retrieve the parameter list for their AssociatedDecl.
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.
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword.
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
ArrayRef< TemplateArgument > Args
IdentifierOrOverloadedOperator()=default
const IdentifierInfo * getIdentifier() const
Returns the identifier to which this template name refers.
void Profile(llvm::FoldingSetNodeID &ID) const
OverloadedOperatorKind getOperator() const
Return the overloaded operator to which this template name refers.
Describes how types, statements, expressions, and declarations should be printed.
unsigned SuppressUnwrittenScope
Suppress printing parts of scope specifiers that are never written, e.g., for anonymous namespaces.
unsigned CleanUglifiedParameters
Whether to strip underscores when printing reserved parameter names.
unsigned SuppressScope
Suppresses printing of scope specifiers.
unsigned PrintAsCanonical
Whether to print entities as written or canonically.
unsigned Data
The pack index, or the number of stored templates or template arguments, depending on which subclass ...
constexpr unsigned toInternalRepresentation() const