clang  9.0.0svn
DeclarationName.cpp
Go to the documentation of this file.
1 //===- DeclarationName.cpp - Declaration names implementation -------------===//
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 implements the DeclarationName and DeclarationNameTable
10 // classes.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/Decl.h"
17 #include "clang/AST/DeclBase.h"
18 #include "clang/AST/DeclCXX.h"
19 #include "clang/AST/DeclTemplate.h"
21 #include "clang/AST/Type.h"
22 #include "clang/AST/TypeLoc.h"
23 #include "clang/AST/TypeOrdering.h"
25 #include "clang/Basic/LLVM.h"
29 #include "llvm/ADT/FoldingSet.h"
30 #include "llvm/Support/Casting.h"
31 #include "llvm/Support/Compiler.h"
32 #include "llvm/Support/ErrorHandling.h"
33 #include "llvm/Support/raw_ostream.h"
34 #include <algorithm>
35 #include <cassert>
36 #include <cstdint>
37 #include <string>
38 
39 using namespace clang;
40 
41 static int compareInt(unsigned A, unsigned B) {
42  return (A < B ? -1 : (A > B ? 1 : 0));
43 }
44 
46  if (LHS.getNameKind() != RHS.getNameKind())
47  return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
48 
49  switch (LHS.getNameKind()) {
51  IdentifierInfo *LII = LHS.castAsIdentifierInfo();
52  IdentifierInfo *RII = RHS.castAsIdentifierInfo();
53  if (!LII)
54  return RII ? -1 : 0;
55  if (!RII)
56  return 1;
57 
58  return LII->getName().compare(RII->getName());
59  }
60 
64  Selector LHSSelector = LHS.getObjCSelector();
65  Selector RHSSelector = RHS.getObjCSelector();
66  // getNumArgs for ZeroArgSelector returns 0, but we still need to compare.
69  return LHSSelector.getAsIdentifierInfo()->getName().compare(
70  RHSSelector.getAsIdentifierInfo()->getName());
71  }
72  unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
73  for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
74  switch (LHSSelector.getNameForSlot(I).compare(
75  RHSSelector.getNameForSlot(I))) {
76  case -1:
77  return -1;
78  case 1:
79  return 1;
80  default:
81  break;
82  }
83  }
84 
85  return compareInt(LN, RN);
86  }
87 
92  return -1;
94  return 1;
95  return 0;
96 
98  // We never want to compare deduction guide names for templates from
99  // different scopes, so just compare the template-name.
102 
106 
108  return LHS.getCXXLiteralIdentifier()->getName().compare(
110 
112  return 0;
113  }
114 
115  llvm_unreachable("Invalid DeclarationName Kind!");
116 }
117 
119  raw_ostream &OS,
120  PrintingPolicy Policy) {
121  // We know we're printing C++ here. Ensure we print types properly.
122  Policy.adjustForCPlusPlus();
123 
124  if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) {
125  OS << *ClassRec->getDecl();
126  return;
127  }
129  if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) {
130  OS << *InjTy->getDecl();
131  return;
132  }
133  }
134  ClassType.print(OS, Policy);
135 }
136 
137 void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) {
138  switch (getNameKind()) {
140  if (const IdentifierInfo *II = getAsIdentifierInfo())
141  OS << II->getName();
142  return;
143 
147  getObjCSelector().print(OS);
148  return;
149 
152 
154  OS << '~';
156 
158  OS << "<deduction guide for ";
160  OS << '>';
161  return;
162 
163  case DeclarationName::CXXOperatorName: {
164  static const char *const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
165  nullptr,
166 #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
167  Spelling,
168 #include "clang/Basic/OperatorKinds.def"
169  };
170  const char *OpName = OperatorNames[getCXXOverloadedOperator()];
171  assert(OpName && "not an overloaded operator");
172 
173  OS << "operator";
174  if (OpName[0] >= 'a' && OpName[0] <= 'z')
175  OS << ' ';
176  OS << OpName;
177  return;
178  }
179 
180  case DeclarationName::CXXLiteralOperatorName:
181  OS << "operator\"\"" << getCXXLiteralIdentifier()->getName();
182  return;
183 
184  case DeclarationName::CXXConversionFunctionName: {
185  OS << "operator ";
186  QualType Type = getCXXNameType();
187  if (const RecordType *Rec = Type->getAs<RecordType>()) {
188  OS << *Rec->getDecl();
189  return;
190  }
191  // We know we're printing C++ here, ensure we print 'bool' properly.
192  PrintingPolicy CXXPolicy = Policy;
193  CXXPolicy.adjustForCPlusPlus();
194  Type.print(OS, CXXPolicy);
195  return;
196  }
198  OS << "<using-directive>";
199  return;
200  }
201 
202  llvm_unreachable("Unexpected declaration name kind");
203 }
204 
205 namespace clang {
206 
207 raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
208  LangOptions LO;
209  N.print(OS, PrintingPolicy(LO));
210  return OS;
211 }
212 
213 } // namespace clang
214 
216  QualType T = getCXXNameType();
217  if (!T.isNull() && T->isDependentType())
218  return true;
219 
220  // A class-scope deduction guide in a dependent context has a dependent name.
221  auto *TD = getCXXDeductionGuideTemplate();
222  if (TD && TD->getDeclContext()->isDependentContext())
223  return true;
224 
225  return false;
226 }
227 
228 std::string DeclarationName::getAsString() const {
229  std::string Result;
230  llvm::raw_string_ostream OS(Result);
231  OS << *this;
232  return OS.str();
233 }
234 
235 void *DeclarationName::getFETokenInfoSlow() const {
236  switch (getNameKind()) {
237  case Identifier:
238  llvm_unreachable("case Identifier already handled by getFETokenInfo!");
239  case CXXConstructorName:
240  case CXXDestructorName:
242  return castAsCXXSpecialNameExtra()->FETokenInfo;
243  case CXXOperatorName:
244  return castAsCXXOperatorIdName()->FETokenInfo;
246  return castAsCXXDeductionGuideNameExtra()->FETokenInfo;
248  return castAsCXXLiteralOperatorIdName()->FETokenInfo;
249  default:
250  llvm_unreachable("DeclarationName has no FETokenInfo!");
251  }
252 }
253 
254 void DeclarationName::setFETokenInfoSlow(void *T) {
255  switch (getNameKind()) {
256  case Identifier:
257  llvm_unreachable("case Identifier already handled by setFETokenInfo!");
258  case CXXConstructorName:
259  case CXXDestructorName:
261  castAsCXXSpecialNameExtra()->FETokenInfo = T;
262  break;
263  case CXXOperatorName:
264  castAsCXXOperatorIdName()->FETokenInfo = T;
265  break;
267  castAsCXXDeductionGuideNameExtra()->FETokenInfo = T;
268  break;
270  castAsCXXLiteralOperatorIdName()->FETokenInfo = T;
271  break;
272  default:
273  llvm_unreachable("DeclarationName has no FETokenInfo!");
274  }
275 }
276 
277 LLVM_DUMP_METHOD void DeclarationName::dump() const {
278  llvm::errs() << *this << '\n';
279 }
280 
282  // Initialize the overloaded operator names.
283  for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op)
284  CXXOperatorNames[Op].Kind = static_cast<OverloadedOperatorKind>(Op);
285 }
286 
289  Template = cast<TemplateDecl>(Template->getCanonicalDecl());
290 
291  llvm::FoldingSetNodeID ID;
292  ID.AddPointer(Template);
293 
294  void *InsertPos = nullptr;
295  if (auto *Name = CXXDeductionGuideNames.FindNodeOrInsertPos(ID, InsertPos))
296  return DeclarationName(Name);
297 
298  auto *Name = new (Ctx) detail::CXXDeductionGuideNameExtra(Template);
299  CXXDeductionGuideNames.InsertNode(Name, InsertPos);
300  return DeclarationName(Name);
301 }
302 
304  // The type of constructors is unqualified.
305  Ty = Ty.getUnqualifiedType();
306  // Do we already have this C++ constructor name ?
307  llvm::FoldingSetNodeID ID;
308  ID.AddPointer(Ty.getAsOpaquePtr());
309  void *InsertPos = nullptr;
310  if (auto *Name = CXXConstructorNames.FindNodeOrInsertPos(ID, InsertPos))
311  return {Name, DeclarationName::StoredCXXConstructorName};
312 
313  // We have to create it.
314  auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
315  CXXConstructorNames.InsertNode(SpecialName, InsertPos);
316  return {SpecialName, DeclarationName::StoredCXXConstructorName};
317 }
318 
320  // The type of destructors is unqualified.
321  Ty = Ty.getUnqualifiedType();
322  // Do we already have this C++ destructor name ?
323  llvm::FoldingSetNodeID ID;
324  ID.AddPointer(Ty.getAsOpaquePtr());
325  void *InsertPos = nullptr;
326  if (auto *Name = CXXDestructorNames.FindNodeOrInsertPos(ID, InsertPos))
327  return {Name, DeclarationName::StoredCXXDestructorName};
328 
329  // We have to create it.
330  auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
331  CXXDestructorNames.InsertNode(SpecialName, InsertPos);
332  return {SpecialName, DeclarationName::StoredCXXDestructorName};
333 }
334 
337  // Do we already have this C++ conversion function name ?
338  llvm::FoldingSetNodeID ID;
339  ID.AddPointer(Ty.getAsOpaquePtr());
340  void *InsertPos = nullptr;
341  if (auto *Name =
342  CXXConversionFunctionNames.FindNodeOrInsertPos(ID, InsertPos))
343  return {Name, DeclarationName::StoredCXXConversionFunctionName};
344 
345  // We have to create it.
346  auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
347  CXXConversionFunctionNames.InsertNode(SpecialName, InsertPos);
348  return {SpecialName, DeclarationName::StoredCXXConversionFunctionName};
349 }
350 
353  CanQualType Ty) {
354  switch (Kind) {
356  return getCXXConstructorName(Ty);
358  return getCXXDestructorName(Ty);
360  return getCXXConversionFunctionName(Ty);
361  default:
362  llvm_unreachable("Invalid kind in getCXXSpecialName!");
363  }
364 }
365 
368  llvm::FoldingSetNodeID ID;
369  ID.AddPointer(II);
370 
371  void *InsertPos = nullptr;
372  if (auto *Name = CXXLiteralOperatorNames.FindNodeOrInsertPos(ID, InsertPos))
373  return DeclarationName(Name);
374 
375  auto *LiteralName = new (Ctx) detail::CXXLiteralOperatorIdName(II);
376  CXXLiteralOperatorNames.InsertNode(LiteralName, InsertPos);
377  return DeclarationName(LiteralName);
378 }
379 
381  switch (Name.getNameKind()) {
384  break;
388  NamedType.TInfo = nullptr;
389  break;
391  CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
392  CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
393  break;
395  CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
396  break;
400  // FIXME: ?
401  break;
403  break;
404  }
405 }
406 
408  switch (Name.getNameKind()) {
417  return false;
418 
422  if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
423  return TInfo->getType()->containsUnexpandedParameterPack();
424 
425  return Name.getCXXNameType()->containsUnexpandedParameterPack();
426  }
427  llvm_unreachable("All name kinds handled.");
428 }
429 
431  switch (Name.getNameKind()) {
440  return false;
441 
445  if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
446  return TInfo->getType()->isInstantiationDependentType();
447 
448  return Name.getCXXNameType()->isInstantiationDependentType();
449  }
450  llvm_unreachable("All name kinds handled.");
451 }
452 
453 std::string DeclarationNameInfo::getAsString() const {
454  std::string Result;
455  llvm::raw_string_ostream OS(Result);
456  printName(OS);
457  return OS.str();
458 }
459 
460 void DeclarationNameInfo::printName(raw_ostream &OS) const {
461  switch (Name.getNameKind()) {
470  OS << Name;
471  return;
472 
476  if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
477  if (Name.getNameKind() == DeclarationName::CXXDestructorName)
478  OS << '~';
479  else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
480  OS << "operator ";
481  LangOptions LO;
482  LO.CPlusPlus = true;
483  LO.Bool = true;
484  PrintingPolicy PP(LO);
485  PP.SuppressScope = true;
486  OS << TInfo->getType().getAsString(PP);
487  } else
488  OS << Name;
489  return;
490  }
491  llvm_unreachable("Unexpected declaration name kind");
492 }
493 
494 SourceLocation DeclarationNameInfo::getEndLocPrivate() const {
495  switch (Name.getNameKind()) {
498  return NameLoc;
499 
501  unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
503  }
504 
506  unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
508  }
509 
513  if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
514  return TInfo->getTypeLoc().getEndLoc();
515  else
516  return NameLoc;
517 
518  // DNInfo work in progress: FIXME.
523  return NameLoc;
524  }
525  llvm_unreachable("Unexpected declaration name kind");
526 }
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:634
NameKind
The kind of the name stored in this DeclarationName.
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:1409
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:6761
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:37
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:49
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...
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
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:872
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:28
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:699
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:4983
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:398
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:59
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:4375
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:2081
__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...