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) {
53 Underlying.Profile(ID);
55 ID.AddInteger(DefArgs.
Args.size());
85 Replacement.Profile(ID);
86 ID.AddPointer(AssociatedDecl);
97 Arguments(ArgPack.data()), AssociatedDeclAndFinal(AssociatedDecl, Final) {
98 assert(AssociatedDecl !=
nullptr);
108 return AssociatedDeclAndFinal.getPointer();
112 return AssociatedDeclAndFinal.getInt();
116 llvm::FoldingSetNodeID &ID,
ASTContext &Context,
120 ID.AddPointer(AssociatedDecl);
121 ID.AddInteger(Index);
122 ID.AddBoolean(Final);
127 : PtrOrOp(reinterpret_cast<
uintptr_t>(II)) {
129 "NUM_OVERLOADED_OPERATORS is too large");
142 ID.AddBoolean(
false);
143 ID.AddPointer(Identifier);
151 Storage = StorageType::getFromOpaqueValue(Ptr);
156 : Storage(Storage) {}
158 : Storage(Storage) {}
160 : Storage(Storage) {}
162 : Storage(Storage) {}
167 : Storage(Deduced) {}
172 if (
auto *ND = dyn_cast<Decl *>(Storage)) {
200 TemplateName Name = *
this;
201 while (std::optional<TemplateName> UnderlyingOrNone =
203 Name = *UnderlyingOrNone;
207 "Unexpected canonical DeducedTemplateName; Did you mean to use "
208 "getTemplateDeclAndDefaultArgs instead?");
210 return cast_if_present<TemplateDecl>(
211 dyn_cast_if_present<Decl *>(Name.Storage));
214std::pair<TemplateName, DefaultArguments>
217 for (TemplateName Name = *
this; ; ) {
219 assert(!DefArgs &&
"multiple default args?");
220 DefArgs = DTS->getDefaultArguments();
221 if (
TemplateDecl *TD = DTS->getUnderlying().getAsTemplateDecl();
224 TD->getTemplateParameters()->size());
225 Name = DTS->getUnderlying();
227 if (std::optional<TemplateName> UnderlyingOrNone =
228 Name.desugar(
false)) {
229 Name = *UnderlyingOrNone;
232 return {Name, DefArgs};
237 if (
Decl *D = dyn_cast_if_present<Decl *>(Storage)) {
238 if (
auto *USD = dyn_cast<UsingShadowDecl>(D))
243 return QTN->getUnderlyingTemplate();
245 return S->getReplacement();
248 return S->getUnderlying();
271 dyn_cast_if_present<UncommonTemplateNameStorage *>(Storage))
287 return dyn_cast_if_present<QualifiedTemplateName *>(Storage);
294std::tuple<NestedNameSpecifier, bool>
296 for (std::optional<TemplateName> Cur = *
this; Cur;
297 Cur = Cur->desugar(
true)) {
299 return {N->getQualifier(), N->hasTemplateKeyword()};
301 return {N->getQualifier(), N->hasTemplateKeyword()};
302 if (Cur->getAsSubstTemplateTemplateParm() ||
303 Cur->getAsSubstTemplateTemplateParmPack())
306 return {std::nullopt,
false};
310 if (
Decl *D = Storage.dyn_cast<
Decl *>())
314 return QTN->getUnderlyingTemplate().getAsUsingShadowDecl();
320 bool HasTemplateKeyword)
321 : Qualifier(Qualifier, HasTemplateKeyword), Name(Name) {
322 assert((!Qualifier || Qualifier.isDependent()) &&
323 "Qualifier must be dependent");
328 TemplateNameDependence::DependentInstantiation;
347 dyn_cast_if_present<UncommonTemplateNameStorage *>(Storage))
358 auto D = TemplateNameDependence::None;
359 if (
auto *TTP = dyn_cast<TemplateTemplateParmDecl>(
Template)) {
360 D |= TemplateNameDependence::DependentInstantiation;
361 if (TTP->isParameterPack())
362 D |= TemplateNameDependence::UnexpandedPack;
369 Template->getDeclContext()->isDependentContext())
370 D |= TemplateNameDependence::DependentInstantiation;
382 TemplateNameDependence::DependentInstantiation;
386 return S->getReplacement().getDependence();
389 return TemplateNameDependence::UnexpandedPack |
390 TemplateNameDependence::DependentInstantiation;
399 return TemplateNameDependence::DependentInstantiation;
401 llvm_unreachable(
"overloaded templates shouldn't survive to here.");
403 llvm_unreachable(
"Unknown TemplateName kind");
411 return getDependence() & TemplateNameDependence::Instantiation;
415 return getDependence() & TemplateNameDependence::UnexpandedPack;
420 auto handleAnonymousTTP = [&](
TemplateDecl *TD, raw_ostream &OS) {
423 OS <<
"template-parameter-" << TTP->getDepth() <<
"-" << TTP->getIndex();
442 if (handleAnonymousTTP(
Template, OS))
449 OS << II->deuglifiedName();
455 Template->printQualifiedName(OS, NestedNamePolicy);
459 QTN->getUnderlyingTemplate().print(OS, Policy, Qual);
463 QTN->getQualifier().print(OS, Policy);
464 if (QTN->hasTemplateKeyword())
467 TemplateName Underlying = QTN->getUnderlyingTemplate();
473 if (handleAnonymousTTP(UTD, OS))
478 DTN->print(OS, Policy);
481 subst->getReplacement().print(OS, Policy, Qual);
484 OS << *SubstPack->getParameterPack();
486 Assumed->getDeclName().print(OS, Policy);
488 Deduced->getUnderlying().print(OS, Policy);
491 printTemplateArgumentList(OS, DefArgs.
Args, Policy);
495 (*OTS->
begin())->printName(OS, Policy);
502 llvm::raw_string_ostream OS(NameStr);
509 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.
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.
NestedNameSpecifierDependence getDependence() const
A structure for storing the information associated with an overloaded template name.
Represents a template name as written in source code.
NestedNameSpecifier getQualifier() const
Return the nested name specifier that qualifies this name.
TemplateName getUnderlyingTemplate() const
Return the underlying template name.
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.).
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 ...
std::pair< TemplateName, DefaultArguments > getTemplateDeclAndDefaultArgs() const
Retrieves the underlying template name that this template name refers to, along with the deduced defa...
@ 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.
bool isDependent() const
Determines whether this is a dependent template name.
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()
UncommonTemplateNameStorage(Kind Kind, unsigned Index, unsigned Data)
@ SubstTemplateTemplateParmPack
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
bool isa(CodeGen::Address addr)
TemplateNameDependence toTemplateNameDependence(NestedNameSpecifierDependence D)
std::tuple< NamedDecl *, TemplateArgument > getReplacedTemplateParameter(Decl *D, unsigned Index)
Internal helper used by Subst* nodes to retrieve a parameter from the AssociatedDecl,...
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ConceptReference *C)
Insertion operator for diagnostics.
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword.
U cast(CodeGen::Address addr)
__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.
constexpr unsigned toInternalRepresentation() const