clang  6.0.0svn
TemplateName.cpp
Go to the documentation of this file.
1 //===- TemplateName.cpp - C++ Template Name Representation ----------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the TemplateName interface and subclasses.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/AST/TemplateName.h"
15 #include "clang/AST/DeclBase.h"
16 #include "clang/AST/DeclTemplate.h"
19 #include "clang/AST/TemplateBase.h"
20 #include "clang/Basic/Diagnostic.h"
21 #include "clang/Basic/LLVM.h"
24 #include "llvm/ADT/ArrayRef.h"
25 #include "llvm/ADT/FoldingSet.h"
26 #include "llvm/Support/Casting.h"
27 #include "llvm/Support/Compiler.h"
28 #include "llvm/Support/raw_ostream.h"
29 #include <cassert>
30 #include <string>
31 
32 using namespace clang;
33 
36  return TemplateArgument(llvm::makeArrayRef(Arguments, size()));
37 }
38 
39 void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID) {
40  Profile(ID, Parameter, Replacement);
41 }
42 
43 void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID,
44  TemplateTemplateParmDecl *parameter,
45  TemplateName replacement) {
46  ID.AddPointer(parameter);
47  ID.AddPointer(replacement.getAsVoidPointer());
48 }
49 
51  ASTContext &Context) {
52  Profile(ID, Context, Parameter, getArgumentPack());
53 }
54 
55 void SubstTemplateTemplateParmPackStorage::Profile(llvm::FoldingSetNodeID &ID,
56  ASTContext &Context,
57  TemplateTemplateParmDecl *Parameter,
58  const TemplateArgument &ArgPack) {
59  ID.AddPointer(Parameter);
60  ArgPack.Profile(ID, Context);
61 }
62 
63 TemplateName::TemplateName(void *Ptr) {
64  Storage = StorageType::getFromOpaqueValue(Ptr);
65 }
66 
67 TemplateName::TemplateName(TemplateDecl *Template) : Storage(Template) {}
69  : Storage(Storage) {}
71  : Storage(Storage) {}
73  : Storage(Storage) {}
76 
77 bool TemplateName::isNull() const { return Storage.isNull(); }
78 
80  if (Storage.is<TemplateDecl *>())
81  return Template;
82  if (Storage.is<DependentTemplateName *>())
83  return DependentTemplate;
84  if (Storage.is<QualifiedTemplateName *>())
85  return QualifiedTemplate;
86 
88  = Storage.get<UncommonTemplateNameStorage*>();
89  if (uncommon->getAsOverloadedStorage())
90  return OverloadedTemplate;
91  if (uncommon->getAsSubstTemplateTemplateParm())
94 }
95 
97  if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
98  return Template;
99 
101  return QTN->getTemplateDecl();
102 
104  return sub->getReplacement().getAsTemplateDecl();
105 
106  return nullptr;
107 }
108 
110  if (UncommonTemplateNameStorage *Uncommon =
111  Storage.dyn_cast<UncommonTemplateNameStorage *>())
112  return Uncommon->getAsOverloadedStorage();
113 
114  return nullptr;
115 }
116 
119  if (UncommonTemplateNameStorage *uncommon =
120  Storage.dyn_cast<UncommonTemplateNameStorage *>())
121  return uncommon->getAsSubstTemplateTemplateParm();
122 
123  return nullptr;
124 }
125 
128  if (UncommonTemplateNameStorage *Uncommon =
129  Storage.dyn_cast<UncommonTemplateNameStorage *>())
130  return Uncommon->getAsSubstTemplateTemplateParmPack();
131 
132  return nullptr;
133 }
134 
136  return Storage.dyn_cast<QualifiedTemplateName *>();
137 }
138 
140  return Storage.dyn_cast<DependentTemplateName *>();
141 }
142 
145 
146  // Substituting a dependent template name: preserve it as written.
147  if (!Decl)
148  return *this;
149 
150  // If we have a template declaration, use the most recent non-friend
151  // declaration of that template.
152  Decl = cast<TemplateDecl>(Decl->getMostRecentDecl());
153  while (Decl->getFriendObjectKind()) {
154  Decl = cast<TemplateDecl>(Decl->getPreviousDecl());
155  assert(Decl && "all declarations of template are friends");
156  }
157  return TemplateName(Decl);
158 }
159 
162  if (isa<TemplateTemplateParmDecl>(Template))
163  return true;
164  // FIXME: Hack, getDeclContext() can be null if Template is still
165  // initializing due to PCH reading, so we check it before using it.
166  // Should probably modify TemplateSpecializationType to allow constructing
167  // it without the isDependent() checking.
168  return Template->getDeclContext() &&
169  Template->getDeclContext()->isDependentContext();
170  }
171 
172  assert(!getAsOverloadedTemplate() &&
173  "overloaded templates shouldn't survive to here");
174 
175  return true;
176 }
177 
180  if (QTN->getQualifier()->isInstantiationDependent())
181  return true;
182  }
183 
184  return isDependent();
185 }
186 
189  if (TemplateTemplateParmDecl *TTP
190  = dyn_cast<TemplateTemplateParmDecl>(Template))
191  return TTP->isParameterPack();
192 
193  return false;
194  }
195 
197  return DTN->getQualifier() &&
198  DTN->getQualifier()->containsUnexpandedParameterPack();
199 
200  return getAsSubstTemplateTemplateParmPack() != nullptr;
201 }
202 
203 void
204 TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
205  bool SuppressNNS) const {
206  if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
207  OS << *Template;
209  if (!SuppressNNS)
210  QTN->getQualifier()->print(OS, Policy);
211  if (QTN->hasTemplateKeyword())
212  OS << "template ";
213  OS << *QTN->getDecl();
215  if (!SuppressNNS && DTN->getQualifier())
216  DTN->getQualifier()->print(OS, Policy);
217  OS << "template ";
218 
219  if (DTN->isIdentifier())
220  OS << DTN->getIdentifier()->getName();
221  else
222  OS << "operator " << getOperatorSpelling(DTN->getOperator());
223  } else if (SubstTemplateTemplateParmStorage *subst
225  subst->getReplacement().print(OS, Policy, SuppressNNS);
226  } else if (SubstTemplateTemplateParmPackStorage *SubstPack
228  OS << *SubstPack->getParameterPack();
229  else {
231  (*OTS->begin())->printName(OS);
232  }
233 }
234 
236  TemplateName N) {
237  std::string NameStr;
238  llvm::raw_string_ostream OS(NameStr);
239  LangOptions LO;
240  LO.CPlusPlus = true;
241  LO.Bool = true;
242  OS << '\'';
243  N.print(OS, PrintingPolicy(LO));
244  OS << '\'';
245  OS.flush();
246  return DB << NameStr;
247 }
248 
249 void TemplateName::dump(raw_ostream &OS) const {
250  LangOptions LO; // FIXME!
251  LO.CPlusPlus = true;
252  LO.Bool = true;
253  print(OS, PrintingPolicy(LO));
254 }
255 
256 LLVM_DUMP_METHOD void TemplateName::dump() const {
257  dump(llvm::errs());
258 }
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:310
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
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:948
const DiagnosticBuilder & operator<<(const DiagnosticBuilder &DB, const Attr *At)
Definition: Attr.h:195
A template template parameter that has been substituted for some other template name.
Definition: TemplateName.h:206
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:38
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:149
Represents a dependent template name that cannot be resolved prior to template instantiation.
Definition: TemplateName.h:422
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:80
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:48
A qualified template name, where the qualification is kept to describe the source code as written...
Definition: TemplateName.h:198
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
Defines the Diagnostic-related interfaces.
SubstTemplateTemplateParmPackStorage * getAsSubstTemplateTemplateParmPack()
Definition: TemplateName.h:86
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:955
A dependent template name that has not been resolved to a template (or set of templates).
Definition: TemplateName.h:202
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:325
Represents a C++ template name within the type system.
Definition: TemplateName.h:178
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:1098
A template template parameter pack that has been substituted for a template template argument pack...
Definition: TemplateName.h:211
OverloadedTemplateStorage * getAsOverloadedStorage()
Definition: TemplateName.h:74
OverloadedTemplateStorage * getAsOverloadedTemplate() const
Retrieve the underlying, overloaded function template.
A structure for storing an already-substituted template template parameter pack.
Definition: TemplateName.h:121
DependentTemplateName * getAsDependentTemplateName() const
Retrieve the underlying dependent template name structure, if any.
Represents a template argument.
Definition: TemplateBase.h:51
Represents a template name that was expressed as a qualified name.
Definition: TemplateName.h:366
bool isNull() const
Determine whether this template name is NULL.
Dataflow Directional Tag Classes.
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:399
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword...
const Expr * Replacement
Definition: AttributeList.h:59
A structure for storing the information associated with an overloaded template name.
Definition: TemplateName.h:95
NameKind getKind() const
NamedDecl * getMostRecentDecl()
Definition: Decl.h:437
TemplateArgument getArgumentPack() const
Retrieve the template template argument pack with which this parameter was substituted.
A set of overloaded template declarations.
Definition: TemplateName.h:194
Implementation class used to describe either a set of overloaded template names or an already-substit...
Definition: TemplateName.h:44
bool isDependent() const
Determines whether this is a dependent template name.
A single template declaration.
Definition: TemplateName.h:191
bool isInstantiationDependent() const
Determines whether this is a template name that somehow depends on a template parameter.