clang  10.0.0svn
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/DeclBase.h"
15 #include "clang/AST/DeclTemplate.h"
18 #include "clang/AST/TemplateBase.h"
19 #include "clang/Basic/Diagnostic.h"
20 #include "clang/Basic/LLVM.h"
23 #include "llvm/ADT/ArrayRef.h"
24 #include "llvm/ADT/FoldingSet.h"
25 #include "llvm/Support/Casting.h"
26 #include "llvm/Support/Compiler.h"
27 #include "llvm/Support/raw_ostream.h"
28 #include <cassert>
29 #include <string>
30 
31 using namespace clang;
32 
35  return TemplateArgument(llvm::makeArrayRef(Arguments, size()));
36 }
37 
38 void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID) {
39  Profile(ID, Parameter, Replacement);
40 }
41 
42 void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID,
43  TemplateTemplateParmDecl *parameter,
44  TemplateName replacement) {
45  ID.AddPointer(parameter);
46  ID.AddPointer(replacement.getAsVoidPointer());
47 }
48 
50  ASTContext &Context) {
51  Profile(ID, Context, Parameter, getArgumentPack());
52 }
53 
55  ASTContext &Context,
56  TemplateTemplateParmDecl *Parameter,
57  const TemplateArgument &ArgPack) {
58  ID.AddPointer(Parameter);
59  ArgPack.Profile(ID, Context);
60 }
61 
62 TemplateName::TemplateName(void *Ptr) {
63  Storage = StorageType::getFromOpaqueValue(Ptr);
64 }
65 
66 TemplateName::TemplateName(TemplateDecl *Template) : Storage(Template) {}
68  : Storage(Storage) {}
70  : Storage(Storage) {}
72  : Storage(Storage) {}
74  : Storage(Storage) {}
77 
78 bool TemplateName::isNull() const { return Storage.isNull(); }
79 
81  if (Storage.is<TemplateDecl *>())
82  return Template;
83  if (Storage.is<DependentTemplateName *>())
84  return DependentTemplate;
85  if (Storage.is<QualifiedTemplateName *>())
86  return QualifiedTemplate;
87 
89  = Storage.get<UncommonTemplateNameStorage*>();
90  if (uncommon->getAsOverloadedStorage())
91  return OverloadedTemplate;
92  if (uncommon->getAsAssumedTemplateName())
93  return AssumedTemplate;
94  if (uncommon->getAsSubstTemplateTemplateParm())
97 }
98 
100  if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
101  return Template;
102 
104  return QTN->getTemplateDecl();
105 
107  return sub->getReplacement().getAsTemplateDecl();
108 
109  return nullptr;
110 }
111 
113  if (UncommonTemplateNameStorage *Uncommon =
114  Storage.dyn_cast<UncommonTemplateNameStorage *>())
115  return Uncommon->getAsOverloadedStorage();
116 
117  return nullptr;
118 }
119 
121  if (UncommonTemplateNameStorage *Uncommon =
122  Storage.dyn_cast<UncommonTemplateNameStorage *>())
123  return Uncommon->getAsAssumedTemplateName();
124 
125  return nullptr;
126 }
127 
130  if (UncommonTemplateNameStorage *uncommon =
131  Storage.dyn_cast<UncommonTemplateNameStorage *>())
132  return uncommon->getAsSubstTemplateTemplateParm();
133 
134  return nullptr;
135 }
136 
139  if (UncommonTemplateNameStorage *Uncommon =
140  Storage.dyn_cast<UncommonTemplateNameStorage *>())
141  return Uncommon->getAsSubstTemplateTemplateParmPack();
142 
143  return nullptr;
144 }
145 
147  return Storage.dyn_cast<QualifiedTemplateName *>();
148 }
149 
151  return Storage.dyn_cast<DependentTemplateName *>();
152 }
153 
156 
157  // Substituting a dependent template name: preserve it as written.
158  if (!Decl)
159  return *this;
160 
161  // If we have a template declaration, use the most recent non-friend
162  // declaration of that template.
163  Decl = cast<TemplateDecl>(Decl->getMostRecentDecl());
164  while (Decl->getFriendObjectKind()) {
165  Decl = cast<TemplateDecl>(Decl->getPreviousDecl());
166  assert(Decl && "all declarations of template are friends");
167  }
168  return TemplateName(Decl);
169 }
170 
173  if (isa<TemplateTemplateParmDecl>(Template))
174  return true;
175  // FIXME: Hack, getDeclContext() can be null if Template is still
176  // initializing due to PCH reading, so we check it before using it.
177  // Should probably modify TemplateSpecializationType to allow constructing
178  // it without the isDependent() checking.
179  return Template->getDeclContext() &&
180  Template->getDeclContext()->isDependentContext();
181  }
182 
183  assert(!getAsOverloadedTemplate() &&
184  "overloaded templates shouldn't survive to here");
185 
186  return true;
187 }
188 
191  if (QTN->getQualifier()->isInstantiationDependent())
192  return true;
193  }
194 
195  return isDependent();
196 }
197 
200  if (QTN->getQualifier()->containsUnexpandedParameterPack())
201  return true;
202  }
203 
205  if (TemplateTemplateParmDecl *TTP
206  = dyn_cast<TemplateTemplateParmDecl>(Template))
207  return TTP->isParameterPack();
208 
209  return false;
210  }
211 
213  return DTN->getQualifier() &&
214  DTN->getQualifier()->containsUnexpandedParameterPack();
215 
216  return getAsSubstTemplateTemplateParmPack() != nullptr;
217 }
218 
219 void
220 TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
221  bool SuppressNNS) const {
222  if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
223  OS << *Template;
225  if (!SuppressNNS)
226  QTN->getQualifier()->print(OS, Policy);
227  if (QTN->hasTemplateKeyword())
228  OS << "template ";
229  OS << *QTN->getDecl();
231  if (!SuppressNNS && DTN->getQualifier())
232  DTN->getQualifier()->print(OS, Policy);
233  OS << "template ";
234 
235  if (DTN->isIdentifier())
236  OS << DTN->getIdentifier()->getName();
237  else
238  OS << "operator " << getOperatorSpelling(DTN->getOperator());
239  } else if (SubstTemplateTemplateParmStorage *subst
241  subst->getReplacement().print(OS, Policy, SuppressNNS);
242  } else if (SubstTemplateTemplateParmPackStorage *SubstPack
244  OS << *SubstPack->getParameterPack();
245  else if (AssumedTemplateStorage *Assumed = getAsAssumedTemplateName()) {
246  Assumed->getDeclName().print(OS, Policy);
247  } else {
249  (*OTS->begin())->printName(OS);
250  }
251 }
252 
254  TemplateName N) {
255  std::string NameStr;
256  llvm::raw_string_ostream OS(NameStr);
257  LangOptions LO;
258  LO.CPlusPlus = true;
259  LO.Bool = true;
260  OS << '\'';
261  N.print(OS, PrintingPolicy(LO));
262  OS << '\'';
263  OS.flush();
264  return DB << NameStr;
265 }
266 
268  TemplateName N) {
269  std::string NameStr;
270  llvm::raw_string_ostream OS(NameStr);
271  LangOptions LO;
272  LO.CPlusPlus = true;
273  LO.Bool = true;
274  OS << '\'';
275  N.print(OS, PrintingPolicy(LO));
276  OS << '\'';
277  OS.flush();
278  return PD << NameStr;
279 }
280 
281 void TemplateName::dump(raw_ostream &OS) const {
282  LangOptions LO; // FIXME!
283  LO.CPlusPlus = true;
284  LO.Bool = true;
285  print(OS, PrintingPolicy(LO));
286 }
287 
288 LLVM_DUMP_METHOD void TemplateName::dump() const {
289  dump(llvm::errs());
290 }
void dump() const
Debugging aid that dumps the template name to standard error.
void * getAsVoidPointer() const
Retrieve the template name as a void pointer.
Definition: TemplateName.h:328
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:88
Defines the C++ template declaration subclasses.
Decl * getPreviousDecl()
Retrieve the previous declaration that declares the same entity as this declaration, or NULL if there is no previous declaration.
Definition: DeclBase.h:960
const DiagnosticBuilder & operator<<(const DiagnosticBuilder &DB, const Attr *At)
Definition: Attr.h:334
A template template parameter that has been substituted for some other template name.
Definition: TemplateName.h:219
void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context)
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const
Used to insert TemplateArguments into FoldingSets.
QualifiedTemplateName * getAsQualifiedTemplateName() const
Retrieve the underlying qualified template name structure, if any.
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:37
SubstTemplateTemplateParmStorage * getAsSubstTemplateTemplateParm() const
Retrieve the substituted template template parameter, if known.
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool SuppressNNS=false) const
Print the template name.
TemplateName getNameToSubstitute() const
Get the template name to substitute when this template name is used as a template template argument...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:160
Represents a dependent template name that cannot be resolved prior to template instantiation.
Definition: TemplateName.h:442
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known...
SubstTemplateTemplateParmPackStorage * getAsSubstTemplateTemplateParmPack() const
Retrieve the substituted template template parameter pack, if known.
SubstTemplateTemplateParmStorage * getAsSubstTemplateTemplateParm()
Definition: TemplateName.h:89
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:49
A qualified template name, where the qualification is kept to describe the source code as written...
Definition: TemplateName.h:211
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
An unqualified-id that has been assumed to name a function template that will be found by ADL...
Definition: TemplateName.h:207
Defines the Diagnostic-related interfaces.
SubstTemplateTemplateParmPackStorage * getAsSubstTemplateTemplateParmPack()
Definition: TemplateName.h:95
bool containsUnexpandedParameterPack() const
Determines whether this template name contains an unexpanded parameter pack (for C++0x variadic templ...
A little helper class used to produce diagnostics.
Definition: Diagnostic.h:1043
A dependent template name that has not been resolved to a template (or set of templates).
Definition: TemplateName.h:215
Defines the clang::LangOptions interface.
Defines an enumeration for C++ overloaded operators.
void Profile(llvm::FoldingSetNodeID &ID)
A structure for storing the information associated with a substituted template template parameter...
Definition: TemplateName.h:345
Represents a C++ template name within the type system.
Definition: TemplateName.h:187
TemplateName()=default
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
FriendObjectKind getFriendObjectKind() const
Determines whether this declaration is the object of a friend declaration and, if so...
Definition: DeclBase.h:1111
A template template parameter pack that has been substituted for a template template argument pack...
Definition: TemplateName.h:224
OverloadedTemplateStorage * getAsOverloadedStorage()
Definition: TemplateName.h:77
OverloadedTemplateStorage * getAsOverloadedTemplate() const
Retrieve the underlying, overloaded function template declarations that this template name refers to...
A structure for storing an already-substituted template template parameter pack.
Definition: TemplateName.h:130
DependentTemplateName * getAsDependentTemplateName() const
Retrieve the underlying dependent template name structure, if any.
Represents a template argument.
Definition: TemplateBase.h:50
Represents a template name that was expressed as a qualified name.
Definition: TemplateName.h:386
bool isNull() const
Determine whether this template name is NULL.
Dataflow Directional Tag Classes.
AssumedTemplateStorage * getAsAssumedTemplateName()
Definition: TemplateName.h:83
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:403
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword...
AssumedTemplateStorage * getAsAssumedTemplateName() const
Retrieve information on a name that has been assumed to be a template-name in order to permit a call ...
A structure for storing the information associated with an overloaded template name.
Definition: TemplateName.h:104
A structure for storing the information associated with a name that has been assumed to be a template...
NameKind getKind() const
NamedDecl * getMostRecentDecl()
Definition: Decl.h:453
TemplateArgument getArgumentPack() const
Retrieve the template template argument pack with which this parameter was substituted.
A set of overloaded template declarations.
Definition: TemplateName.h:203
Implementation class used to describe either a set of overloaded template names or an already-substit...
Definition: TemplateName.h:46
bool isDependent() const
Determines whether this is a dependent template name.
A single template declaration.
Definition: TemplateName.h:200
bool isInstantiationDependent() const
Determines whether this is a template name that somehow depends on a template parameter.