clang  11.0.0git
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"
20 #include "clang/AST/OpenMPClause.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,
139  const PrintingPolicy &Policy) const {
140  switch (getNameKind()) {
142  if (const IdentifierInfo *II = getAsIdentifierInfo()) {
143  StringRef Name = II->getName();
144  // If this is a mangled OpenMP variant name we strip off the mangling for
145  // printing. It should not be visible to the user at all.
146  if (II->isMangledOpenMPVariantName()) {
147  std::pair<StringRef, StringRef> NameContextPair =
149  OS << NameContextPair.first << "["
150  << OMPTraitInfo(NameContextPair.second) << "]";
151  } else {
152  OS << Name;
153  }
154  }
155  return;
156 
160  getObjCSelector().print(OS);
161  return;
162 
165 
167  OS << '~';
169 
171  OS << "<deduction guide for ";
173  OS << '>';
174  return;
175 
176  case DeclarationName::CXXOperatorName: {
177  const char *OpName = getOperatorSpelling(getCXXOverloadedOperator());
178  assert(OpName && "not an overloaded operator");
179 
180  OS << "operator";
181  if (OpName[0] >= 'a' && OpName[0] <= 'z')
182  OS << ' ';
183  OS << OpName;
184  return;
185  }
186 
187  case DeclarationName::CXXLiteralOperatorName:
188  OS << "operator\"\"" << getCXXLiteralIdentifier()->getName();
189  return;
190 
191  case DeclarationName::CXXConversionFunctionName: {
192  OS << "operator ";
193  QualType Type = getCXXNameType();
194  if (const RecordType *Rec = Type->getAs<RecordType>()) {
195  OS << *Rec->getDecl();
196  return;
197  }
198  // We know we're printing C++ here, ensure we print 'bool' properly.
199  PrintingPolicy CXXPolicy = Policy;
200  CXXPolicy.adjustForCPlusPlus();
201  Type.print(OS, CXXPolicy);
202  return;
203  }
205  OS << "<using-directive>";
206  return;
207  }
208 
209  llvm_unreachable("Unexpected declaration name kind");
210 }
211 
212 namespace clang {
213 
214 raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
215  LangOptions LO;
216  N.print(OS, PrintingPolicy(LO));
217  return OS;
218 }
219 
220 } // namespace clang
221 
223  QualType T = getCXXNameType();
224  if (!T.isNull() && T->isDependentType())
225  return true;
226 
227  // A class-scope deduction guide in a dependent context has a dependent name.
228  auto *TD = getCXXDeductionGuideTemplate();
229  if (TD && TD->getDeclContext()->isDependentContext())
230  return true;
231 
232  return false;
233 }
234 
235 std::string DeclarationName::getAsString() const {
236  std::string Result;
237  llvm::raw_string_ostream OS(Result);
238  OS << *this;
239  return OS.str();
240 }
241 
242 void *DeclarationName::getFETokenInfoSlow() const {
243  switch (getNameKind()) {
244  case Identifier:
245  llvm_unreachable("case Identifier already handled by getFETokenInfo!");
246  case CXXConstructorName:
247  case CXXDestructorName:
249  return castAsCXXSpecialNameExtra()->FETokenInfo;
250  case CXXOperatorName:
251  return castAsCXXOperatorIdName()->FETokenInfo;
253  return castAsCXXDeductionGuideNameExtra()->FETokenInfo;
255  return castAsCXXLiteralOperatorIdName()->FETokenInfo;
256  default:
257  llvm_unreachable("DeclarationName has no FETokenInfo!");
258  }
259 }
260 
261 void DeclarationName::setFETokenInfoSlow(void *T) {
262  switch (getNameKind()) {
263  case Identifier:
264  llvm_unreachable("case Identifier already handled by setFETokenInfo!");
265  case CXXConstructorName:
266  case CXXDestructorName:
268  castAsCXXSpecialNameExtra()->FETokenInfo = T;
269  break;
270  case CXXOperatorName:
271  castAsCXXOperatorIdName()->FETokenInfo = T;
272  break;
274  castAsCXXDeductionGuideNameExtra()->FETokenInfo = T;
275  break;
277  castAsCXXLiteralOperatorIdName()->FETokenInfo = T;
278  break;
279  default:
280  llvm_unreachable("DeclarationName has no FETokenInfo!");
281  }
282 }
283 
284 LLVM_DUMP_METHOD void DeclarationName::dump() const {
285  llvm::errs() << *this << '\n';
286 }
287 
289  // Initialize the overloaded operator names.
290  for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op)
291  CXXOperatorNames[Op].Kind = static_cast<OverloadedOperatorKind>(Op);
292 }
293 
296  Template = cast<TemplateDecl>(Template->getCanonicalDecl());
297 
298  llvm::FoldingSetNodeID ID;
299  ID.AddPointer(Template);
300 
301  void *InsertPos = nullptr;
302  if (auto *Name = CXXDeductionGuideNames.FindNodeOrInsertPos(ID, InsertPos))
303  return DeclarationName(Name);
304 
305  auto *Name = new (Ctx) detail::CXXDeductionGuideNameExtra(Template);
306  CXXDeductionGuideNames.InsertNode(Name, InsertPos);
307  return DeclarationName(Name);
308 }
309 
311  // The type of constructors is unqualified.
312  Ty = Ty.getUnqualifiedType();
313  // Do we already have this C++ constructor name ?
314  llvm::FoldingSetNodeID ID;
315  ID.AddPointer(Ty.getAsOpaquePtr());
316  void *InsertPos = nullptr;
317  if (auto *Name = CXXConstructorNames.FindNodeOrInsertPos(ID, InsertPos))
318  return {Name, DeclarationName::StoredCXXConstructorName};
319 
320  // We have to create it.
321  auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
322  CXXConstructorNames.InsertNode(SpecialName, InsertPos);
323  return {SpecialName, DeclarationName::StoredCXXConstructorName};
324 }
325 
327  // The type of destructors is unqualified.
328  Ty = Ty.getUnqualifiedType();
329  // Do we already have this C++ destructor name ?
330  llvm::FoldingSetNodeID ID;
331  ID.AddPointer(Ty.getAsOpaquePtr());
332  void *InsertPos = nullptr;
333  if (auto *Name = CXXDestructorNames.FindNodeOrInsertPos(ID, InsertPos))
334  return {Name, DeclarationName::StoredCXXDestructorName};
335 
336  // We have to create it.
337  auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
338  CXXDestructorNames.InsertNode(SpecialName, InsertPos);
339  return {SpecialName, DeclarationName::StoredCXXDestructorName};
340 }
341 
344  // Do we already have this C++ conversion function name ?
345  llvm::FoldingSetNodeID ID;
346  ID.AddPointer(Ty.getAsOpaquePtr());
347  void *InsertPos = nullptr;
348  if (auto *Name =
349  CXXConversionFunctionNames.FindNodeOrInsertPos(ID, InsertPos))
350  return {Name, DeclarationName::StoredCXXConversionFunctionName};
351 
352  // We have to create it.
353  auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
354  CXXConversionFunctionNames.InsertNode(SpecialName, InsertPos);
355  return {SpecialName, DeclarationName::StoredCXXConversionFunctionName};
356 }
357 
360  CanQualType Ty) {
361  switch (Kind) {
363  return getCXXConstructorName(Ty);
365  return getCXXDestructorName(Ty);
367  return getCXXConversionFunctionName(Ty);
368  default:
369  llvm_unreachable("Invalid kind in getCXXSpecialName!");
370  }
371 }
372 
375  llvm::FoldingSetNodeID ID;
376  ID.AddPointer(II);
377 
378  void *InsertPos = nullptr;
379  if (auto *Name = CXXLiteralOperatorNames.FindNodeOrInsertPos(ID, InsertPos))
380  return DeclarationName(Name);
381 
382  auto *LiteralName = new (Ctx) detail::CXXLiteralOperatorIdName(II);
383  CXXLiteralOperatorNames.InsertNode(LiteralName, InsertPos);
384  return DeclarationName(LiteralName);
385 }
386 
388  switch (Name.getNameKind()) {
391  break;
395  NamedType.TInfo = nullptr;
396  break;
398  CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
399  CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
400  break;
402  CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
403  break;
407  // FIXME: ?
408  break;
410  break;
411  }
412 }
413 
415  switch (Name.getNameKind()) {
424  return false;
425 
429  if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
430  return TInfo->getType()->containsUnexpandedParameterPack();
431 
432  return Name.getCXXNameType()->containsUnexpandedParameterPack();
433  }
434  llvm_unreachable("All name kinds handled.");
435 }
436 
438  switch (Name.getNameKind()) {
447  return false;
448 
452  if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
453  return TInfo->getType()->isInstantiationDependentType();
454 
455  return Name.getCXXNameType()->isInstantiationDependentType();
456  }
457  llvm_unreachable("All name kinds handled.");
458 }
459 
460 std::string DeclarationNameInfo::getAsString() const {
461  std::string Result;
462  llvm::raw_string_ostream OS(Result);
463  OS << *this;
464  return OS.str();
465 }
466 
467 raw_ostream &clang::operator<<(raw_ostream &OS, DeclarationNameInfo DNInfo) {
468  LangOptions LO;
469  DNInfo.printName(OS, PrintingPolicy(LangOptions()));
470  return OS;
471 }
472 
473 void DeclarationNameInfo::printName(raw_ostream &OS, PrintingPolicy Policy) const {
474  switch (Name.getNameKind()) {
483  Name.print(OS, Policy);
484  return;
485 
489  if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
490  if (Name.getNameKind() == DeclarationName::CXXDestructorName)
491  OS << '~';
492  else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
493  OS << "operator ";
494  LangOptions LO;
495  Policy.adjustForCPlusPlus();
496  Policy.SuppressScope = true;
497  OS << TInfo->getType().getAsString(Policy);
498  } else
499  Name.print(OS, Policy);
500  return;
501  }
502  llvm_unreachable("Unexpected declaration name kind");
503 }
504 
505 SourceLocation DeclarationNameInfo::getEndLocPrivate() const {
506  switch (Name.getNameKind()) {
509  return NameLoc;
510 
512  unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
514  }
515 
517  unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
519  }
520 
524  if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
525  return TInfo->getTypeLoc().getEndLoc();
526  else
527  return NameLoc;
528 
529  // DNInfo work in progress: FIXME.
534  return NameLoc;
535  }
536  llvm_unreachable("Unexpected declaration name kind");
537 }
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:655
NameKind
The kind of the name stored in this DeclarationName.
void print(raw_ostream &OS, const PrintingPolicy &Policy) const
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...
The base class of the type hierarchy.
Definition: Type.h:1472
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
A container of type source information.
Definition: Type.h:6373
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:7153
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:49
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:272
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:174
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:54
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:901
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.
__DEVICE__ int min(int __a, int __b)
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:720
This file defines OpenMP AST classes for clauses.
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 ...
static constexpr StringRef getOpenMPVariantManglingSeparatorStr()
OpenMP variants are mangled early based on their OpenMP context selector.
Definition: Decl.h:4568
DeclarationName getCXXSpecialName(DeclarationName::NameKind Kind, CanQualType Ty)
Returns a declaration name for special kind of C++ name, e.g., for a constructor, destructor...
The injected class name of a C++ class template or class template partial specialization.
Definition: Type.h:5241
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.
const DiagnosticBuilder & operator<<(const DiagnosticBuilder &DB, const ASTContext::SectionInfo &Section)
Insertion operator for diagnostics.
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:402
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:72
void printName(raw_ostream &OS, PrintingPolicy Policy) const
printName - Print the human-readable name to a stream.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:4617
Helper data structure representing the traits in a match clause of an declare variant or metadirectiv...
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)
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:2185
IdentifierInfo * getCXXLiteralIdentifier() const
If this name is the name of a literal operator, retrieve the identifier associated with it...