clang  13.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/DeclTemplate.h"
20 #include "clang/AST/TemplateBase.h"
21 #include "clang/Basic/Diagnostic.h"
22 #include "clang/Basic/LLVM.h"
25 #include "llvm/ADT/ArrayRef.h"
26 #include "llvm/ADT/FoldingSet.h"
27 #include "llvm/Support/Casting.h"
28 #include "llvm/Support/Compiler.h"
29 #include "llvm/Support/raw_ostream.h"
30 #include <cassert>
31 #include <string>
32 
33 using namespace clang;
34 
37  return TemplateArgument(llvm::makeArrayRef(Arguments, size()));
38 }
39 
40 void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID) {
41  Profile(ID, Parameter, Replacement);
42 }
43 
44 void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID,
45  TemplateTemplateParmDecl *parameter,
46  TemplateName replacement) {
47  ID.AddPointer(parameter);
48  ID.AddPointer(replacement.getAsVoidPointer());
49 }
50 
52  ASTContext &Context) {
53  Profile(ID, Context, Parameter, getArgumentPack());
54 }
55 
57  ASTContext &Context,
58  TemplateTemplateParmDecl *Parameter,
59  const TemplateArgument &ArgPack) {
60  ID.AddPointer(Parameter);
61  ArgPack.Profile(ID, Context);
62 }
63 
64 TemplateName::TemplateName(void *Ptr) {
65  Storage = StorageType::getFromOpaqueValue(Ptr);
66 }
67 
68 TemplateName::TemplateName(TemplateDecl *Template) : Storage(Template) {}
70  : Storage(Storage) {}
72  : Storage(Storage) {}
74  : Storage(Storage) {}
76  : Storage(Storage) {}
79 
80 bool TemplateName::isNull() const { return Storage.isNull(); }
81 
83  if (Storage.is<TemplateDecl *>())
84  return Template;
85  if (Storage.is<DependentTemplateName *>())
86  return DependentTemplate;
87  if (Storage.is<QualifiedTemplateName *>())
88  return QualifiedTemplate;
89 
91  = Storage.get<UncommonTemplateNameStorage*>();
92  if (uncommon->getAsOverloadedStorage())
93  return OverloadedTemplate;
94  if (uncommon->getAsAssumedTemplateName())
95  return AssumedTemplate;
96  if (uncommon->getAsSubstTemplateTemplateParm())
99 }
100 
102  if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
103  return Template;
104 
106  return QTN->getTemplateDecl();
107 
109  return sub->getReplacement().getAsTemplateDecl();
110 
111  return nullptr;
112 }
113 
115  if (UncommonTemplateNameStorage *Uncommon =
116  Storage.dyn_cast<UncommonTemplateNameStorage *>())
117  return Uncommon->getAsOverloadedStorage();
118 
119  return nullptr;
120 }
121 
123  if (UncommonTemplateNameStorage *Uncommon =
124  Storage.dyn_cast<UncommonTemplateNameStorage *>())
125  return Uncommon->getAsAssumedTemplateName();
126 
127  return nullptr;
128 }
129 
132  if (UncommonTemplateNameStorage *uncommon =
133  Storage.dyn_cast<UncommonTemplateNameStorage *>())
134  return uncommon->getAsSubstTemplateTemplateParm();
135 
136  return nullptr;
137 }
138 
141  if (UncommonTemplateNameStorage *Uncommon =
142  Storage.dyn_cast<UncommonTemplateNameStorage *>())
143  return Uncommon->getAsSubstTemplateTemplateParmPack();
144 
145  return nullptr;
146 }
147 
149  return Storage.dyn_cast<QualifiedTemplateName *>();
150 }
151 
153  return Storage.dyn_cast<DependentTemplateName *>();
154 }
155 
158 
159  // Substituting a dependent template name: preserve it as written.
160  if (!Decl)
161  return *this;
162 
163  // If we have a template declaration, use the most recent non-friend
164  // declaration of that template.
165  Decl = cast<TemplateDecl>(Decl->getMostRecentDecl());
166  while (Decl->getFriendObjectKind()) {
167  Decl = cast<TemplateDecl>(Decl->getPreviousDecl());
168  assert(Decl && "all declarations of template are friends");
169  }
170  return TemplateName(Decl);
171 }
172 
173 TemplateNameDependence TemplateName::getDependence() const {
175  switch (getKind()) {
176  case TemplateName::NameKind::QualifiedTemplate:
178  getAsQualifiedTemplateName()->getQualifier()->getDependence());
179  break;
180  case TemplateName::NameKind::DependentTemplate:
182  getAsDependentTemplateName()->getQualifier()->getDependence());
183  break;
184  case TemplateName::NameKind::SubstTemplateTemplateParmPack:
185  D |= TemplateNameDependence::UnexpandedPack;
186  break;
187  case TemplateName::NameKind::OverloadedTemplate:
188  llvm_unreachable("overloaded templates shouldn't survive to here.");
189  default:
190  break;
191  }
193  if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Template)) {
194  D |= TemplateNameDependence::DependentInstantiation;
195  if (TTP->isParameterPack())
196  D |= TemplateNameDependence::UnexpandedPack;
197  }
198  // FIXME: Hack, getDeclContext() can be null if Template is still
199  // initializing due to PCH reading, so we check it before using it.
200  // Should probably modify TemplateSpecializationType to allow constructing
201  // it without the isDependent() checking.
202  if (Template->getDeclContext() &&
203  Template->getDeclContext()->isDependentContext())
204  D |= TemplateNameDependence::DependentInstantiation;
205  } else {
206  D |= TemplateNameDependence::DependentInstantiation;
207  }
208  return D;
209 }
210 
212  return getDependence() & TemplateNameDependence::Dependent;
213 }
214 
216  return getDependence() & TemplateNameDependence::Instantiation;
217 }
218 
220  return getDependence() & TemplateNameDependence::UnexpandedPack;
221 }
222 
223 void
224 TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
225  bool SuppressNNS) const {
226  if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
227  OS << *Template;
229  if (!SuppressNNS)
230  QTN->getQualifier()->print(OS, Policy);
231  if (QTN->hasTemplateKeyword())
232  OS << "template ";
233  OS << *QTN->getDecl();
235  if (!SuppressNNS && DTN->getQualifier())
236  DTN->getQualifier()->print(OS, Policy);
237  OS << "template ";
238 
239  if (DTN->isIdentifier())
240  OS << DTN->getIdentifier()->getName();
241  else
242  OS << "operator " << getOperatorSpelling(DTN->getOperator());
243  } else if (SubstTemplateTemplateParmStorage *subst
245  subst->getReplacement().print(OS, Policy, SuppressNNS);
246  } else if (SubstTemplateTemplateParmPackStorage *SubstPack
248  OS << *SubstPack->getParameterPack();
249  else if (AssumedTemplateStorage *Assumed = getAsAssumedTemplateName()) {
250  Assumed->getDeclName().print(OS, Policy);
251  } else {
253  (*OTS->begin())->printName(OS);
254  }
255 }
256 
258  TemplateName N) {
259  std::string NameStr;
260  llvm::raw_string_ostream OS(NameStr);
261  LangOptions LO;
262  LO.CPlusPlus = true;
263  LO.Bool = true;
264  OS << '\'';
265  N.print(OS, PrintingPolicy(LO));
266  OS << '\'';
267  OS.flush();
268  return DB << NameStr;
269 }
270 
271 void TemplateName::dump(raw_ostream &OS) const {
272  LangOptions LO; // FIXME!
273  LO.CPlusPlus = true;
274  LO.Bool = true;
275  print(OS, PrintingPolicy(LO));
276 }
277 
278 LLVM_DUMP_METHOD void TemplateName::dump() const {
279  dump(llvm::errs());
280 }
clang::SubstTemplateTemplateParmPackStorage::getArgumentPack
TemplateArgument getArgumentPack() const
Retrieve the template template argument pack with which this parameter was substituted.
Definition: TemplateName.cpp:36
clang::TemplateName::isInstantiationDependent
bool isInstantiationDependent() const
Determines whether this is a template name that somehow depends on a template parameter.
Definition: TemplateName.cpp:215
clang::TemplateName::getAsSubstTemplateTemplateParm
SubstTemplateTemplateParmStorage * getAsSubstTemplateTemplateParm() const
Retrieve the substituted template template parameter, if known.
Definition: TemplateName.cpp:131
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:219
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:231
clang::TemplateName::getAsTemplateDecl
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known.
Definition: TemplateName.cpp:101
clang::toTemplateNameDependence
TemplateNameDependence toTemplateNameDependence(NestedNameSpecifierDependence D)
Definition: DependenceFlags.h:292
clang::OverloadedTemplateStorage
A structure for storing the information associated with an overloaded template name.
Definition: TemplateName.h:105
clang::TemplateName::getDependence
TemplateNameDependence getDependence() const
Definition: TemplateName.cpp:173
clang::TemplateName::getAsOverloadedTemplate
OverloadedTemplateStorage * getAsOverloadedTemplate() const
Retrieve the underlying, overloaded function template declarations that this template name refers to,...
Definition: TemplateName.cpp:114
clang::PrintingPolicy
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:59
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:156
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:211
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:187
clang::OverloadedTemplateStorage::begin
iterator begin() const
Definition: TemplateName.h:121
clang::StreamingDiagnostic
The streaming interface shared between DiagnosticBuilder and PartialDiagnostic.
Definition: Diagnostic.h:1105
NestedNameSpecifier.h
LangOptions.h
Diagnostic.h
clang::TemplateArgument
Represents a template argument.
Definition: TemplateBase.h:62
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:122
clang::TemplateTemplateParmDecl
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
Definition: DeclTemplate.h:1596
clang::TemplateName::Template
@ Template
A single template declaration.
Definition: TemplateName.h:205
clang::getOperatorSpelling
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword.
Definition: IdentifierTable.cpp:697
clang::TemplateName::SubstTemplateTemplateParmPack
@ SubstTemplateTemplateParmPack
A template template parameter pack that has been substituted for a template template argument pack,...
Definition: TemplateName.h:229
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:11534
clang::TemplateName::isNull
bool isNull() const
Determine whether this template name is NULL.
Definition: TemplateName.cpp:80
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:447
clang::TemplateName::getKind
NameKind getKind() const
Definition: TemplateName.cpp:82
clang::TemplateName::getAsQualifiedTemplateName
QualifiedTemplateName * getAsQualifiedTemplateName() const
Retrieve the underlying qualified template name structure, if any.
Definition: TemplateName.cpp:148
clang::TemplateName::getAsVoidPointer
void * getAsVoidPointer() const
Retrieve the template name as a void pointer.
Definition: TemplateName.h:335
clang::Decl::getPreviousDecl
Decl * getPreviousDecl()
Retrieve the previous declaration that declares the same entity as this declaration,...
Definition: DeclBase.h:984
clang::Decl::getFriendObjectKind
FriendObjectKind getFriendObjectKind() const
Determines whether this declaration is the object of a friend declaration and, if so,...
Definition: DeclBase.h:1143
clang::TemplateName::QualifiedTemplate
@ QualifiedTemplate
A qualified template name, where the qualification is kept to describe the source code as written.
Definition: TemplateName.h:216
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:398
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:89
clang::TemplateName::dump
void dump() const
Debugging aid that dumps the template name to standard error.
Definition: TemplateName.cpp:278
clang::QualifiedTemplateName
Represents a template name that was expressed as a qualified name.
Definition: TemplateName.h:391
clang::TemplateName::print
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool SuppressNNS=false) const
Print the template name.
Definition: TemplateName.cpp:224
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:58
clang::TemplateName::SubstTemplateTemplateParm
@ SubstTemplateTemplateParm
A template template parameter that has been substituted for some other template name.
Definition: TemplateName.h:224
clang::Builtin::ID
ID
Definition: Builtins.h:47
clang::SubstTemplateTemplateParmStorage
A structure for storing the information associated with a substituted template template parameter.
Definition: TemplateName.h:350
clang
Dataflow Directional Tag Classes.
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:212
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:152
clang::SubstTemplateTemplateParmPackStorage::Profile
void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context)
Definition: TemplateName.cpp:51
clang::TemplateName::OverloadedTemplate
@ OverloadedTemplate
A set of overloaded template declarations.
Definition: TemplateName.h:208
clang::UncommonTemplateNameStorage::getAsSubstTemplateTemplateParm
SubstTemplateTemplateParmStorage * getAsSubstTemplateTemplateParm()
Definition: TemplateName.h:90
clang::TemplateName::NameKind
NameKind
Definition: TemplateName.h:203
clang::SubstTemplateTemplateParmStorage::Profile
void Profile(llvm::FoldingSetNodeID &ID)
Definition: TemplateName.cpp:40
clang::TemplateName::getAsSubstTemplateTemplateParmPack
SubstTemplateTemplateParmPackStorage * getAsSubstTemplateTemplateParmPack() const
Retrieve the substituted template template parameter pack, if known.
Definition: TemplateName.cpp:140
clang::AssumedTemplateStorage
A structure for storing the information associated with a name that has been assumed to be a template...
Definition: DeclarationName.h:931
clang::Decl::getMostRecentDecl
Decl * getMostRecentDecl()
Retrieve the most recent declaration that declares the same entity as this declaration (which may be ...
Definition: DeclBase.h:999
clang::TemplateName::DependentTemplate
@ DependentTemplate
A dependent template name that has not been resolved to a template (or set of templates).
Definition: TemplateName.h:220