clang  20.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 
13 #include "clang/AST/TemplateName.h"
14 #include "clang/AST/Decl.h"
15 #include "clang/AST/DeclBase.h"
16 #include "clang/AST/DeclCXX.h"
17 #include "clang/AST/DeclTemplate.h"
21 #include "clang/AST/TemplateBase.h"
22 #include "clang/Basic/Diagnostic.h"
23 #include "clang/Basic/LLVM.h"
26 #include "llvm/ADT/ArrayRef.h"
27 #include "llvm/ADT/FoldingSet.h"
28 #include "llvm/Support/Casting.h"
29 #include "llvm/Support/Compiler.h"
30 #include "llvm/Support/raw_ostream.h"
31 #include <cassert>
32 #include <optional>
33 #include <string>
34 
35 using namespace clang;
36 
39  return TemplateArgument(llvm::ArrayRef(Arguments, Bits.Data));
40 }
41 
44  return cast<TemplateTemplateParmDecl>(
46  ->asArray()[Bits.Index]);
47 }
48 
51  return cast<TemplateTemplateParmDecl>(
53  ->asArray()[Bits.Index]);
54 }
55 
56 void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID) {
57  Profile(ID, Replacement, getAssociatedDecl(), getIndex(), getPackIndex());
58 }
59 
61  llvm::FoldingSetNodeID &ID, TemplateName Replacement, Decl *AssociatedDecl,
62  unsigned Index, std::optional<unsigned> PackIndex) {
63  Replacement.Profile(ID);
64  ID.AddPointer(AssociatedDecl);
65  ID.AddInteger(Index);
66  ID.AddInteger(PackIndex ? *PackIndex + 1 : 0);
67 }
68 
70  ArrayRef<TemplateArgument> ArgPack, Decl *AssociatedDecl, unsigned Index,
71  bool Final)
72  : UncommonTemplateNameStorage(SubstTemplateTemplateParmPack, Index,
73  ArgPack.size()),
74  Arguments(ArgPack.data()), AssociatedDeclAndFinal(AssociatedDecl, Final) {
75  assert(AssociatedDecl != nullptr);
76 }
77 
79  ASTContext &Context) {
81  getFinal());
82 }
83 
85  return AssociatedDeclAndFinal.getPointer();
86 }
87 
89  return AssociatedDeclAndFinal.getInt();
90 }
91 
93  llvm::FoldingSetNodeID &ID, ASTContext &Context,
94  const TemplateArgument &ArgPack, Decl *AssociatedDecl, unsigned Index,
95  bool Final) {
96  ArgPack.Profile(ID, Context);
97  ID.AddPointer(AssociatedDecl);
98  ID.AddInteger(Index);
99  ID.AddBoolean(Final);
100 }
101 
102 TemplateName::TemplateName(void *Ptr) {
103  Storage = StorageType::getFromOpaqueValue(Ptr);
104 }
105 
108  : Storage(Storage) {}
110  : Storage(Storage) {}
112  : Storage(Storage) {}
114  : Storage(Storage) {}
118 
119 bool TemplateName::isNull() const { return Storage.isNull(); }
120 
122  if (auto *ND = Storage.dyn_cast<Decl *>()) {
123  if (isa<UsingShadowDecl>(ND))
124  return UsingTemplate;
125  assert(isa<TemplateDecl>(ND));
126  return Template;
127  }
128 
129  if (Storage.is<DependentTemplateName *>())
130  return DependentTemplate;
131  if (Storage.is<QualifiedTemplateName *>())
132  return QualifiedTemplate;
133 
135  = Storage.get<UncommonTemplateNameStorage*>();
136  if (uncommon->getAsOverloadedStorage())
137  return OverloadedTemplate;
138  if (uncommon->getAsAssumedTemplateName())
139  return AssumedTemplate;
140  if (uncommon->getAsSubstTemplateTemplateParm())
143 }
144 
146  if (Decl *TemplateOrUsing = Storage.dyn_cast<Decl *>()) {
147  if (UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(TemplateOrUsing))
148  return cast<TemplateDecl>(USD->getTargetDecl());
149 
150  assert(isa<TemplateDecl>(TemplateOrUsing));
151  return cast<TemplateDecl>(TemplateOrUsing);
152  }
153 
155  return QTN->getUnderlyingTemplate().getAsTemplateDecl();
156 
158  return sub->getReplacement().getAsTemplateDecl();
159 
161  return cast<TemplateDecl>(USD->getTargetDecl());
162 
163  return nullptr;
164 }
165 
167  if (UncommonTemplateNameStorage *Uncommon =
168  Storage.dyn_cast<UncommonTemplateNameStorage *>())
169  return Uncommon->getAsOverloadedStorage();
170 
171  return nullptr;
172 }
173 
175  if (UncommonTemplateNameStorage *Uncommon =
176  Storage.dyn_cast<UncommonTemplateNameStorage *>())
177  return Uncommon->getAsAssumedTemplateName();
178 
179  return nullptr;
180 }
181 
184  if (UncommonTemplateNameStorage *uncommon =
185  Storage.dyn_cast<UncommonTemplateNameStorage *>())
186  return uncommon->getAsSubstTemplateTemplateParm();
187 
188  return nullptr;
189 }
190 
193  if (UncommonTemplateNameStorage *Uncommon =
194  Storage.dyn_cast<UncommonTemplateNameStorage *>())
195  return Uncommon->getAsSubstTemplateTemplateParmPack();
196 
197  return nullptr;
198 }
199 
201  return Storage.dyn_cast<QualifiedTemplateName *>();
202 }
203 
205  return Storage.dyn_cast<DependentTemplateName *>();
206 }
207 
209  if (Decl *D = Storage.dyn_cast<Decl *>())
210  if (UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(D))
211  return USD;
213  return QTN->getUnderlyingTemplate().getAsUsingShadowDecl();
214  return nullptr;
215 }
216 
217 TemplateNameDependence TemplateName::getDependence() const {
219  switch (getKind()) {
220  case TemplateName::NameKind::QualifiedTemplate:
221  if (NestedNameSpecifier *NNS = getAsQualifiedTemplateName()->getQualifier())
222  D |= toTemplateNameDependence(NNS->getDependence());
223  break;
224  case TemplateName::NameKind::DependentTemplate:
226  getAsDependentTemplateName()->getQualifier()->getDependence());
227  break;
228  case TemplateName::NameKind::SubstTemplateTemplateParmPack:
229  D |= TemplateNameDependence::UnexpandedPack;
230  break;
231  case TemplateName::NameKind::OverloadedTemplate:
232  llvm_unreachable("overloaded templates shouldn't survive to here.");
233  default:
234  break;
235  }
237  if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Template)) {
238  D |= TemplateNameDependence::DependentInstantiation;
239  if (TTP->isParameterPack())
240  D |= TemplateNameDependence::UnexpandedPack;
241  }
242  // FIXME: Hack, getDeclContext() can be null if Template is still
243  // initializing due to PCH reading, so we check it before using it.
244  // Should probably modify TemplateSpecializationType to allow constructing
245  // it without the isDependent() checking.
246  if (Template->getDeclContext() &&
247  Template->getDeclContext()->isDependentContext())
248  D |= TemplateNameDependence::DependentInstantiation;
249  } else {
250  D |= TemplateNameDependence::DependentInstantiation;
251  }
252  return D;
253 }
254 
256  return getDependence() & TemplateNameDependence::Dependent;
257 }
258 
260  return getDependence() & TemplateNameDependence::Instantiation;
261 }
262 
264  return getDependence() & TemplateNameDependence::UnexpandedPack;
265 }
266 
267 void TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
268  Qualified Qual) const {
269  auto handleAnonymousTTP = [](TemplateDecl *TD, raw_ostream &OS) {
270  if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(TD);
271  TTP && TTP->getIdentifier() == nullptr) {
272  OS << "template-parameter-" << TTP->getDepth() << "-" << TTP->getIndex();
273  return true;
274  }
275  return false;
276  };
277  if (NameKind Kind = getKind();
279  // After `namespace ns { using std::vector }`, what is the fully-qualified
280  // name of the UsingTemplateName `vector` within ns?
281  //
282  // - ns::vector (the qualified name of the using-shadow decl)
283  // - std::vector (the qualified name of the underlying template decl)
284  //
285  // Similar to the UsingType behavior, using declarations are used to import
286  // names more often than to export them, thus using the original name is
287  // most useful in this case.
289  if (handleAnonymousTTP(Template, OS))
290  return;
291  if (Qual == Qualified::None)
292  OS << *Template;
293  else
294  Template->printQualifiedName(OS, Policy);
296  if (NestedNameSpecifier *NNS = QTN->getQualifier();
297  Qual != Qualified::None && NNS)
298  NNS->print(OS, Policy);
299  if (QTN->hasTemplateKeyword())
300  OS << "template ";
301 
302  TemplateName Underlying = QTN->getUnderlyingTemplate();
303  assert(Underlying.getKind() == TemplateName::Template ||
304  Underlying.getKind() == TemplateName::UsingTemplate);
305 
306  TemplateDecl *UTD = Underlying.getAsTemplateDecl();
307 
308  if (handleAnonymousTTP(UTD, OS))
309  return;
310 
311  if (IdentifierInfo *II = UTD->getIdentifier();
312  Policy.CleanUglifiedParameters && II &&
313  isa<TemplateTemplateParmDecl>(UTD))
314  OS << II->deuglifiedName();
315  else
316  OS << *UTD;
318  if (NestedNameSpecifier *NNS = DTN->getQualifier())
319  NNS->print(OS, Policy);
320  OS << "template ";
321 
322  if (DTN->isIdentifier())
323  OS << DTN->getIdentifier()->getName();
324  else
325  OS << "operator " << getOperatorSpelling(DTN->getOperator());
326  } else if (SubstTemplateTemplateParmStorage *subst =
328  subst->getReplacement().print(OS, Policy, Qual);
329  } else if (SubstTemplateTemplateParmPackStorage *SubstPack =
331  OS << *SubstPack->getParameterPack();
332  else if (AssumedTemplateStorage *Assumed = getAsAssumedTemplateName()) {
333  Assumed->getDeclName().print(OS, Policy);
334  } else {
337  (*OTS->begin())->printName(OS, Policy);
338  }
339 }
340 
342  TemplateName N) {
343  std::string NameStr;
344  llvm::raw_string_ostream OS(NameStr);
345  LangOptions LO;
346  LO.CPlusPlus = true;
347  LO.Bool = true;
348  OS << '\'';
349  N.print(OS, PrintingPolicy(LO));
350  OS << '\'';
351  OS.flush();
352  return DB << NameStr;
353 }
static char ID
Definition: Arena.cpp:183
Defines the Diagnostic-related interfaces.
const Decl * D
enum clang::sema::@1659::IndirectLocalPathEntry::EntryKind Kind
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:187
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
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
Represents a dependent template name that cannot be resolved prior to template instantiation.
Definition: TemplateName.h:491
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...
Definition: LangOptions.h:480
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:270
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
A structure for storing the information associated with an overloaded template name.
Definition: TemplateName.h:108
Represents a template name as written in source code.
Definition: TemplateName.h:434
The streaming interface shared between DiagnosticBuilder and PartialDiagnostic.
Definition: Diagnostic.h:1121
A structure for storing an already-substituted template template parameter pack.
Definition: TemplateName.h:141
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.
Definition: TemplateName.h:156
SubstTemplateTemplateParmPackStorage(ArrayRef< TemplateArgument > ArgPack, Decl *AssociatedDecl, unsigned Index, bool Final)
A structure for storing the information associated with a substituted template template parameter.
Definition: TemplateName.h:375
Decl * getAssociatedDecl() const
A template-like entity which owns the whole pattern being substituted.
Definition: TemplateName.h:393
void Profile(llvm::FoldingSetNodeID &ID)
TemplateTemplateParmDecl * getParameter() const
unsigned getIndex() const
Returns the index of the replaced parameter in the associated declaration.
Definition: TemplateName.h:397
std::optional< unsigned > getPackIndex() const
Definition: TemplateName.h:399
Represents a template argument.
Definition: TemplateBase.h:61
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.).
Definition: DeclTemplate.h:394
Represents a C++ template name within the type system.
Definition: TemplateName.h:203
TemplateNameDependence getDependence() const
bool isNull() const
Determine whether this template name is NULL.
TemplateName()=default
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known.
DependentTemplateName * getAsDependentTemplateName() const
Retrieve the underlying dependent template name structure, if any.
QualifiedTemplateName * getAsQualifiedTemplateName() const
Retrieve the underlying qualified template name structure, if any.
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 ...
NameKind getKind() const
@ UsingTemplate
A template name that refers to a template declaration found through a specific using shadow declarati...
Definition: TemplateName.h:248
@ OverloadedTemplate
A set of overloaded template declarations.
Definition: TemplateName.h:223
@ Template
A single template declaration.
Definition: TemplateName.h:220
@ DependentTemplate
A dependent template name that has not been resolved to a template (or set of templates).
Definition: TemplateName.h:235
@ SubstTemplateTemplateParm
A template template parameter that has been substituted for some other template name.
Definition: TemplateName.h:239
@ SubstTemplateTemplateParmPack
A template template parameter pack that has been substituted for a template template argument pack,...
Definition: TemplateName.h:244
@ QualifiedTemplate
A qualified template name, where the qualification is kept to describe the source code as written.
Definition: TemplateName.h:231
@ AssumedTemplate
An unqualified-id that has been assumed to name a function template that will be found by ADL.
Definition: TemplateName.h:227
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.
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...
Definition: TemplateName.h:48
SubstTemplateTemplateParmStorage * getAsSubstTemplateTemplateParm()
Definition: TemplateName.h:93
OverloadedTemplateStorage * getAsOverloadedStorage()
Definition: TemplateName.h:81
SubstTemplateTemplateParmPackStorage * getAsSubstTemplateTemplateParmPack()
Definition: TemplateName.h:99
AssumedTemplateStorage * getAsAssumedTemplateName()
Definition: TemplateName.h:87
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Definition: DeclCXX.h:3324
constexpr XRayInstrMask None
Definition: XRayInstr.h:38
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.
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword.
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
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 ...
Definition: TemplateName.h:66