clang: lib/AST/TemplateName.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
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"
30#include
31#include
32#include
33
34using namespace clang;
35
36DeducedTemplateStorage::DeducedTemplateStorage(TemplateName Underlying,
39 DefArgs.Args.size()),
40 Underlying(Underlying) {
42}
43
47}
48
54 ID.AddInteger(DefArgs.StartPos);
55 ID.AddInteger(DefArgs.Args.size());
58}
59
63}
64
67 return cast(
70}
71
74 return cast(
77}
78
81}
82
84 llvm::FoldingSetNodeID &ID, TemplateName Replacement, Decl *AssociatedDecl,
85 unsigned Index, std::optional PackIndex) {
86 Replacement.Profile(ID);
87 ID.AddPointer(AssociatedDecl);
88 ID.AddInteger(Index);
89 ID.AddInteger(PackIndex ? *PackIndex + 1 : 0);
90}
91
94 bool Final)
96 ArgPack.size()),
97 Arguments(ArgPack.data()), AssociatedDeclAndFinal(AssociatedDecl, Final) {
98 assert(AssociatedDecl != nullptr);
99}
100
105}
106
108 return AssociatedDeclAndFinal.getPointer();
109}
110
112 return AssociatedDeclAndFinal.getInt();
113}
114
116 llvm::FoldingSetNodeID &ID, ASTContext &Context,
118 bool Final) {
119 ArgPack.Profile(ID, Context);
120 ID.AddPointer(AssociatedDecl);
121 ID.AddInteger(Index);
122 ID.AddBoolean(Final);
123}
124
126 Storage = StorageType::getFromOpaqueValue(Ptr);
127}
128
131 : Storage(Storage) {}
133 : Storage(Storage) {}
135 : Storage(Storage) {}
137 : Storage(Storage) {}
142 : Storage(Deduced) {}
143
145
147 if (auto *ND = Storage.dyn_cast<Decl *>()) {
148 if (isa(ND))
150 assert(isa(ND));
152 }
153
154 if (isa<DependentTemplateName *>(Storage))
156 if (isa<QualifiedTemplateName *>(Storage))
158
160 cast<UncommonTemplateNameStorage *>(Storage);
169
172}
173
176 while (std::optional UnderlyingOrNone =
177 Name.desugar(IgnoreDeduced))
178 Name = *UnderlyingOrNone;
179
180 if (!IgnoreDeduced)
181 assert(Name.getAsDeducedTemplateName() == nullptr &&
182 "Unexpected canonical DeducedTemplateName; Did you mean to use "
183 "getTemplateDeclAndDefaultArgs instead?");
184
185 return cast_if_present(Name.Storage.dyn_cast<Decl *>());
186}
187
188std::pair<TemplateDecl *, DefaultArguments>
190 for (TemplateName Name = *this; ; ) {
196 if (TD && DefArgs)
197 assert(DefArgs.StartPos + DefArgs.Args.size() <=
200 }
201 if (std::optional UnderlyingOrNone =
202 Name.desugar(false)) {
203 Name = *UnderlyingOrNone;
204 continue;
205 }
206 return {cast_if_present(Name.Storage.dyn_cast<Decl *>()), {}};
207 }
208}
209
211 if (Decl *D = Storage.dyn_cast<Decl *>()) {
212 if (auto *USD = dyn_cast(D))
214 return std::nullopt;
215 }
217 return QTN->getUnderlyingTemplate();
219 return S->getReplacement();
220 if (IgnoreDeduced)
222 return S->getUnderlying();
223 return std::nullopt;
224}
225
230
231 return nullptr;
232}
233
238
239 return nullptr;
240}
241
247
248 return nullptr;
249}
250
256
257 return nullptr;
258}
259
262}
263
266}
267
269 if (Decl *D = Storage.dyn_cast<Decl *>())
271 return USD;
273 return QTN->getUnderlyingTemplate().getAsUsingShadowDecl();
274 return nullptr;
275}
276
281
282 return nullptr;
283}
284
290 auto D = TemplateNameDependence::None;
291 if (auto *TTP = dyn_cast(Template)) {
292 D |= TemplateNameDependence::DependentInstantiation;
293 if (TTP->isParameterPack())
294 D |= TemplateNameDependence::UnexpandedPack;
295 }
296
297
298
299
300 if (Template->getDeclContext() &&
301 Template->getDeclContext()->isDependentContext())
302 D |= TemplateNameDependence::DependentInstantiation;
303 return D;
304 }
307 TemplateNameDependence D = S->getUnderlyingTemplate().getDependence();
310 return D;
311 }
314 auto D = TemplateNameDependence::DependentInstantiation;
316 return D;
317 }
320 return S->getReplacement().getDependence();
321 }
323 return TemplateNameDependence::UnexpandedPack |
324 TemplateNameDependence::DependentInstantiation;
330 return D;
331 }
333 return TemplateNameDependence::DependentInstantiation;
335 llvm_unreachable("overloaded templates shouldn't survive to here.");
336 }
337 llvm_unreachable("Unknown TemplateName kind");
338}
339
341 return getDependence() & TemplateNameDependence::Dependent;
342}
343
345 return getDependence() & TemplateNameDependence::Instantiation;
346}
347
349 return getDependence() & TemplateNameDependence::UnexpandedPack;
350}
351
354 auto handleAnonymousTTP = [](TemplateDecl *TD, raw_ostream &OS) {
357 OS << "template-parameter-" << TTP->getDepth() << "-" << TTP->getIndex();
358 return true;
359 }
360 return false;
361 };
364
365
366
367
368
369
370
371
372
374 if (handleAnonymousTTP(Template, OS))
375 return;
378 else
379 Template->printQualifiedName(OS, Policy);
383 NNS->print(OS, Policy);
384 if (QTN->hasTemplateKeyword())
385 OS << "template ";
386
387 TemplateName Underlying = QTN->getUnderlyingTemplate();
390
392
393 if (handleAnonymousTTP(UTD, OS))
394 return;
395
398 isa(UTD))
399 OS << II->deuglifiedName();
400 else
401 OS << *UTD;
404 NNS->print(OS, Policy);
405 OS << "template ";
406
407 if (DTN->isIdentifier())
408 OS << DTN->getIdentifier()->getName();
409 else
413 subst->getReplacement().print(OS, Policy, Qual);
416 OS << *SubstPack->getParameterPack();
418 Assumed->getDeclName().print(OS, Policy);
420 Deduced->getUnderlying().print(OS, Policy);
422 OS << ":" << DefArgs.StartPos;
424 } else {
427 (*OTS->begin())->printName(OS, Policy);
428 }
429}
430
433 std::string NameStr;
434 llvm::raw_string_ostream OS(NameStr);
436 LO.CPlusPlus = true;
437 LO.Bool = true;
438 OS << '\'';
440 OS << '\'';
441 return DB << NameStr;
442}
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
Represents a dependent template name that cannot be resolved prior to template instantiation.
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...
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Represents a C++ nested name specifier, such as "\::std::vector::".
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.
std::optional< unsigned > getPackIndex() const
void Profile(llvm::FoldingSetNodeID &ID)
TemplateTemplateParmDecl * getParameter() 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.
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.
TemplateNameDependence toTemplateNameDependence(NestedNameSpecifierDependence D)
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ASTContext::SectionInfo &Section)
Insertion operator for diagnostics.
TemplateParameterList * getReplacedTemplateParameterList(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.
ArrayRef< TemplateArgument > Args
Describes how types, statements, expressions, and declarations should be printed.
unsigned CleanUglifiedParameters
Whether to strip underscores when printing reserved parameter names.
unsigned Data
The pack index, or the number of stored templates or template arguments, depending on which subclass ...