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()) {
54  if (!LII) return RII ? -1 : 0;
55  if (!RII) return 1;
56 
57  return LII->getName().compare(RII->getName());
58  }
59 
63  Selector LHSSelector = LHS.getObjCSelector();
64  Selector RHSSelector = RHS.getObjCSelector();
65  // getNumArgs for ZeroArgSelector returns 0, but we still need to compare.
68  return LHSSelector.getAsIdentifierInfo()->getName().compare(
69  RHSSelector.getAsIdentifierInfo()->getName());
70  }
71  unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
72  for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
73  switch (LHSSelector.getNameForSlot(I).compare(
74  RHSSelector.getNameForSlot(I))) {
75  case -1: return -1;
76  case 1: return 1;
77  default: break;
78  }
79  }
80 
81  return compareInt(LN, RN);
82  }
83 
88  return -1;
90  return 1;
91  return 0;
92 
94  // We never want to compare deduction guide names for templates from
95  // different scopes, so just compare the template-name.
98 
102 
104  return LHS.getCXXLiteralIdentifier()->getName().compare(
106 
108  return 0;
109  }
110 
111  llvm_unreachable("Invalid DeclarationName Kind!");
112 }
113 
115  raw_ostream &OS,
116  PrintingPolicy Policy) {
117  // We know we're printing C++ here. Ensure we print types properly.
118  Policy.adjustForCPlusPlus();
119 
120  if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) {
121  OS << *ClassRec->getDecl();
122  return;
123  }
125  if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) {
126  OS << *InjTy->getDecl();
127  return;
128  }
129  }
130  ClassType.print(OS, Policy);
131 }
132 
133 void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) {
134  DeclarationName &N = *this;
135  switch (N.getNameKind()) {
137  if (const IdentifierInfo *II = N.getAsIdentifierInfo())
138  OS << II->getName();
139  return;
140 
144  N.getObjCSelector().print(OS);
145  return;
146 
148  return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy);
149 
151  OS << '~';
152  return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy);
153 
155  OS << "<deduction guide for ";
157  OS << '>';
158  return;
159 
160  case DeclarationName::CXXOperatorName: {
161  static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
162  nullptr,
163 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
164  Spelling,
165 #include "clang/Basic/OperatorKinds.def"
166  };
167  const char *OpName = OperatorNames[N.getCXXOverloadedOperator()];
168  assert(OpName && "not an overloaded operator");
169 
170  OS << "operator";
171  if (OpName[0] >= 'a' && OpName[0] <= 'z')
172  OS << ' ';
173  OS << OpName;
174  return;
175  }
176 
177  case DeclarationName::CXXLiteralOperatorName:
178  OS << "operator\"\"" << N.getCXXLiteralIdentifier()->getName();
179  return;
180 
181  case DeclarationName::CXXConversionFunctionName: {
182  OS << "operator ";
183  QualType Type = N.getCXXNameType();
184  if (const RecordType *Rec = Type->getAs<RecordType>()) {
185  OS << *Rec->getDecl();
186  return;
187  }
188  // We know we're printing C++ here, ensure we print 'bool' properly.
189  PrintingPolicy CXXPolicy = Policy;
190  CXXPolicy.adjustForCPlusPlus();
191  Type.print(OS, CXXPolicy);
192  return;
193  }
195  OS << "<using-directive>";
196  return;
197  }
198 
199  llvm_unreachable("Unexpected declaration name kind");
200 }
201 
202 namespace clang {
203 
204 raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
205  LangOptions LO;
206  N.print(OS, PrintingPolicy(LO));
207  return OS;
208 }
209 
210 } // namespace clang
211 
213  switch (getStoredNameKind()) {
214  case StoredIdentifier: return Identifier;
215  case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
216  case StoredObjCOneArgSelector: return ObjCOneArgSelector;
217 
218  case StoredDeclarationNameExtra:
219  switch (getExtra()->ExtraKindOrNumArgs) {
221  return CXXConstructorName;
222 
224  return CXXDestructorName;
225 
227  return CXXDeductionGuideName;
228 
231 
233  return CXXLiteralOperatorName;
234 
236  return CXXUsingDirective;
237 
238  default:
239  // Check if we have one of the CXXOperator* enumeration values.
240  if (getExtra()->ExtraKindOrNumArgs <
242  return CXXOperatorName;
243 
244  return ObjCMultiArgSelector;
245  }
246  }
247 
248  // Can't actually get here.
249  llvm_unreachable("This should be unreachable!");
250 }
251 
253  QualType T = getCXXNameType();
254  if (!T.isNull() && T->isDependentType())
255  return true;
256 
257  // A class-scope deduction guide in a dependent context has a dependent name.
258  auto *TD = getCXXDeductionGuideTemplate();
259  if (TD && TD->getDeclContext()->isDependentContext())
260  return true;
261 
262  return false;
263 }
264 
265 std::string DeclarationName::getAsString() const {
266  std::string Result;
267  llvm::raw_string_ostream OS(Result);
268  OS << *this;
269  return OS.str();
270 }
271 
273  if (CXXSpecialName *CXXName = getAsCXXSpecialName())
274  return CXXName->Type;
275  else
276  return QualType();
277 }
278 
280  if (auto *Guide = getAsCXXDeductionGuideNameExtra())
281  return Guide->Template;
282  return nullptr;
283 }
284 
286  if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
287  unsigned value
288  = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
289  return static_cast<OverloadedOperatorKind>(value);
290  } else {
291  return OO_None;
292  }
293 }
294 
296  if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
297  return CXXLit->ID;
298  else
299  return nullptr;
300 }
301 
302 void *DeclarationName::getFETokenInfoAsVoidSlow() const {
303  switch (getNameKind()) {
304  case Identifier:
305  llvm_unreachable("Handled by getFETokenInfo()");
306 
307  case CXXConstructorName:
308  case CXXDestructorName:
310  return getAsCXXSpecialName()->FETokenInfo;
311 
313  return getAsCXXDeductionGuideNameExtra()->FETokenInfo;
314 
315  case CXXOperatorName:
316  return getAsCXXOperatorIdName()->FETokenInfo;
317 
319  return getAsCXXLiteralOperatorIdName()->FETokenInfo;
320 
321  default:
322  llvm_unreachable("Declaration name has no FETokenInfo");
323  }
324 }
325 
327  switch (getNameKind()) {
328  case Identifier:
330  break;
331 
332  case CXXConstructorName:
333  case CXXDestructorName:
335  getAsCXXSpecialName()->FETokenInfo = T;
336  break;
337 
339  getAsCXXDeductionGuideNameExtra()->FETokenInfo = T;
340  break;
341 
342  case CXXOperatorName:
343  getAsCXXOperatorIdName()->FETokenInfo = T;
344  break;
345 
347  getAsCXXLiteralOperatorIdName()->FETokenInfo = T;
348  break;
349 
350  default:
351  llvm_unreachable("Declaration name has no FETokenInfo");
352  }
353 }
354 
356  // Single instance of DeclarationNameExtra for using-directive
357  static const DeclarationNameExtra UDirExtra =
359 
360  uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
361  Ptr |= StoredDeclarationNameExtra;
362 
363  return DeclarationName(Ptr);
364 }
365 
366 LLVM_DUMP_METHOD void DeclarationName::dump() const {
367  llvm::errs() << *this << '\n';
368 }
369 
371  // Initialize the overloaded operator names.
372  CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
373  for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
374  CXXOperatorNames[Op].ExtraKindOrNumArgs
376  CXXOperatorNames[Op].FETokenInfo = nullptr;
377  }
378 }
379 
382  Ty.getUnqualifiedType());
383 }
384 
387  Ty.getUnqualifiedType());
388 }
389 
392  Template = cast<TemplateDecl>(Template->getCanonicalDecl());
393 
394  llvm::FoldingSetNodeID ID;
395  ID.AddPointer(Template);
396 
397  void *InsertPos = nullptr;
398  if (auto *Name = CXXDeductionGuideNames.FindNodeOrInsertPos(ID, InsertPos))
399  return DeclarationName(Name);
400 
401  auto *Name = new (Ctx) CXXDeductionGuideNameExtra;
402  Name->ExtraKindOrNumArgs = DeclarationNameExtra::CXXDeductionGuide;
403  Name->Template = Template;
404  Name->FETokenInfo = nullptr;
405 
406  CXXDeductionGuideNames.InsertNode(Name, InsertPos);
407  return DeclarationName(Name);
408 }
409 
413 }
414 
417  CanQualType Ty) {
418  assert(Kind >= DeclarationName::CXXConstructorName &&
420  "Kind must be a C++ special name kind");
421 
423  switch (Kind) {
426  assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
427  break;
430  assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
431  break;
434  break;
435  default:
436  return DeclarationName();
437  }
438 
439  // Unique selector, to guarantee there is one per name.
440  llvm::FoldingSetNodeID ID;
441  ID.AddInteger(EKind);
442  ID.AddPointer(Ty.getAsOpaquePtr());
443 
444  void *InsertPos = nullptr;
445  if (CXXSpecialName *Name = CXXSpecialNames.FindNodeOrInsertPos(ID, InsertPos))
446  return DeclarationName(Name);
447 
448  CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
449  SpecialName->ExtraKindOrNumArgs = EKind;
450  SpecialName->Type = Ty;
451  SpecialName->FETokenInfo = nullptr;
452 
453  CXXSpecialNames.InsertNode(SpecialName, InsertPos);
454  return DeclarationName(SpecialName);
455 }
456 
459  return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
460 }
461 
464  llvm::FoldingSetNodeID ID;
465  ID.AddPointer(II);
466 
467  void *InsertPos = nullptr;
468  if (CXXLiteralOperatorIdName *Name =
469  CXXLiteralOperatorNames.FindNodeOrInsertPos(ID, InsertPos))
470  return DeclarationName (Name);
471 
472  CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
474  LiteralName->ID = II;
475  LiteralName->FETokenInfo = nullptr;
476 
477  CXXLiteralOperatorNames.InsertNode(LiteralName, InsertPos);
478  return DeclarationName(LiteralName);
479 }
480 
482  switch (Name.getNameKind()) {
485  break;
489  NamedType.TInfo = nullptr;
490  break;
492  CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
493  CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
494  break;
496  CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
497  break;
501  // FIXME: ?
502  break;
504  break;
505  }
506 }
507 
509  switch (Name.getNameKind()) {
518  return false;
519 
523  if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
524  return TInfo->getType()->containsUnexpandedParameterPack();
525 
526  return Name.getCXXNameType()->containsUnexpandedParameterPack();
527  }
528  llvm_unreachable("All name kinds handled.");
529 }
530 
532  switch (Name.getNameKind()) {
541  return false;
542 
546  if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
547  return TInfo->getType()->isInstantiationDependentType();
548 
549  return Name.getCXXNameType()->isInstantiationDependentType();
550  }
551  llvm_unreachable("All name kinds handled.");
552 }
553 
554 std::string DeclarationNameInfo::getAsString() const {
555  std::string Result;
556  llvm::raw_string_ostream OS(Result);
557  printName(OS);
558  return OS.str();
559 }
560 
561 void DeclarationNameInfo::printName(raw_ostream &OS) const {
562  switch (Name.getNameKind()) {
571  OS << Name;
572  return;
573 
577  if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
578  if (Name.getNameKind() == DeclarationName::CXXDestructorName)
579  OS << '~';
580  else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
581  OS << "operator ";
582  LangOptions LO;
583  LO.CPlusPlus = true;
584  LO.Bool = true;
585  PrintingPolicy PP(LO);
586  PP.SuppressScope = true;
587  OS << TInfo->getType().getAsString(PP);
588  } else
589  OS << Name;
590  return;
591  }
592  llvm_unreachable("Unexpected declaration name kind");
593 }
594 
595 SourceLocation DeclarationNameInfo::getEndLocPrivate() const {
596  switch (Name.getNameKind()) {
599  return NameLoc;
600 
602  unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
604  }
605 
607  unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
609  }
610 
614  if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
615  return TInfo->getTypeLoc().getEndLoc();
616  else
617  return NameLoc;
618 
619  // DNInfo work in progress: FIXME.
624  return NameLoc;
625  }
626  llvm_unreachable("Unexpected declaration name kind");
627 }
Defines the clang::ASTContext interface.
Smart pointer class that efficiently represents Objective-C method names.
CXXSpecialName - Records the type associated with one of the "special" kinds of declaration names in ...
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:642
NameKind
NameKind - The kind of name this object contains.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Definition: Type.h:985
QualType Type
Type - The type associated with this declaration name.
DeclarationName getCXXConstructorName(CanQualType Ty)
getCXXConstructorName - Returns the name of a C++ constructor for the given Type. ...
C Language Family Type Representation.
DeclarationName getCXXConversionFunctionName(CanQualType Ty)
getCXXConversionFunctionName - Returns the name of a C++ conversion function for the given Type...
Selector getObjCSelector() const
getObjCSelector - Get the Objective-C selector stored in this declaration name.
Defines the C++ template declaration subclasses.
const DiagnosticBuilder & operator<<(const DiagnosticBuilder &DB, const Attr *At)
Definition: Attr.h:335
The base class of the type hierarchy.
Definition: Type.h:1415
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.
QualType getCXXNameType() const
getCXXNameType - If this name is one of the C++ names (of a constructor, destructor, or conversion function), return the type associated with that name.
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6590
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:38
CXXOperatorIdName - Contains extra information for the name of an overloaded operator in C++...
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.
DeclarationName getCXXDestructorName(CanQualType Ty)
getCXXDestructorName - 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
TemplateDecl * getCXXDeductionGuideTemplate() const
If this name is the name of a C++ deduction guide, return the template associated with that name...
bool isDependentName() const
Determines whether the name itself is dependent, e.g., because it involves a C++ type that is itself ...
DeclarationNameExtra - Common base of the MultiKeywordSelector, CXXSpecialName, and CXXOperatorIdName...
Type(TypeClass tc, QualType canon, bool Dependent, bool InstantiationDependent, bool VariablyModified, bool ContainsUnexpandedParameterPack)
Definition: Type.h:1755
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.
NameKind getNameKind() const
getNameKind - Determine what kind of name this is.
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:875
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
unsigned ExtraKindOrNumArgs
ExtraKindOrNumArgs - Either the kind of C++ special name or operator-id (if the value is one of the C...
OverloadedOperatorKind getCXXOverloadedOperator() const
getCXXOverloadedOperator - If this name is the name of an overloadable operator in C++ (e...
Allows QualTypes to be sorted and hence used in maps and sets.
Defines the clang::LangOptions interface.
Contains extra information for the name of a C++ deduction guide.
bool hasQualifiers() const
Determines whether this type has any qualifiers.
void setFETokenInfo(void *T)
static void printCXXConstructorDestructorName(QualType ClassType, raw_ostream &OS, PrintingPolicy Policy)
std::string getAsString() const
getNameAsString - 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
getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in this declaration name, or NULL if this declaration name isn&#39;t a simple identifier.
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:707
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
Definition: opencl-c.h:82
void * FETokenInfo
FETokenInfo - Extra information associated with this operator name that can be used by the front end...
IdentifierInfo * getCXXLiteralIdentifier() const
getCXXLiteralIdentifier - If this name is the name of a literal operator, retrieve the identifier ass...
ExtraKind
ExtraKind - The kind of "extra" information stored in the DeclarationName.
Kind
Encodes a location in the source.
DeclarationNameTable(const ASTContext &C)
unsigned SuppressScope
Suppresses printing of scope specifiers.
void * FETokenInfo
FETokenInfo - Extra information associated with this operator name that can be used by the front end...
DeclarationName getCXXSpecialName(DeclarationName::NameKind Kind, CanQualType Ty)
getCXXSpecialName - Returns a declaration name for special kind of C++ name, e.g., for a constructor, destructor, or conversion function.
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:4859
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
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:22
DeclarationName - 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:61
Not an overloaded operator.
Definition: OperatorKinds.h:23
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:4253
void * getAsOpaquePtr() const
Retrieve the internal representation of this canonical type.
CXXLiteralOperatorName - Contains the actual identifier that makes up the name.
DeclarationName getCXXLiteralOperatorName(IdentifierInfo *II)
getCXXLiteralOperatorName - 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).
Defines the clang::SourceLocation class and associated facilities.
static int compare(DeclarationName LHS, DeclarationName RHS)
void print(raw_ostream &OS, const PrintingPolicy &Policy)
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2056
DeclarationName()=default
DeclarationName - Used to create an empty selector.
__DEVICE__ int min(int __a, int __b)
void * FETokenInfo
FETokenInfo - Extra information associated with this declaration name that can be used by the front e...
static DeclarationName getUsingDirectiveName()
getUsingDirectiveName - Return name for all using-directives.
DeclarationName getCXXOperatorName(OverloadedOperatorKind Op)
getCXXOperatorName - Get the name of the overloadable C++ operator corresponding to Op...