clang 24.0.0git
TemplateName.cpp
Go to the documentation of this file.
1//===- TemplateName.cpp - C++ Template Name Representation ----------------===//
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//
9// This file defines the TemplateName interface and subclasses.
10//
11//===----------------------------------------------------------------------===//
12
14#include "clang/AST/Decl.h"
15#include "clang/AST/DeclBase.h"
16#include "clang/AST/DeclCXX.h"
22#include "clang/Basic/LLVM.h"
25#include "llvm/ADT/ArrayRef.h"
26#include "llvm/ADT/FoldingSet.h"
27#include "llvm/Support/raw_ostream.h"
28#include <cassert>
29#include <optional>
30#include <string>
31
32using namespace clang;
33
34DeducedTemplateStorage::DeducedTemplateStorage(TemplateName Underlying,
35 const DefaultArguments &DefArgs)
36 : UncommonTemplateNameStorage(Deduced, /*Index=*/DefArgs.StartPos,
37 DefArgs.Args.size()),
38 Underlying(Underlying) {
39 llvm::copy(DefArgs.Args, reinterpret_cast<TemplateArgument *>(this + 1));
40}
41
42void DeducedTemplateStorage::Profile(llvm::FoldingSetNodeID &ID,
43 const ASTContext &Context) const {
44 Profile(ID, Context, Underlying, getDefaultArguments());
45}
46
47void DeducedTemplateStorage::Profile(llvm::FoldingSetNodeID &ID,
48 const ASTContext &Context,
49 TemplateName Underlying,
50 const DefaultArguments &DefArgs) {
51 Underlying.Profile(ID);
52 ID.AddInteger(DefArgs.StartPos);
53 ID.AddInteger(DefArgs.Args.size());
54 for (const TemplateArgument &Arg : DefArgs.Args)
55 Arg.Profile(ID, Context);
56}
57
62
68
74
75void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID) {
76 Profile(ID, Replacement, getAssociatedDecl(), getIndex(), getPackIndex(),
77 getFinal());
78}
79
81 llvm::FoldingSetNodeID &ID, TemplateName Replacement, Decl *AssociatedDecl,
82 unsigned Index, UnsignedOrNone PackIndex, bool Final) {
83 Replacement.Profile(ID);
84 ID.AddPointer(AssociatedDecl);
85 ID.AddInteger(Index);
86 ID.AddInteger(PackIndex.toInternalRepresentation());
87 ID.AddBoolean(Final);
88}
89
91 ArrayRef<TemplateArgument> ArgPack, Decl *AssociatedDecl, unsigned Index,
92 bool Final)
94 ArgPack.size()),
95 Arguments(ArgPack.data()), AssociatedDeclAndFinal(AssociatedDecl, Final) {
96 assert(AssociatedDecl != nullptr);
97}
98
99void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID,
100 ASTContext &Context) {
102 getFinal());
103}
104
106 return AssociatedDeclAndFinal.getPointer();
107}
108
110 return AssociatedDeclAndFinal.getInt();
111}
112
114 llvm::FoldingSetNodeID &ID, ASTContext &Context,
115 const TemplateArgument &ArgPack, Decl *AssociatedDecl, unsigned Index,
116 bool Final) {
117 ArgPack.Profile(ID, Context);
118 ID.AddPointer(AssociatedDecl);
119 ID.AddInteger(Index);
120 ID.AddBoolean(Final);
121}
122
123PackIndexingTemplateStorage::PackIndexingTemplateStorage(
124 TemplateName Pattern, Expr *IndexExpr, bool FullySubstituted,
125 ArrayRef<TemplateName> Expansions)
126 : UncommonTemplateNameStorage(PackIndexing, /*Index=*/0,
127 /*Data=*/Expansions.size()),
128 Pattern(Pattern),
129 IndexAndIsFullySubstituted(IndexExpr, FullySubstituted) {
130 llvm::uninitialized_copy(Expansions, getTrailingObjects());
131}
132
137 return S->getParameterPack();
138 return dyn_cast_if_present<TemplateTemplateParmDecl>(
139 Pattern.getAsTemplateDecl());
140}
141
143 if (getIndexExpr()->isInstantiationDependent())
144 return std::nullopt;
145 auto *CE = dyn_cast<ConstantExpr>(getIndexExpr());
146 if (!CE)
147 return std::nullopt;
148 llvm::APSInt Index = CE->getResultAsAPSInt();
149 assert(Index.isNonNegative() && "Invalid index");
150 return static_cast<unsigned>(Index.getExtValue());
151}
152
154 if (!isFullySubstituted() || getIndexExpr()->isInstantiationDependent())
155 return TemplateName();
158 assert(Index && *Index < Expansions.size());
159 return Expansions[*Index];
160}
161
162TemplateNameDependence PackIndexingTemplateStorage::getDependence() const {
163 TemplateNameDependence IndexD =
165
166 TemplateNameDependence D =
168 ? TemplateNameDependence::DependentInstantiation
169 : TemplateNameDependence::None);
170 if (ArrayRef<TemplateName> Expansions = getExpansions(); Expansions.empty())
171 D |= Pattern.getDependence() &
172 TemplateNameDependence::DependentInstantiation;
173 else
174 for (TemplateName T : Expansions)
175 D |= T.getDependence();
176
177 // C++29 [temp.names]p5:
178 // A pack-index-template-name is a pack expansion.
179 if (!(IndexD & TemplateNameDependence::UnexpandedPack))
180 D &= ~TemplateNameDependence::UnexpandedPack;
181
182 // C++29 [temp.names]p3:
183 // The simple-template-name P in a pack-index-template-name shall
184 // denote a pack.
185 if (!Pattern.containsUnexpandedParameterPack())
186 D |= TemplateNameDependence::Error |
187 TemplateNameDependence::DependentInstantiation;
188
189 return D;
190}
191
192void PackIndexingTemplateStorage::Profile(llvm::FoldingSetNodeID &ID,
193 const ASTContext &Context) const {
194 Profile(ID, Context, Pattern, getIndexExpr(), isFullySubstituted(),
195 getExpansions());
196}
197
198void PackIndexingTemplateStorage::Profile(llvm::FoldingSetNodeID &ID,
199 const ASTContext &Context,
200 TemplateName Pattern, Expr *IndexExpr,
201 bool FullySubstituted,
202 ArrayRef<TemplateName> Expansions) {
203 Pattern.Profile(ID);
204 IndexExpr->Profile(ID, Context, /*Canonical=*/true);
205 ID.AddBoolean(FullySubstituted);
206 ID.AddInteger(Expansions.size());
207 for (TemplateName T : Expansions)
208 T.Profile(ID);
209}
210
212 const IdentifierInfo *II)
213 : PtrOrOp(reinterpret_cast<uintptr_t>(II)) {
214 static_assert(NUM_OVERLOADED_OPERATORS <= 4096,
215 "NUM_OVERLOADED_OPERATORS is too large");
216 assert(II);
217 assert(getIdentifier() == II);
218}
221 : PtrOrOp(-uintptr_t(OOK)) {
222 assert(OOK != OO_None);
223 assert(getOperator() == OOK);
224}
225
226void IdentifierOrOverloadedOperator::Profile(llvm::FoldingSetNodeID &ID) const {
227 if (auto *Identifier = getIdentifier()) {
228 ID.AddBoolean(false);
229 ID.AddPointer(Identifier);
230 } else {
231 ID.AddBoolean(true);
232 ID.AddInteger(getOperator());
233 }
234}
235
237 Storage = StorageType::getFromOpaqueValue(Ptr);
238}
239
242 : Storage(Storage) {}
244 : Storage(Storage) {}
255 : Storage(PackIndexing) {}
256
257bool TemplateName::isNull() const { return Storage.isNull(); }
258
260 if (auto *ND = dyn_cast<Decl *>(Storage)) {
261 if (isa<UsingShadowDecl>(ND))
262 return UsingTemplate;
263 assert(isa<TemplateDecl>(ND));
264 return Template;
265 }
266
267 if (isa<DependentTemplateName *>(Storage))
268 return DependentTemplate;
269 if (isa<QualifiedTemplateName *>(Storage))
270 return QualifiedTemplate;
271
274 if (uncommon->getAsOverloadedStorage())
275 return OverloadedTemplate;
276 if (uncommon->getAsAssumedTemplateName())
277 return AssumedTemplate;
278 if (uncommon->getAsSubstTemplateTemplateParm())
280 if (uncommon->getAsDeducedTemplateName())
281 return DeducedTemplate;
282 if (uncommon->getAsPackIndexingTemplate())
284
285 assert(uncommon->getAsSubstTemplateTemplateParmPack() != nullptr);
287}
288
290 TemplateName Name = *this;
291 while (std::optional<TemplateName> UnderlyingOrNone =
292 Name.desugar(IgnoreDeduced))
293 Name = *UnderlyingOrNone;
294
295 if (!IgnoreDeduced)
296 assert(Name.getAsDeducedTemplateName() == nullptr &&
297 "Unexpected canonical DeducedTemplateName; Did you mean to use "
298 "getTemplateDeclAndDefaultArgs instead?");
299
300 return cast_if_present<TemplateDecl>(
301 dyn_cast_if_present<Decl *>(Name.Storage));
302}
303
306 return dyn_cast<TemplateTemplateParmDecl>(TD);
308 return PI->getParameterPack();
309 return nullptr;
310}
311
312std::pair<TemplateName, DefaultArguments>
314 DefaultArguments DefArgs;
315 for (TemplateName Name = *this; /**/; /**/) {
317 assert(!DefArgs && "multiple default args?");
318 DefArgs = DTS->getDefaultArguments();
319 if (TemplateDecl *TD = DTS->getUnderlying().getAsTemplateDecl();
320 TD && DefArgs)
321 assert(DefArgs.StartPos + DefArgs.Args.size() <=
322 TD->getTemplateParameters()->size());
323 Name = DTS->getUnderlying();
324 }
325 if (std::optional<TemplateName> UnderlyingOrNone =
326 Name.desugar(/*IgnoreDeduced=*/false)) {
327 Name = *UnderlyingOrNone;
328 continue;
329 }
330 return {Name, DefArgs};
331 }
332}
333
334std::optional<TemplateName> TemplateName::desugar(bool IgnoreDeduced) const {
335 if (Decl *D = dyn_cast_if_present<Decl *>(Storage)) {
336 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
337 return TemplateName(USD->getTargetDecl());
338 return std::nullopt;
339 }
341 return QTN->getUnderlyingTemplate();
343 return S->getReplacement();
345 if (TemplateName Selected = S->getSelectedTemplate(); !Selected.isNull())
346 return Selected;
347 return std::nullopt;
348 }
349 if (IgnoreDeduced)
351 return S->getUnderlying();
352 return std::nullopt;
353}
354
356 if (UncommonTemplateNameStorage *Uncommon =
357 Storage.dyn_cast<UncommonTemplateNameStorage *>())
358 return Uncommon->getAsOverloadedStorage();
359
360 return nullptr;
361}
362
364 if (UncommonTemplateNameStorage *Uncommon =
365 Storage.dyn_cast<UncommonTemplateNameStorage *>())
366 return Uncommon->getAsAssumedTemplateName();
367
368 return nullptr;
369}
370
373 if (UncommonTemplateNameStorage *uncommon =
374 dyn_cast_if_present<UncommonTemplateNameStorage *>(Storage))
375 return uncommon->getAsSubstTemplateTemplateParm();
376
377 return nullptr;
378}
379
382 if (UncommonTemplateNameStorage *Uncommon =
383 Storage.dyn_cast<UncommonTemplateNameStorage *>())
384 return Uncommon->getAsSubstTemplateTemplateParmPack();
385
386 return nullptr;
387}
388
390 return dyn_cast_if_present<QualifiedTemplateName *>(Storage);
391}
392
396
397std::tuple<NestedNameSpecifier, bool>
399 for (std::optional<TemplateName> Cur = *this; Cur;
400 Cur = Cur->desugar(/*IgnoreDeduced=*/true)) {
401 if (DependentTemplateName *N = Cur->getAsDependentTemplateName())
402 return {N->getQualifier(), N->hasTemplateKeyword()};
403 if (QualifiedTemplateName *N = Cur->getAsQualifiedTemplateName())
404 return {N->getQualifier(), N->hasTemplateKeyword()};
405 if (Cur->getAsSubstTemplateTemplateParm() ||
406 Cur->getAsSubstTemplateTemplateParmPack() ||
407 Cur->getAsPackIndexingTemplate())
408 break;
409 }
410 return {std::nullopt, false};
411}
412
414 if (Decl *D = Storage.dyn_cast<Decl *>())
415 if (UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(D))
416 return USD;
418 return QTN->getUnderlyingTemplate().getAsUsingShadowDecl();
419 return nullptr;
420}
421
424 bool HasTemplateKeyword)
425 : Qualifier(Qualifier, HasTemplateKeyword), Name(Name) {
426 assert((!Qualifier || Qualifier.isDependent()) &&
427 "Qualifier must be dependent");
428}
429
430TemplateNameDependence DependentTemplateStorage::getDependence() const {
432 TemplateNameDependence::DependentInstantiation;
433}
434
436 const PrintingPolicy &Policy) const {
437 getQualifier().print(OS, Policy);
438
439 if (hasTemplateKeyword())
440 OS << "template ";
441
443 if (const IdentifierInfo *II = Name.getIdentifier())
444 OS << II->getName();
445 else
446 OS << "operator " << getOperatorSpelling(Name.getOperator());
447}
448
450 if (UncommonTemplateNameStorage *Uncommon =
451 dyn_cast_if_present<UncommonTemplateNameStorage *>(Storage))
452 return Uncommon->getAsDeducedTemplateName();
453
454 return nullptr;
455}
456
458 if (UncommonTemplateNameStorage *Uncommon =
459 dyn_cast_if_present<UncommonTemplateNameStorage *>(Storage))
460 return Uncommon->getAsPackIndexingTemplate();
461
462 return nullptr;
463}
464
465TemplateNameDependence TemplateName::getDependence() const {
466 switch (getKind()) {
470 auto D = TemplateNameDependence::None;
471 if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Template)) {
472 D |= TemplateNameDependence::DependentInstantiation;
473 if (TTP->isParameterPack())
474 D |= TemplateNameDependence::UnexpandedPack;
475 }
476 // FIXME: Hack, getDeclContext() can be null if Template is still
477 // initializing due to PCH reading, so we check it before using it.
478 // Should probably modify TemplateSpecializationType to allow constructing
479 // it without the isDependent() checking.
480 if (Template->getDeclContext() &&
481 Template->getDeclContext()->isDependentContext())
482 D |= TemplateNameDependence::DependentInstantiation;
483 return D;
484 }
487 TemplateNameDependence D = S->getUnderlyingTemplate().getDependence();
489 return D;
490 }
494 TemplateNameDependence::DependentInstantiation;
495 }
498 return S->getReplacement().getDependence();
499 }
501 return TemplateNameDependence::UnexpandedPack |
502 TemplateNameDependence::DependentInstantiation;
505 TemplateNameDependence D = DTS->getUnderlying().getDependence();
506 for (const TemplateArgument &Arg : DTS->getDefaultArguments().Args)
507 D |= toTemplateNameDependence(Arg.getDependence());
508 return D;
509 }
513 return TemplateNameDependence::DependentInstantiation;
515 llvm_unreachable("overloaded templates shouldn't survive to here.");
516 }
517 llvm_unreachable("Unknown TemplateName kind");
518}
519
521 return getDependence() & TemplateNameDependence::Dependent;
522}
523
525 return getDependence() & TemplateNameDependence::Instantiation;
526}
527
529 return getDependence() & TemplateNameDependence::UnexpandedPack;
530}
531
533 auto namesConcept = [](const TemplateTemplateParmDecl *TTP) {
534 return TTP->templateParameterKind() == TNK_Concept_template;
535 };
536 switch (getKind()) {
539 const TemplateDecl *TD = getAsTemplateDecl();
540 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TD))
541 return namesConcept(TTP);
542 return isa<ConceptDecl>(TD);
543 }
547 return namesConcept(
548 getAsSubstTemplateTemplateParmPack()->getParameterPack());
552 return desugar(/*IgnoreDeduced=*/true)->isConceptName();
556 return false;
557 }
558 llvm_unreachable("Unknown TemplateName kind");
559}
560
561void TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
562 Qualified Qual) const {
563 auto handleAnonymousTTP = [&](TemplateDecl *TD, raw_ostream &OS) {
564 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(TD);
565 TTP && (Policy.PrintAsCanonical || TTP->getIdentifier() == nullptr)) {
566 OS << "template-parameter-" << TTP->getDepth() << "-" << TTP->getIndex();
567 return true;
568 }
569 return false;
570 };
571 if (NameKind Kind = getKind();
573 // After `namespace ns { using std::vector }`, what is the fully-qualified
574 // name of the UsingTemplateName `vector` within ns?
575 //
576 // - ns::vector (the qualified name of the using-shadow decl)
577 // - std::vector (the qualified name of the underlying template decl)
578 //
579 // Similar to the UsingType behavior, using declarations are used to import
580 // names more often than to export them, thus using the original name is
581 // most useful in this case.
583 if (Policy.PrintAsCanonical)
584 Template = cast<TemplateDecl>(Template->getCanonicalDecl());
585 if (handleAnonymousTTP(Template, OS))
586 return;
588 Policy.SuppressScope) {
589 if (IdentifierInfo *II = Template->getIdentifier();
590 Policy.CleanUglifiedParameters && II &&
592 OS << II->deuglifiedName();
593 else
594 OS << *Template;
595 } else {
596 PrintingPolicy NestedNamePolicy = Policy;
597 NestedNamePolicy.SuppressUnwrittenScope = true;
598 Template->printQualifiedName(OS, NestedNamePolicy);
599 }
601 if (Policy.PrintAsCanonical) {
602 QTN->getUnderlyingTemplate().print(OS, Policy, Qual);
603 return;
604 }
605 if (Qual != Qualified::None)
606 QTN->getQualifier().print(OS, Policy);
607 if (QTN->hasTemplateKeyword())
608 OS << "template ";
609
610 TemplateName Underlying = QTN->getUnderlyingTemplate();
611 assert(Underlying.getKind() == TemplateName::Template ||
612 Underlying.getKind() == TemplateName::UsingTemplate);
613
614 TemplateDecl *UTD = Underlying.getAsTemplateDecl();
615
616 if (handleAnonymousTTP(UTD, OS))
617 return;
618
619 OS << *UTD;
621 DTN->print(OS, Policy);
622 } else if (SubstTemplateTemplateParmStorage *subst =
624 subst->getReplacement().print(OS, Policy, Qual);
626 if (TemplateName Selected = PI->getSelectedTemplate();
627 !Selected.isNull() && Policy.PrintAsCanonical) {
628 Selected.print(OS, Policy, Qual);
629 return;
630 }
631 PI->getPattern().print(OS, Policy, Qual);
632 OS << "...[";
633 PI->getIndexExpr()->printPretty(OS, nullptr, Policy);
634 OS << "]";
635 } else if (SubstTemplateTemplateParmPackStorage *SubstPack =
637 OS << *SubstPack->getParameterPack();
638 else if (AssumedTemplateStorage *Assumed = getAsAssumedTemplateName()) {
639 Assumed->getDeclName().print(OS, Policy);
641 Deduced->getUnderlying().print(OS, Policy);
642 DefaultArguments DefArgs = Deduced->getDefaultArguments();
643 OS << ":" << DefArgs.StartPos;
644 printTemplateArgumentList(OS, DefArgs.Args, Policy);
645 } else {
648 (*OTS->begin())->printName(OS, Policy);
649 }
650}
651
653 TemplateName N) {
654 std::string NameStr;
655 llvm::raw_string_ostream OS(NameStr);
656 LangOptions LO;
657 LO.CPlusPlus = true;
658 LO.Bool = true;
659 OS << '\'';
660 N.print(OS, PrintingPolicy(LO));
661 OS << '\'';
662 return DB << NameStr;
663}
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 ...
Definition ASTContext.h:223
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.
Definition DeclBase.h:86
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?
This represents one expression.
Definition Expr.h:113
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
Definition Expr.h:224
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.
A structure for storing a pack-index-template-name ([temp.names]).
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const
TemplateName getSelectedTemplate() const
TemplateTemplateParmDecl * getParameterPack() const
UnsignedOrNone getSelectedIndex() const
ArrayRef< TemplateName > getExpansions() const
TemplateNameDependence getDependence() const
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.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
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
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.
TemplateName()=default
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...
bool isConceptName() const
Determines whether this template name denotes a concept, or a template template parameter denoting on...
NameKind getKind() const
@ UsingTemplate
A template name that refers to a template declaration found through a specific using shadow declarati...
@ OverloadedTemplate
A set of overloaded template declarations.
@ PackIndexingTemplate
A pack-index-template-name.
@ 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.
TemplateTemplateParmDecl * getAsTemplateTemplateParmDecl() const
Retrieve the template template parameter that this template name refers to, if any.
bool isDependent() const
Determines whether this is a dependent template name.
SubstTemplateTemplateParmStorage * getAsSubstTemplateTemplateParm() const
Retrieve the substituted template template parameter, if known.
PackIndexingTemplateStorage * getAsPackIndexingTemplate() const
Retrieve the pack-index-template-name storage, if any.
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...
PackIndexingTemplateStorage * getAsPackIndexingTemplate()
SubstTemplateTemplateParmPackStorage * getAsSubstTemplateTemplateParmPack()
UncommonTemplateNameStorage(Kind Kind, unsigned Index, unsigned Data)
SubstTemplateTemplateParmStorage * getAsSubstTemplateTemplateParm()
AssumedTemplateStorage * getAsAssumedTemplateName()
DeducedTemplateStorage * getAsDeducedTemplateName()
OverloadedTemplateStorage * getAsOverloadedStorage()
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Definition DeclCXX.h:3428
Top level wrappers for InstallAPI frontend operations.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ OO_None
Not an overloaded operator.
@ NUM_OVERLOADED_OPERATORS
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
Definition Parser.h:61
TemplateNameDependence toTemplateNameDependence(NestedNameSpecifierDependence D)
OptionalUnsigned< unsigned > UnsignedOrNone
const FunctionProtoType * T
@ Deduced
The normal deduced case.
Definition TypeBase.h:1818
std::tuple< NamedDecl *, TemplateArgument > getReplacedTemplateParameter(Decl *D, unsigned Index)
Internal helper used by Subst* nodes to retrieve a parameter from the AssociatedDecl,...
@ TNK_Concept_template
The name refers to a concept.
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)
Definition Address.h:327
@ PackIndex
Index of a pack indexing expression or specifier.
Definition Sema.h:845
__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
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.