clang  15.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 <string>
33 
34 using namespace clang;
35 
38  return TemplateArgument(llvm::makeArrayRef(Arguments, size()));
39 }
40 
41 void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID) {
42  Profile(ID, Parameter, Replacement);
43 }
44 
45 void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID,
46  TemplateTemplateParmDecl *parameter,
47  TemplateName replacement) {
48  ID.AddPointer(parameter);
49  ID.AddPointer(replacement.getAsVoidPointer());
50 }
51 
53  ASTContext &Context) {
54  Profile(ID, Context, Parameter, getArgumentPack());
55 }
56 
58  ASTContext &Context,
59  TemplateTemplateParmDecl *Parameter,
60  const TemplateArgument &ArgPack) {
61  ID.AddPointer(Parameter);
62  ArgPack.Profile(ID, Context);
63 }
64 
65 TemplateName::TemplateName(void *Ptr) {
66  Storage = StorageType::getFromOpaqueValue(Ptr);
67 }
68 
69 TemplateName::TemplateName(TemplateDecl *Template) : Storage(Template) {}
71  : Storage(Storage) {}
73  : Storage(Storage) {}
75  : Storage(Storage) {}
77  : Storage(Storage) {}
80 TemplateName::TemplateName(UsingShadowDecl *Using) : Storage(Using) {}
81 
82 bool TemplateName::isNull() const { return Storage.isNull(); }
83 
85  if (auto *ND = Storage.dyn_cast<Decl *>()) {
86  if (isa<UsingShadowDecl>(ND))
87  return UsingTemplate;
88  assert(isa<TemplateDecl>(ND));
89  return Template;
90  }
91 
92  if (Storage.is<DependentTemplateName *>())
93  return DependentTemplate;
94  if (Storage.is<QualifiedTemplateName *>())
95  return QualifiedTemplate;
96 
98  = Storage.get<UncommonTemplateNameStorage*>();
99  if (uncommon->getAsOverloadedStorage())
100  return OverloadedTemplate;
101  if (uncommon->getAsAssumedTemplateName())
102  return AssumedTemplate;
103  if (uncommon->getAsSubstTemplateTemplateParm())
106 }
107 
109  if (Decl *TemplateOrUsing = Storage.dyn_cast<Decl *>()) {
110  if (UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(TemplateOrUsing))
111  return cast<TemplateDecl>(USD->getTargetDecl());
112 
113  assert(isa<TemplateDecl>(TemplateOrUsing));
114  return cast<TemplateDecl>(TemplateOrUsing);
115  }
116 
118  return QTN->getUnderlyingTemplate().getAsTemplateDecl();
119 
121  return sub->getReplacement().getAsTemplateDecl();
122 
124  return cast<TemplateDecl>(USD->getTargetDecl());
125 
126  return nullptr;
127 }
128 
130  if (UncommonTemplateNameStorage *Uncommon =
131  Storage.dyn_cast<UncommonTemplateNameStorage *>())
132  return Uncommon->getAsOverloadedStorage();
133 
134  return nullptr;
135 }
136 
138  if (UncommonTemplateNameStorage *Uncommon =
139  Storage.dyn_cast<UncommonTemplateNameStorage *>())
140  return Uncommon->getAsAssumedTemplateName();
141 
142  return nullptr;
143 }
144 
147  if (UncommonTemplateNameStorage *uncommon =
148  Storage.dyn_cast<UncommonTemplateNameStorage *>())
149  return uncommon->getAsSubstTemplateTemplateParm();
150 
151  return nullptr;
152 }
153 
156  if (UncommonTemplateNameStorage *Uncommon =
157  Storage.dyn_cast<UncommonTemplateNameStorage *>())
158  return Uncommon->getAsSubstTemplateTemplateParmPack();
159 
160  return nullptr;
161 }
162 
164  return Storage.dyn_cast<QualifiedTemplateName *>();
165 }
166 
168  return Storage.dyn_cast<DependentTemplateName *>();
169 }
170 
172  if (Decl *D = Storage.dyn_cast<Decl *>())
173  if (UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(D))
174  return USD;
176  return QTN->getUnderlyingTemplate().getAsUsingShadowDecl();
177  return nullptr;
178 }
179 
182 
183  // Substituting a dependent template name: preserve it as written.
184  if (!Decl)
185  return *this;
186 
187  // If we have a template declaration, use the most recent non-friend
188  // declaration of that template.
189  Decl = cast<TemplateDecl>(Decl->getMostRecentDecl());
190  while (Decl->getFriendObjectKind()) {
191  Decl = cast<TemplateDecl>(Decl->getPreviousDecl());
192  assert(Decl && "all declarations of template are friends");
193  }
194  return TemplateName(Decl);
195 }
196 
197 TemplateNameDependence TemplateName::getDependence() const {
199  switch (getKind()) {
200  case TemplateName::NameKind::QualifiedTemplate:
202  getAsQualifiedTemplateName()->getQualifier()->getDependence());
203  break;
204  case TemplateName::NameKind::DependentTemplate:
206  getAsDependentTemplateName()->getQualifier()->getDependence());
207  break;
208  case TemplateName::NameKind::SubstTemplateTemplateParmPack:
209  D |= TemplateNameDependence::UnexpandedPack;
210  break;
211  case TemplateName::NameKind::OverloadedTemplate:
212  llvm_unreachable("overloaded templates shouldn't survive to here.");
213  default:
214  break;
215  }
217  if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Template)) {
218  D |= TemplateNameDependence::DependentInstantiation;
219  if (TTP->isParameterPack())
220  D |= TemplateNameDependence::UnexpandedPack;
221  }
222  // FIXME: Hack, getDeclContext() can be null if Template is still
223  // initializing due to PCH reading, so we check it before using it.
224  // Should probably modify TemplateSpecializationType to allow constructing
225  // it without the isDependent() checking.
226  if (Template->getDeclContext() &&
227  Template->getDeclContext()->isDependentContext())
228  D |= TemplateNameDependence::DependentInstantiation;
229  } else {
230  D |= TemplateNameDependence::DependentInstantiation;
231  }
232  return D;
233 }
234 
236  return getDependence() & TemplateNameDependence::Dependent;
237 }
238 
240  return getDependence() & TemplateNameDependence::Instantiation;
241 }
242 
244  return getDependence() & TemplateNameDependence::UnexpandedPack;
245 }
246 
247 void TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
248  Qualified Qual) const {
249  auto Kind = getKind();
250  TemplateDecl *Template = nullptr;
252  // After `namespace ns { using std::vector }`, what is the fully-qualified
253  // name of the UsingTemplateName `vector` within ns?
254  //
255  // - ns::vector (the qualified name of the using-shadow decl)
256  // - std::vector (the qualified name of the underlying template decl)
257  //
258  // Similar to the UsingType behavior, using declarations are used to import
259  // names more often than to export them, thus using the original name is
260  // most useful in this case.
262  }
263 
264  if (Template)
265  if (Policy.CleanUglifiedParameters &&
266  isa<TemplateTemplateParmDecl>(Template) && Template->getIdentifier())
267  OS << Template->getIdentifier()->deuglifiedName();
268  else if (Qual == Qualified::Fully &&
269  getDependence() !=
270  TemplateNameDependenceScope::DependentInstantiation)
271  Template->printQualifiedName(OS, Policy);
272  else
273  OS << *Template;
275  if (Qual == Qualified::Fully &&
276  getDependence() !=
277  TemplateNameDependenceScope::DependentInstantiation) {
278  QTN->getUnderlyingTemplate().getAsTemplateDecl()->printQualifiedName(
279  OS, Policy);
280  return;
281  }
282  if (Qual == Qualified::AsWritten)
283  QTN->getQualifier()->print(OS, Policy);
284  if (QTN->hasTemplateKeyword())
285  OS << "template ";
286  OS << *QTN->getUnderlyingTemplate().getAsTemplateDecl();
288  if (Qual == Qualified::AsWritten && DTN->getQualifier())
289  DTN->getQualifier()->print(OS, Policy);
290  OS << "template ";
291 
292  if (DTN->isIdentifier())
293  OS << DTN->getIdentifier()->getName();
294  else
295  OS << "operator " << getOperatorSpelling(DTN->getOperator());
296  } else if (SubstTemplateTemplateParmStorage *subst
298  subst->getReplacement().print(OS, Policy, Qual);
299  } else if (SubstTemplateTemplateParmPackStorage *SubstPack
301  OS << *SubstPack->getParameterPack();
302  else if (AssumedTemplateStorage *Assumed = getAsAssumedTemplateName()) {
303  Assumed->getDeclName().print(OS, Policy);
304  } else {
307  (*OTS->begin())->printName(OS);
308  }
309 }
310 
312  TemplateName N) {
313  std::string NameStr;
314  llvm::raw_string_ostream OS(NameStr);
315  LangOptions LO;
316  LO.CPlusPlus = true;
317  LO.Bool = true;
318  OS << '\'';
319  N.print(OS, PrintingPolicy(LO));
320  OS << '\'';
321  OS.flush();
322  return DB << NameStr;
323 }
324 
325 void TemplateName::dump(raw_ostream &OS) const {
326  LangOptions LO; // FIXME!
327  LO.CPlusPlus = true;
328  LO.Bool = true;
329  print(OS, PrintingPolicy(LO));
330 }
331 
332 LLVM_DUMP_METHOD void TemplateName::dump() const {
333  dump(llvm::errs());
334 }
clang::TemplateName::Qualified::AsWritten
@ AsWritten
clang::SubstTemplateTemplateParmPackStorage::getArgumentPack
TemplateArgument getArgumentPack() const
Retrieve the template template argument pack with which this parameter was substituted.
Definition: TemplateName.cpp:37
clang::TemplateName::isInstantiationDependent
bool isInstantiationDependent() const
Determines whether this is a template name that somehow depends on a template parameter.
Definition: TemplateName.cpp:239
clang::TemplateName::Qualified::Fully
@ Fully
clang::PrintingPolicy::CleanUglifiedParameters
unsigned CleanUglifiedParameters
Whether to strip underscores when printing reserved parameter names.
Definition: PrettyPrinter.h:288
clang::TemplateName::getAsSubstTemplateTemplateParm
SubstTemplateTemplateParmStorage * getAsSubstTemplateTemplateParm() const
Retrieve the substituted template template parameter, if known.
Definition: TemplateName.cpp:146
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
clang::ObjCSubstitutionContext::Parameter
@ Parameter
The parameter type of a method or function.
clang::TemplateName::containsUnexpandedParameterPack
bool containsUnexpandedParameterPack() const
Determines whether this template name contains an unexpanded parameter pack (for C++0x variadic templ...
Definition: TemplateName.cpp:243
DependenceFlags.h
clang::UncommonTemplateNameStorage::getAsAssumedTemplateName
AssumedTemplateStorage * getAsAssumedTemplateName()
Definition: TemplateName.h:84
clang::TemplateArgument::Profile
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const
Used to insert TemplateArguments into FoldingSets.
Definition: TemplateBase.cpp:307
clang::TemplateName::getAsTemplateDecl
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known.
Definition: TemplateName.cpp:108
clang::toTemplateNameDependence
TemplateNameDependence toTemplateNameDependence(NestedNameSpecifierDependence D)
Definition: DependenceFlags.h:314
clang::OverloadedTemplateStorage
A structure for storing the information associated with an overloaded template name.
Definition: TemplateName.h:105
DeclCXX.h
clang::UsingShadowDecl
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Definition: DeclCXX.h:3220
clang::TemplateName::getDependence
TemplateNameDependence getDependence() const
Definition: TemplateName.cpp:197
clang::TemplateName::getAsOverloadedTemplate
OverloadedTemplateStorage * getAsOverloadedTemplate() const
Retrieve the underlying, overloaded function template declarations that this template name refers to,...
Definition: TemplateName.cpp:129
clang::PrintingPolicy
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
clang::UncommonTemplateNameStorage::getAsOverloadedStorage
OverloadedTemplateStorage * getAsOverloadedStorage()
Definition: TemplateName.h:78
clang::TemplateName::getNameToSubstitute
TemplateName getNameToSubstitute() const
Get the template name to substitute when this template name is used as a template template argument.
Definition: TemplateName.cpp:180
TemplateName.h
Decl.h
PrettyPrinter.h
TemplateBase.h
clang::TemplateName::isDependent
bool isDependent() const
Determines whether this is a dependent template name.
Definition: TemplateName.cpp:235
DeclTemplate.h
DeclBase.h
clang::XRayInstrKind::None
constexpr XRayInstrMask None
Definition: XRayInstr.h:38
OperatorKinds.h
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:208
clang::OverloadedTemplateStorage::begin
iterator begin() const
Definition: TemplateName.h:121
clang::StreamingDiagnostic
The streaming interface shared between DiagnosticBuilder and PartialDiagnostic.
Definition: Diagnostic.h:1110
NestedNameSpecifier.h
LangOptions.h
Diagnostic.h
clang::TemplateArgument
Represents a template argument.
Definition: TemplateBase.h:61
clang::TemplateName::getAsAssumedTemplateName
AssumedTemplateStorage * getAsAssumedTemplateName() const
Retrieve information on a name that has been assumed to be a template-name in order to permit a call ...
Definition: TemplateName.cpp:137
clang::TemplateTemplateParmDecl
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
Definition: DeclTemplate.h:1618
clang::TemplateName::Template
@ Template
A single template declaration.
Definition: TemplateName.h:209
clang::TemplateName::getAsUsingShadowDecl
UsingShadowDecl * getAsUsingShadowDecl() const
Retrieve the using shadow declaration through which the underlying template declaration is introduced...
Definition: TemplateName.cpp:171
clang::getOperatorSpelling
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword.
Definition: IdentifierTable.cpp:747
clang::TemplateName::SubstTemplateTemplateParmPack
@ SubstTemplateTemplateParmPack
A template template parameter pack that has been substituted for a template template argument pack,...
Definition: TemplateName.h:233
clang::SubstTemplateTemplateParmPackStorage
A structure for storing an already-substituted template template parameter pack.
Definition: TemplateName.h:135
clang::operator<<
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ASTContext::SectionInfo &Section)
Insertion operator for diagnostics.
Definition: ASTContext.cpp:12322
clang::TemplateName::isNull
bool isNull() const
Determine whether this template name is NULL.
Definition: TemplateName.cpp:82
clang::TemplateName::TemplateName
TemplateName()=default
clang::UncommonTemplateNameStorage
Implementation class used to describe either a set of overloaded template names or an already-substit...
Definition: TemplateName.h:47
clang::DependentTemplateName
Represents a dependent template name that cannot be resolved prior to template instantiation.
Definition: TemplateName.h:462
clang::TemplateName::getKind
NameKind getKind() const
Definition: TemplateName.cpp:84
clang::TemplateName::getAsQualifiedTemplateName
QualifiedTemplateName * getAsQualifiedTemplateName() const
Retrieve the underlying qualified template name structure, if any.
Definition: TemplateName.cpp:163
clang::TemplateName::getAsVoidPointer
void * getAsVoidPointer() const
Retrieve the template name as a void pointer.
Definition: TemplateName.h:349
clang::Decl::getPreviousDecl
Decl * getPreviousDecl()
Retrieve the previous declaration that declares the same entity as this declaration,...
Definition: DeclBase.h:1013
clang::Decl::getFriendObjectKind
FriendObjectKind getFriendObjectKind() const
Determines whether this declaration is the object of a friend declaration and, if so,...
Definition: DeclBase.h:1172
clang::TemplateName::QualifiedTemplate
@ QualifiedTemplate
A qualified template name, where the qualification is kept to describe the source code as written.
Definition: TemplateName.h:220
clang::TemplateName
Represents a C++ template name within the type system.
Definition: TemplateName.h:192
clang::TemplateDecl
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:400
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
clang::TemplateName::dump
void dump() const
Debugging aid that dumps the template name to standard error.
Definition: TemplateName.cpp:332
clang::QualifiedTemplateName
Represents a template name that was expressed as a qualified name.
Definition: TemplateName.h:405
LLVM.h
clang::UncommonTemplateNameStorage::getAsSubstTemplateTemplateParmPack
SubstTemplateTemplateParmPackStorage * getAsSubstTemplateTemplateParmPack()
Definition: TemplateName.h:96
clang::LangOptions
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:78
clang::ObjCPropertyAttribute::Kind
Kind
Definition: DeclObjCCommon.h:22
clang::TemplateName::SubstTemplateTemplateParm
@ SubstTemplateTemplateParm
A template template parameter that has been substituted for some other template name.
Definition: TemplateName.h:228
clang::TemplateName::print
void print(raw_ostream &OS, const PrintingPolicy &Policy, Qualified Qual=Qualified::AsWritten) const
Print the template name.
Definition: TemplateName.cpp:247
clang::Builtin::ID
ID
Definition: Builtins.h:52
clang::SubstTemplateTemplateParmStorage
A structure for storing the information associated with a substituted template template parameter.
Definition: TemplateName.h:364
clang
Definition: CalledOnceCheck.h:17
clang::TemplateName::AssumedTemplate
@ AssumedTemplate
An unqualified-id that has been assumed to name a function template that will be found by ADL.
Definition: TemplateName.h:216
clang::UncommonTemplateNameStorage::size
unsigned size() const
Definition: TemplateName.h:76
clang::TemplateName::getAsDependentTemplateName
DependentTemplateName * getAsDependentTemplateName() const
Retrieve the underlying dependent template name structure, if any.
Definition: TemplateName.cpp:167
clang::SubstTemplateTemplateParmPackStorage::Profile
void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context)
Definition: TemplateName.cpp:52
clang::TemplateName::OverloadedTemplate
@ OverloadedTemplate
A set of overloaded template declarations.
Definition: TemplateName.h:212
clang::UncommonTemplateNameStorage::getAsSubstTemplateTemplateParm
SubstTemplateTemplateParmStorage * getAsSubstTemplateTemplateParm()
Definition: TemplateName.h:90
clang::TemplateName::Qualified
Qualified
Definition: TemplateName.h:325
clang::TemplateName::NameKind
NameKind
Definition: TemplateName.h:207
clang::SubstTemplateTemplateParmStorage::Profile
void Profile(llvm::FoldingSetNodeID &ID)
Definition: TemplateName.cpp:41
clang::TemplateName::getAsSubstTemplateTemplateParmPack
SubstTemplateTemplateParmPackStorage * getAsSubstTemplateTemplateParmPack() const
Retrieve the substituted template template parameter pack, if known.
Definition: TemplateName.cpp:155
clang::AssumedTemplateStorage
A structure for storing the information associated with a name that has been assumed to be a template...
Definition: DeclarationName.h:940
clang::Decl::getMostRecentDecl
Decl * getMostRecentDecl()
Retrieve the most recent declaration that declares the same entity as this declaration (which may be ...
Definition: DeclBase.h:1028
clang::TemplateName::DependentTemplate
@ DependentTemplate
A dependent template name that has not been resolved to a template (or set of templates).
Definition: TemplateName.h:224
clang::TemplateName::UsingTemplate
@ UsingTemplate
A template name that refers to a template declaration found through a specific using shadow declarati...
Definition: TemplateName.h:237