clang  8.0.0svn
DeclarationName.cpp
Go to the documentation of this file.
1 //===- DeclarationName.cpp - Declaration names implementation -------------===//
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 implements the DeclarationName and DeclarationNameTable
11 // classes.
12 //
13 //===----------------------------------------------------------------------===//
14 
16 #include "clang/AST/ASTContext.h"
17 #include "clang/AST/Decl.h"
18 #include "clang/AST/DeclBase.h"
19 #include "clang/AST/DeclCXX.h"
20 #include "clang/AST/DeclTemplate.h"
22 #include "clang/AST/Type.h"
23 #include "clang/AST/TypeLoc.h"
24 #include "clang/AST/TypeOrdering.h"
26 #include "clang/Basic/LLVM.h"
30 #include "llvm/ADT/FoldingSet.h"
31 #include "llvm/Support/Casting.h"
32 #include "llvm/Support/Compiler.h"
33 #include "llvm/Support/ErrorHandling.h"
34 #include "llvm/Support/raw_ostream.h"
35 #include <algorithm>
36 #include <cassert>
37 #include <cstdint>
38 #include <string>
39 
40 using namespace clang;
41 
42 static int compareInt(unsigned A, unsigned B) {
43  return (A < B ? -1 : (A > B ? 1 : 0));
44 }
45 
47  if (LHS.getNameKind() != RHS.getNameKind())
48  return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
49 
50  switch (LHS.getNameKind()) {
52  IdentifierInfo *LII = LHS.castAsIdentifierInfo();
53  IdentifierInfo *RII = RHS.castAsIdentifierInfo();
54  if (!LII)
55  return RII ? -1 : 0;
56  if (!RII)
57  return 1;
58 
59  return LII->getName().compare(RII->getName());
60  }
61 
65  Selector LHSSelector = LHS.getObjCSelector();
66  Selector RHSSelector = RHS.getObjCSelector();
67  // getNumArgs for ZeroArgSelector returns 0, but we still need to compare.
70  return LHSSelector.getAsIdentifierInfo()->getName().compare(
71  RHSSelector.getAsIdentifierInfo()->getName());
72  }
73  unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
74  for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
75  switch (LHSSelector.getNameForSlot(I).compare(
76  RHSSelector.getNameForSlot(I))) {
77  case -1:
78  return -1;
79  case 1:
80  return 1;
81  default:
82  break;
83  }
84  }
85 
86  return compareInt(LN, RN);
87  }
88 
93  return -1;
95  return 1;
96  return 0;
97 
99  // We never want to compare deduction guide names for templates from
100  // different scopes, so just compare the template-name.
103 
107 
109  return LHS.getCXXLiteralIdentifier()->getName().compare(
111 
113  return 0;
114  }
115 
116  llvm_unreachable("Invalid DeclarationName Kind!");
117 }
118 
120  raw_ostream &OS,
121  PrintingPolicy Policy) {
122  // We know we're printing C++ here. Ensure we print types properly.
123  Policy.adjustForCPlusPlus();
124 
125  if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) {
126  OS << *ClassRec->getDecl();
127  return;
128  }
130  if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) {
131  OS << *InjTy->getDecl();
132  return;
133  }
134  }
135  ClassType.print(OS, Policy);
136 }
137 
138 void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) {
139  switch (getNameKind()) {
141  if (const IdentifierInfo *II = getAsIdentifierInfo())
142  OS << II->getName();
143  return;
144 
148  getObjCSelector().print(OS);
149  return;
150 
153 
155  OS << '~';
157 
159  OS << "<deduction guide for ";
161  OS << '>';
162  return;
163 
164  case DeclarationName::CXXOperatorName: {
165  static const char *const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
166  nullptr,
167 #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
168  Spelling,
169 #include "clang/Basic/OperatorKinds.def"
170  };
171  const char *OpName = OperatorNames[getCXXOverloadedOperator()];
172  assert(OpName && "not an overloaded operator");
173 
174  OS << "operator";
175  if (OpName[0] >= 'a' && OpName[0] <= 'z')
176  OS << ' ';
177  OS << OpName;
178  return;
179  }
180 
181  case DeclarationName::CXXLiteralOperatorName:
182  OS << "operator\"\"" << getCXXLiteralIdentifier()->getName();
183  return;
184 
185  case DeclarationName::CXXConversionFunctionName: {
186  OS << "operator ";
187  QualType Type = getCXXNameType();
188  if (const RecordType *Rec = Type->getAs<RecordType>()) {
189  OS << *Rec->getDecl();
190  return;
191  }
192  // We know we're printing C++ here, ensure we print 'bool' properly.
193  PrintingPolicy CXXPolicy = Policy;
194  CXXPolicy.adjustForCPlusPlus();
195  Type.print(OS, CXXPolicy);
196  return;
197  }
199  OS << "<using-directive>";
200  return;
201  }
202 
203  llvm_unreachable("Unexpected declaration name kind");
204 }
205 
206 namespace clang {
207 
208 raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
209  LangOptions LO;
210  N.print(OS, PrintingPolicy(LO));
211  return OS;
212 }
213 
214 } // namespace clang
215 
217  QualType T = getCXXNameType();
218  if (!T.isNull() && T->isDependentType())
219  return true;
220 
221  // A class-scope deduction guide in a dependent context has a dependent name.
222  auto *TD = getCXXDeductionGuideTemplate();
223  if (TD && TD->getDeclContext()->isDependentContext())
224  return true;
225 
226  return false;
227 }
228 
229 std::string DeclarationName::getAsString() const {
230  std::string Result;
231  llvm::raw_string_ostream OS(Result);
232  OS << *this;
233  return OS.str();
234 }
235 
236 void *DeclarationName::getFETokenInfoSlow() const {
237  switch (getNameKind()) {
238  case Identifier:
239  llvm_unreachable("case Identifier already handled by getFETokenInfo!");
240  case CXXConstructorName:
241  case CXXDestructorName:
243  return castAsCXXSpecialNameExtra()->FETokenInfo;
244  case CXXOperatorName:
245  return castAsCXXOperatorIdName()->FETokenInfo;
247  return castAsCXXDeductionGuideNameExtra()->FETokenInfo;
249  return castAsCXXLiteralOperatorIdName()->FETokenInfo;
250  default:
251  llvm_unreachable("DeclarationName has no FETokenInfo!");
252  }
253 }
254 
255 void DeclarationName::setFETokenInfoSlow(void *T) {
256  switch (getNameKind()) {
257  case Identifier:
258  llvm_unreachable("case Identifier already handled by setFETokenInfo!");
259  case CXXConstructorName:
260  case CXXDestructorName:
262  castAsCXXSpecialNameExtra()->FETokenInfo = T;
263  break;
264  case CXXOperatorName:
265  castAsCXXOperatorIdName()->FETokenInfo = T;
266  break;
268  castAsCXXDeductionGuideNameExtra()->FETokenInfo = T;
269  break;
271  castAsCXXLiteralOperatorIdName()->FETokenInfo = T;
272  break;
273  default:
274  llvm_unreachable("DeclarationName has no FETokenInfo!");
275  }
276 }
277 
278 LLVM_DUMP_METHOD void DeclarationName::dump() const {
279  llvm::errs() << *this << '\n';
280 }
281 
283  // Initialize the overloaded operator names.
284  for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op)
285  CXXOperatorNames[Op].Kind = static_cast<OverloadedOperatorKind>(Op);
286 }
287 
290  Template = cast<TemplateDecl>(Template->getCanonicalDecl());
291 
292  llvm::FoldingSetNodeID ID;
293  ID.AddPointer(Template);
294 
295  void *InsertPos = nullptr;
296  if (auto *Name = CXXDeductionGuideNames.FindNodeOrInsertPos(ID, InsertPos))
297  return DeclarationName(Name);
298 
299  auto *Name = new (Ctx) detail::CXXDeductionGuideNameExtra(Template);
300  CXXDeductionGuideNames.InsertNode(Name, InsertPos);
301  return DeclarationName(Name);
302 }
303 
305  // The type of constructors is unqualified.
306  Ty = Ty.getUnqualifiedType();
307  // Do we already have this C++ constructor name ?
308  llvm::FoldingSetNodeID ID;
309  ID.AddPointer(Ty.getAsOpaquePtr());
310  void *InsertPos = nullptr;
311  if (auto *Name = CXXConstructorNames.FindNodeOrInsertPos(ID, InsertPos))
312  return {Name, DeclarationName::StoredCXXConstructorName};
313 
314  // We have to create it.
315  auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
316  CXXConstructorNames.InsertNode(SpecialName, InsertPos);
317  return {SpecialName, DeclarationName::StoredCXXConstructorName};
318 }
319 
321  // The type of destructors is unqualified.
322  Ty = Ty.getUnqualifiedType();
323  // Do we already have this C++ destructor name ?
324  llvm::FoldingSetNodeID ID;
325  ID.AddPointer(Ty.getAsOpaquePtr());
326  void *InsertPos = nullptr;
327  if (auto *Name = CXXDestructorNames.FindNodeOrInsertPos(ID, InsertPos))
328  return {Name, DeclarationName::StoredCXXDestructorName};
329 
330  // We have to create it.
331  auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
332  CXXDestructorNames.InsertNode(SpecialName, InsertPos);
333  return {SpecialName, DeclarationName::StoredCXXDestructorName};
334 }
335 
338  // Do we already have this C++ conversion function name ?
339  llvm::FoldingSetNodeID ID;
340  ID.AddPointer(Ty.getAsOpaquePtr());
341  void *InsertPos = nullptr;
342  if (auto *Name =
343  CXXConversionFunctionNames.FindNodeOrInsertPos(ID, InsertPos))
344  return {Name, DeclarationName::StoredCXXConversionFunctionName};
345 
346  // We have to create it.
347  auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
348  CXXConversionFunctionNames.InsertNode(SpecialName, InsertPos);
349  return {SpecialName, DeclarationName::StoredCXXConversionFunctionName};
350 }
351 
354  CanQualType Ty) {
355  switch (Kind) {
357  return getCXXConstructorName(Ty);
359  return getCXXDestructorName(Ty);
361  return getCXXConversionFunctionName(Ty);
362  default:
363  llvm_unreachable("Invalid kind in getCXXSpecialName!");
364  }
365 }
366 
369  llvm::FoldingSetNodeID ID;
370  ID.AddPointer(II);
371 
372  void *InsertPos = nullptr;
373  if (auto *Name = CXXLiteralOperatorNames.FindNodeOrInsertPos(ID, InsertPos))
374  return DeclarationName(Name);
375 
376  auto *LiteralName = new (Ctx) detail::CXXLiteralOperatorIdName(II);
377  CXXLiteralOperatorNames.InsertNode(LiteralName, InsertPos);
378  return DeclarationName(LiteralName);
379 }
380 
382  switch (Name.getNameKind()) {
385  break;
389  NamedType.TInfo = nullptr;
390  break;
392  CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
393  CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
394  break;
396  CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
397  break;
401  // FIXME: ?
402  break;
404  break;
405  }
406 }
407 
409  switch (Name.getNameKind()) {
418  return false;
419 
423  if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
424  return TInfo->getType()->containsUnexpandedParameterPack();
425 
426  return Name.getCXXNameType()->containsUnexpandedParameterPack();
427  }
428  llvm_unreachable("All name kinds handled.");
429 }
430 
432  switch (Name.getNameKind()) {
441  return false;
442 
446  if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
447  return TInfo->getType()->isInstantiationDependentType();
448 
449  return Name.getCXXNameType()->isInstantiationDependentType();
450  }
451  llvm_unreachable("All name kinds handled.");
452 }
453 
454 std::string DeclarationNameInfo::getAsString() const {
455  std::string Result;
456  llvm::raw_string_ostream OS(Result);
457  printName(OS);
458  return OS.str();
459 }
460 
461 void DeclarationNameInfo::printName(raw_ostream &OS) const {
462  switch (Name.getNameKind()) {
471  OS << Name;
472  return;
473 
477  if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
478  if (Name.getNameKind() == DeclarationName::CXXDestructorName)
479  OS << '~';
480  else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
481  OS << "operator ";
482  LangOptions LO;
483  LO.CPlusPlus = true;
484  LO.Bool = true;
485  PrintingPolicy PP(LO);
486  PP.SuppressScope = true;
487  OS << TInfo->getType().getAsString(PP);
488  } else
489  OS << Name;
490  return;
491  }
492  llvm_unreachable("Unexpected declaration name kind");
493 }
494 
495 SourceLocation DeclarationNameInfo::getEndLocPrivate() const {
496  switch (Name.getNameKind()) {
499  return NameLoc;
500 
502  unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
504  }
505 
507  unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
509  }
510 
514  if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
515  return TInfo->getTypeLoc().getEndLoc();
516  else
517  return NameLoc;
518 
519  // DNInfo work in progress: FIXME.
524  return NameLoc;
525  }
526  llvm_unreachable("Unexpected declaration name kind");
527 }
Defines the clang::ASTContext interface.
Smart pointer class that efficiently represents Objective-C method names.
unsigned getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it...
A (possibly-)qualified type.
Definition: Type.h:638
NameKind
The kind of the name stored in this DeclarationName.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Definition: Type.h:981
DeclarationName getCXXConstructorName(CanQualType Ty)
Returns the name of a C++ constructor for the given Type.
C Language Family Type Representation.
DeclarationName getCXXConversionFunctionName(CanQualType Ty)
Returns the name of a C++ conversion function for the given Type.
Selector getObjCSelector() const
Get the Objective-C selector stored in this declaration name.
Defines the C++ template declaration subclasses.
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
const DiagnosticBuilder & operator<<(const DiagnosticBuilder &DB, const Attr *At)
Definition: Attr.h:335
The base class of the type hierarchy.
Definition: Type.h:1411
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
A container of type source information.
Definition: Decl.h:86
bool isInstantiationDependent() const
Determine whether this name involves a template parameter.
DeclarationName getCXXDeductionGuideName(TemplateDecl *TD)
Returns the name of a C++ deduction guide for the given template.
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6734
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:38
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:297
One of these records is kept for each identifier that is lexed.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:154
static SourceLocation getFromRawEncoding(unsigned Encoding)
Turn a raw encoding of a SourceLocation object into a real SourceLocation.
NameKind getNameKind() const
Determine what kind of name this is.
DeclarationName getCXXDestructorName(CanQualType Ty)
Returns the name of a C++ destructor for the given Type.
static int compareInt(unsigned A, unsigned B)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:50
bool isDependentName() const
Determines whether the name itself is dependent, e.g., because it involves a C++ type that is itself ...
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
bool containsUnexpandedParameterPack() const
Determine whether this name contains an unexpanded parameter pack.
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:870
unsigned SuppressTemplateArgsInCXXConstructors
When true, suppresses printing template arguments in names of C++ constructors.
Function object that provides a total ordering on QualType values.
Definition: TypeOrdering.h:29
Allows QualTypes to be sorted and hence used in maps and sets.
QualType getCXXNameType() const
If this name is one of the C++ names (of a constructor, destructor, or conversion function)...
Defines the clang::LangOptions interface.
Contains extra information for the name of a C++ deduction guide.
static void printCXXConstructorDestructorName(QualType ClassType, raw_ostream &OS, PrintingPolicy Policy)
std::string getAsString() const
Retrieve the human-readable string for this name.
Defines an enumeration for C++ overloaded operators.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
Defines the clang::TypeLoc interface and its subclasses.
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn&#39;t...
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
void print(llvm::raw_ostream &OS) const
Prints the full selector name (e.g. "foo:bar:").
unsigned getNumArgs() const
The result type of a method or function.
bool isNull() const
Return true if this QualType doesn&#39;t point to a type yet.
Definition: Type.h:703
Kind
Encodes a location in the source.
DeclarationNameTable(const ASTContext &C)
unsigned SuppressScope
Suppresses printing of scope specifiers.
CXXSpecialNameExtra records the type associated with one of the "special" kinds of declaration names ...
DeclarationName getCXXSpecialName(DeclarationName::NameKind Kind, CanQualType Ty)
Returns a declaration name for special kind of C++ name, e.g., for a constructor, destructor...
void printName(raw_ostream &OS) const
printName - Print the human-readable name to a stream.
The injected class name of a C++ class template or class template partial specialization.
Definition: Type.h:4982
StringRef getName() const
Return the actual identifier string.
Dataflow Directional Tag Classes.
std::string getAsString() const
getAsString - Retrieve the human-readable string for this name.
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:399
The name of a declaration.
void adjustForCPlusPlus()
Adjust this printing policy for cases where it&#39;s known that we&#39;re printing C++ code (for instance...
Definition: PrettyPrinter.h:60
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:4374
void * getAsOpaquePtr() const
Retrieve the internal representation of this canonical type.
DeclarationName getCXXLiteralOperatorName(IdentifierInfo *II)
Get the name of the literal operator function with II as the identifier.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
TemplateDecl * getCXXDeductionGuideTemplate() const
If this name is the name of a C++ deduction guide, return the template associated with that name...
Defines the clang::SourceLocation class and associated facilities.
static int compare(DeclarationName LHS, DeclarationName RHS)
void print(raw_ostream &OS, const PrintingPolicy &Policy)
Contains the actual identifier that makes up the name of a C++ literal operator.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2083
__DEVICE__ int min(int __a, int __b)
IdentifierInfo * getCXXLiteralIdentifier() const
If this name is the name of a literal operator, retrieve the identifier associated with it...