clang  3.9.0
DeclarationName.cpp
Go to the documentation of this file.
1 //===-- DeclarationName.cpp - Declaration names implementation --*- C++ -*-===//
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 #include "clang/AST/ASTContext.h"
15 #include "clang/AST/DeclCXX.h"
17 #include "clang/AST/Type.h"
18 #include "clang/AST/TypeLoc.h"
19 #include "clang/AST/TypeOrdering.h"
21 #include "llvm/ADT/DenseMap.h"
22 #include "llvm/ADT/FoldingSet.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/raw_ostream.h"
25 using namespace clang;
26 
27 namespace clang {
28 /// CXXSpecialName - Records the type associated with one of the
29 /// "special" kinds of declaration names in C++, e.g., constructors,
30 /// destructors, and conversion functions.
32  : public DeclarationNameExtra, public llvm::FoldingSetNode {
33 public:
34  /// Type - The type associated with this declaration name.
36 
37  /// FETokenInfo - Extra information associated with this declaration
38  /// name that can be used by the front end.
39  void *FETokenInfo;
40 
41  void Profile(llvm::FoldingSetNodeID &ID) {
42  ID.AddInteger(ExtraKindOrNumArgs);
43  ID.AddPointer(Type.getAsOpaquePtr());
44  }
45 };
46 
47 /// CXXOperatorIdName - Contains extra information for the name of an
48 /// overloaded operator in C++, such as "operator+.
50 public:
51  /// FETokenInfo - Extra information associated with this operator
52  /// name that can be used by the front end.
53  void *FETokenInfo;
54 };
55 
56 /// CXXLiteralOperatorName - Contains the actual identifier that makes up the
57 /// name.
58 ///
59 /// This identifier is stored here rather than directly in DeclarationName so as
60 /// to allow Objective-C selectors, which are about a million times more common,
61 /// to consume minimal memory.
63  : public DeclarationNameExtra, public llvm::FoldingSetNode {
64 public:
66 
67  /// FETokenInfo - Extra information associated with this operator
68  /// name that can be used by the front end.
69  void *FETokenInfo;
70 
71  void Profile(llvm::FoldingSetNodeID &FSID) {
72  FSID.AddPointer(ID);
73  }
74 };
75 
76 static int compareInt(unsigned A, unsigned B) {
77  return (A < B ? -1 : (A > B ? 1 : 0));
78 }
79 
81  if (LHS.getNameKind() != RHS.getNameKind())
82  return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
83 
84  switch (LHS.getNameKind()) {
88  if (!LII) return RII ? -1 : 0;
89  if (!RII) return 1;
90 
91  return LII->getName().compare(RII->getName());
92  }
93 
97  Selector LHSSelector = LHS.getObjCSelector();
98  Selector RHSSelector = RHS.getObjCSelector();
99  unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
100  for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
101  switch (LHSSelector.getNameForSlot(I).compare(
102  RHSSelector.getNameForSlot(I))) {
103  case -1: return true;
104  case 1: return false;
105  default: break;
106  }
107  }
108 
109  return compareInt(LN, RN);
110  }
111 
115  if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
116  return -1;
117  if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
118  return 1;
119  return 0;
120 
124 
126  return LHS.getCXXLiteralIdentifier()->getName().compare(
128 
130  return 0;
131  }
132 
133  llvm_unreachable("Invalid DeclarationName Kind!");
134 }
135 
137  raw_ostream &OS,
138  PrintingPolicy Policy) {
139  // We know we're printing C++ here. Ensure we print types properly.
140  Policy.adjustForCPlusPlus();
141 
142  if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) {
143  OS << *ClassRec->getDecl();
144  return;
145  }
147  if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) {
148  OS << *InjTy->getDecl();
149  return;
150  }
151  }
152  ClassType.print(OS, Policy);
153 }
154 
155 void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) {
156  DeclarationName &N = *this;
157  switch (N.getNameKind()) {
159  if (const IdentifierInfo *II = N.getAsIdentifierInfo())
160  OS << II->getName();
161  return;
162 
166  N.getObjCSelector().print(OS);
167  return;
168 
170  return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy);
171 
173  OS << '~';
174  return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy);
175  }
176 
178  static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
179  nullptr,
180 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
181  Spelling,
182 #include "clang/Basic/OperatorKinds.def"
183  };
184  const char *OpName = OperatorNames[N.getCXXOverloadedOperator()];
185  assert(OpName && "not an overloaded operator");
186 
187  OS << "operator";
188  if (OpName[0] >= 'a' && OpName[0] <= 'z')
189  OS << ' ';
190  OS << OpName;
191  return;
192  }
193 
195  OS << "operator\"\"" << N.getCXXLiteralIdentifier()->getName();
196  return;
197 
199  OS << "operator ";
201  if (const RecordType *Rec = Type->getAs<RecordType>()) {
202  OS << *Rec->getDecl();
203  return;
204  }
205  // We know we're printing C++ here, ensure we print 'bool' properly.
206  PrintingPolicy CXXPolicy = Policy;
207  CXXPolicy.adjustForCPlusPlus();
208  Type.print(OS, CXXPolicy);
209  return;
210  }
212  OS << "<using-directive>";
213  return;
214  }
215 
216  llvm_unreachable("Unexpected declaration name kind");
217 }
218 
219 raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
220  LangOptions LO;
221  N.print(OS, PrintingPolicy(LO));
222  return OS;
223 }
224 
225 } // end namespace clang
226 
227 DeclarationName::NameKind DeclarationName::getNameKind() const {
228  switch (getStoredNameKind()) {
229  case StoredIdentifier: return Identifier;
230  case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
231  case StoredObjCOneArgSelector: return ObjCOneArgSelector;
232 
233  case StoredDeclarationNameExtra:
234  switch (getExtra()->ExtraKindOrNumArgs) {
236  return CXXConstructorName;
237 
239  return CXXDestructorName;
240 
243 
245  return CXXLiteralOperatorName;
246 
248  return CXXUsingDirective;
249 
250  default:
251  // Check if we have one of the CXXOperator* enumeration values.
252  if (getExtra()->ExtraKindOrNumArgs <
254  return CXXOperatorName;
255 
256  return ObjCMultiArgSelector;
257  }
258  }
259 
260  // Can't actually get here.
261  llvm_unreachable("This should be unreachable!");
262 }
263 
265  QualType T = getCXXNameType();
266  return !T.isNull() && T->isDependentType();
267 }
268 
269 std::string DeclarationName::getAsString() const {
270  std::string Result;
271  llvm::raw_string_ostream OS(Result);
272  OS << *this;
273  return OS.str();
274 }
275 
277  if (CXXSpecialName *CXXName = getAsCXXSpecialName())
278  return CXXName->Type;
279  else
280  return QualType();
281 }
282 
284  if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
285  unsigned value
286  = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
287  return static_cast<OverloadedOperatorKind>(value);
288  } else {
289  return OO_None;
290  }
291 }
292 
294  if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
295  return CXXLit->ID;
296  else
297  return nullptr;
298 }
299 
300 void *DeclarationName::getFETokenInfoAsVoidSlow() const {
301  switch (getNameKind()) {
302  case Identifier:
303  llvm_unreachable("Handled by getFETokenInfo()");
304 
305  case CXXConstructorName:
306  case CXXDestructorName:
308  return getAsCXXSpecialName()->FETokenInfo;
309 
310  case CXXOperatorName:
311  return getAsCXXOperatorIdName()->FETokenInfo;
312 
314  return getAsCXXLiteralOperatorIdName()->FETokenInfo;
315 
316  default:
317  llvm_unreachable("Declaration name has no FETokenInfo");
318  }
319 }
320 
322  switch (getNameKind()) {
323  case Identifier:
325  break;
326 
327  case CXXConstructorName:
328  case CXXDestructorName:
330  getAsCXXSpecialName()->FETokenInfo = T;
331  break;
332 
333  case CXXOperatorName:
334  getAsCXXOperatorIdName()->FETokenInfo = T;
335  break;
336 
338  getAsCXXLiteralOperatorIdName()->FETokenInfo = T;
339  break;
340 
341  default:
342  llvm_unreachable("Declaration name has no FETokenInfo");
343  }
344 }
345 
347  // Single instance of DeclarationNameExtra for using-directive
348  static const DeclarationNameExtra UDirExtra =
350 
351  uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
352  Ptr |= StoredDeclarationNameExtra;
353 
354  return DeclarationName(Ptr);
355 }
356 
357 LLVM_DUMP_METHOD void DeclarationName::dump() const {
358  llvm::errs() << *this << '\n';
359 }
360 
361 DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
362  CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
363  CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
364 
365  // Initialize the overloaded operator names.
366  CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
367  for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
368  CXXOperatorNames[Op].ExtraKindOrNumArgs
370  CXXOperatorNames[Op].FETokenInfo = nullptr;
371  }
372 }
373 
375  llvm::FoldingSet<CXXSpecialName> *SpecialNames =
376  static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
377  llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
378  = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
379  (CXXLiteralOperatorNames);
380 
381  delete SpecialNames;
382  delete LiteralNames;
383 }
384 
387  Ty.getUnqualifiedType());
388 }
389 
392  Ty.getUnqualifiedType());
393 }
394 
398 }
399 
402  CanQualType Ty) {
403  assert(Kind >= DeclarationName::CXXConstructorName &&
405  "Kind must be a C++ special name kind");
406  llvm::FoldingSet<CXXSpecialName> *SpecialNames
407  = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
408 
410  switch (Kind) {
413  assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
414  break;
417  assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
418  break;
421  break;
422  default:
423  return DeclarationName();
424  }
425 
426  // Unique selector, to guarantee there is one per name.
427  llvm::FoldingSetNodeID ID;
428  ID.AddInteger(EKind);
429  ID.AddPointer(Ty.getAsOpaquePtr());
430 
431  void *InsertPos = nullptr;
432  if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
433  return DeclarationName(Name);
434 
435  CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
436  SpecialName->ExtraKindOrNumArgs = EKind;
437  SpecialName->Type = Ty;
438  SpecialName->FETokenInfo = nullptr;
439 
440  SpecialNames->InsertNode(SpecialName, InsertPos);
441  return DeclarationName(SpecialName);
442 }
443 
446  return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
447 }
448 
451  llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
452  = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
453  (CXXLiteralOperatorNames);
454 
455  llvm::FoldingSetNodeID ID;
456  ID.AddPointer(II);
457 
458  void *InsertPos = nullptr;
460  LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
461  return DeclarationName (Name);
462 
463  CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
465  LiteralName->ID = II;
466  LiteralName->FETokenInfo = nullptr;
467 
468  LiteralNames->InsertNode(LiteralName, InsertPos);
469  return DeclarationName(LiteralName);
470 }
471 
473  switch (Name.getNameKind()) {
475  break;
479  NamedType.TInfo = nullptr;
480  break;
484  break;
487  break;
491  // FIXME: ?
492  break;
494  break;
495  }
496 }
497 
499  switch (Name.getNameKind()) {
507  return false;
508 
512  if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
513  return TInfo->getType()->containsUnexpandedParameterPack();
514 
516  }
517  llvm_unreachable("All name kinds handled.");
518 }
519 
521  switch (Name.getNameKind()) {
529  return false;
530 
534  if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
535  return TInfo->getType()->isInstantiationDependentType();
536 
538  }
539  llvm_unreachable("All name kinds handled.");
540 }
541 
542 std::string DeclarationNameInfo::getAsString() const {
543  std::string Result;
544  llvm::raw_string_ostream OS(Result);
545  printName(OS);
546  return OS.str();
547 }
548 
549 void DeclarationNameInfo::printName(raw_ostream &OS) const {
550  switch (Name.getNameKind()) {
558  OS << Name;
559  return;
560 
564  if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
565  if (Name.getNameKind() == DeclarationName::CXXDestructorName)
566  OS << '~';
567  else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
568  OS << "operator ";
569  LangOptions LO;
570  LO.CPlusPlus = true;
571  LO.Bool = true;
572  OS << TInfo->getType().getAsString(PrintingPolicy(LO));
573  } else
574  OS << Name;
575  return;
576  }
577  llvm_unreachable("Unexpected declaration name kind");
578 }
579 
581  switch (Name.getNameKind()) {
583  return NameLoc;
584 
586  unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
588  }
589 
591  unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
593  }
594 
598  if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
599  return TInfo->getTypeLoc().getEndLoc();
600  else
601  return NameLoc;
602 
603  // DNInfo work in progress: FIXME.
608  return NameLoc;
609  }
610  llvm_unreachable("Unexpected declaration name kind");
611 }
bool isDependentName() const
Determines whether the name itself is dependent, e.g., because it involves a C++ type that is itself ...
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 ...
A (possibly-)qualified type.
Definition: Type.h:598
NameKind
NameKind - The kind of name this object contains.
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. ...
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
Definition: Type.h:1780
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
SourceLocation getEndLoc() const
getEndLoc - Retrieve the location of the last token.
IdentifierInfo * getCXXLiteralIdentifier() const
getCXXLiteralIdentifier - If this name is the name of a literal operator, retrieve the identifier ass...
C Language Family Type Representation.
DeclarationName getCXXConversionFunctionName(CanQualType Ty)
getCXXConversionFunctionName - Returns the name of a C++ conversion function for the given Type...
const DiagnosticBuilder & operator<<(const DiagnosticBuilder &DB, const Attr *At)
Definition: Attr.h:198
IdentifierInfo * getAsIdentifierInfo() const
getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in this declaration name, or NULL if this declaration name isn't a simple identifier.
The base class of the type hierarchy.
Definition: Type.h:1281
A container of type source information.
Definition: Decl.h:62
unsigned getRawEncoding() const
When a SourceLocation itself cannot be used, this returns an (opaque) 32-bit integer encoding for it...
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:38
bool containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
Definition: Type.h:1553
CXXOperatorIdName - Contains extra information for the name of an overloaded operator in C++...
void Profile(llvm::FoldingSetNodeID &ID)
One of these records is kept for each identifier that is lexed.
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
Definition: Type.h:4549
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:92
static int compare(DeclarationName LHS, DeclarationName RHS)
static SourceLocation getFromRawEncoding(unsigned Encoding)
Turn a raw encoding of a SourceLocation object into a real SourceLocation.
static int compareInt(unsigned A, unsigned B)
void print(raw_ostream &OS, const PrintingPolicy &Policy)
DeclarationName getCXXDestructorName(CanQualType Ty)
getCXXDestructorName - Returns the name of a C++ destructor for the given Type.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:48
DeclarationNameExtra - Common base of the MultiKeywordSelector, CXXSpecialName, and CXXOperatorIdName...
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Definition: Type.h:934
std::string getAsString() const
getNameAsString - Retrieve the human-readable string for this name.
void print(llvm::raw_ostream &OS) const
Prints the full selector name (e.g. "foo:bar:").
detail::InMemoryDirectory::const_iterator I
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...
NameKind getNameKind() const
getNameKind - Determine what kind of name this is.
Allows QualTypes to be sorted and hence used in maps and sets.
void * getAsOpaquePtr() const
Retrieve the internal representation of this canonical type.
StringRef getName() const
Return the actual identifier string.
void Profile(llvm::FoldingSetNodeID &FSID)
unsigned getNumArgs() const
void setFETokenInfo(void *T)
char __ovld __cnfn min(char x, char y)
Returns y if y < x, otherwise it returns x.
Defines the clang::TypeLoc interface and its subclasses.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:1774
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.
struct CXXOpName CXXOperatorName
The result type of a method or function.
__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:75
void * FETokenInfo
FETokenInfo - Extra information associated with this operator name that can be used by the front end...
ExtraKind
ExtraKind - The kind of "extra" information stored in the DeclarationName.
Kind
Encodes a location in the source.
OverloadedOperatorKind getCXXOverloadedOperator() const
getCXXOverloadedOperator - If this name is the name of an overloadable operator in C++ (e...
const std::string ID
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
std::string getAsString() const
getAsString - Retrieve the human-readable string for this name.
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.
The injected class name of a C++ class template or class template partial specialization.
Definition: Type.h:4294
Selector getObjCSelector() const
getObjCSelector - Get the Objective-C selector stored in this declaration name.
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's known that we're printing C++ code (for instance...
Definition: PrettyPrinter.h:59
void printName(raw_ostream &OS) const
printName - Print the human-readable name to a stream.
bool hasQualifiers() const
Determines whether this type has any qualifiers.
DeclarationName()
DeclarationName - Used to create an empty selector.
Not an overloaded operator.
Definition: OperatorKinds.h:23
struct CXXLitOpName CXXLiteralOperatorName
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:3707
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:5818
bool isInstantiationDependent() const
Determine whether this name involves a template parameter.
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).
bool containsUnexpandedParameterPack() const
Determine whether this name contains an unexpanded parameter pack.
static void printCXXConstructorDestructorName(QualType ClassType, raw_ostream &OS, PrintingPolicy Policy)
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.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:665
DeclarationName getCXXOperatorName(OverloadedOperatorKind Op)
getCXXOperatorName - Get the name of the overloadable C++ operator corresponding to Op...