clang  3.7.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/Decl.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 
136 raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
137  switch (N.getNameKind()) {
139  if (const IdentifierInfo *II = N.getAsIdentifierInfo())
140  OS << II->getName();
141  return OS;
142 
146  N.getObjCSelector().print(OS);
147  return OS;
148 
150  QualType ClassType = N.getCXXNameType();
151  if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
152  return OS << *ClassRec->getDecl();
153  LangOptions LO;
154  LO.CPlusPlus = true;
155  return OS << ClassType.getAsString(PrintingPolicy(LO));
156  }
157 
159  OS << '~';
161  if (const RecordType *Rec = Type->getAs<RecordType>())
162  return OS << *Rec->getDecl();
163  LangOptions LO;
164  LO.CPlusPlus = true;
165  return OS << Type.getAsString(PrintingPolicy(LO));
166  }
167 
169  static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
170  nullptr,
171 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
172  Spelling,
173 #include "clang/Basic/OperatorKinds.def"
174  };
175  const char *OpName = OperatorNames[N.getCXXOverloadedOperator()];
176  assert(OpName && "not an overloaded operator");
177 
178  OS << "operator";
179  if (OpName[0] >= 'a' && OpName[0] <= 'z')
180  OS << ' ';
181  return OS << OpName;
182  }
183 
185  return OS << "operator \"\" " << N.getCXXLiteralIdentifier()->getName();
186 
188  OS << "operator ";
190  if (const RecordType *Rec = Type->getAs<RecordType>())
191  return OS << *Rec->getDecl();
192  LangOptions LO;
193  LO.CPlusPlus = true;
194  LO.Bool = true;
195  return OS << Type.getAsString(PrintingPolicy(LO));
196  }
198  return OS << "<using-directive>";
199  }
200 
201  llvm_unreachable("Unexpected declaration name kind");
202 }
203 
204 } // end namespace clang
205 
206 DeclarationName::NameKind DeclarationName::getNameKind() const {
207  switch (getStoredNameKind()) {
208  case StoredIdentifier: return Identifier;
209  case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
210  case StoredObjCOneArgSelector: return ObjCOneArgSelector;
211 
212  case StoredDeclarationNameExtra:
213  switch (getExtra()->ExtraKindOrNumArgs) {
215  return CXXConstructorName;
216 
218  return CXXDestructorName;
219 
222 
224  return CXXLiteralOperatorName;
225 
227  return CXXUsingDirective;
228 
229  default:
230  // Check if we have one of the CXXOperator* enumeration values.
231  if (getExtra()->ExtraKindOrNumArgs <
233  return CXXOperatorName;
234 
235  return ObjCMultiArgSelector;
236  }
237  }
238 
239  // Can't actually get here.
240  llvm_unreachable("This should be unreachable!");
241 }
242 
244  QualType T = getCXXNameType();
245  return !T.isNull() && T->isDependentType();
246 }
247 
248 std::string DeclarationName::getAsString() const {
249  std::string Result;
250  llvm::raw_string_ostream OS(Result);
251  OS << *this;
252  return OS.str();
253 }
254 
256  if (CXXSpecialName *CXXName = getAsCXXSpecialName())
257  return CXXName->Type;
258  else
259  return QualType();
260 }
261 
263  if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
264  unsigned value
265  = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
266  return static_cast<OverloadedOperatorKind>(value);
267  } else {
268  return OO_None;
269  }
270 }
271 
273  if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
274  return CXXLit->ID;
275  else
276  return nullptr;
277 }
278 
279 void *DeclarationName::getFETokenInfoAsVoidSlow() const {
280  switch (getNameKind()) {
281  case Identifier:
282  llvm_unreachable("Handled by getFETokenInfo()");
283 
284  case CXXConstructorName:
285  case CXXDestructorName:
287  return getAsCXXSpecialName()->FETokenInfo;
288 
289  case CXXOperatorName:
290  return getAsCXXOperatorIdName()->FETokenInfo;
291 
293  return getAsCXXLiteralOperatorIdName()->FETokenInfo;
294 
295  default:
296  llvm_unreachable("Declaration name has no FETokenInfo");
297  }
298 }
299 
301  switch (getNameKind()) {
302  case Identifier:
304  break;
305 
306  case CXXConstructorName:
307  case CXXDestructorName:
309  getAsCXXSpecialName()->FETokenInfo = T;
310  break;
311 
312  case CXXOperatorName:
313  getAsCXXOperatorIdName()->FETokenInfo = T;
314  break;
315 
317  getAsCXXLiteralOperatorIdName()->FETokenInfo = T;
318  break;
319 
320  default:
321  llvm_unreachable("Declaration name has no FETokenInfo");
322  }
323 }
324 
326  // Single instance of DeclarationNameExtra for using-directive
327  static const DeclarationNameExtra UDirExtra =
329 
330  uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
331  Ptr |= StoredDeclarationNameExtra;
332 
333  return DeclarationName(Ptr);
334 }
335 
336 void DeclarationName::dump() const {
337  llvm::errs() << *this << '\n';
338 }
339 
340 DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
341  CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
342  CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
343 
344  // Initialize the overloaded operator names.
345  CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
346  for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
347  CXXOperatorNames[Op].ExtraKindOrNumArgs
349  CXXOperatorNames[Op].FETokenInfo = nullptr;
350  }
351 }
352 
354  llvm::FoldingSet<CXXSpecialName> *SpecialNames =
355  static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
356  llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
357  = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
358  (CXXLiteralOperatorNames);
359 
360  delete SpecialNames;
361  delete LiteralNames;
362 }
363 
366  Ty.getUnqualifiedType());
367 }
368 
371  Ty.getUnqualifiedType());
372 }
373 
377 }
378 
381  CanQualType Ty) {
382  assert(Kind >= DeclarationName::CXXConstructorName &&
384  "Kind must be a C++ special name kind");
385  llvm::FoldingSet<CXXSpecialName> *SpecialNames
386  = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
387 
389  switch (Kind) {
392  assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
393  break;
396  assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
397  break;
400  break;
401  default:
402  return DeclarationName();
403  }
404 
405  // Unique selector, to guarantee there is one per name.
406  llvm::FoldingSetNodeID ID;
407  ID.AddInteger(EKind);
408  ID.AddPointer(Ty.getAsOpaquePtr());
409 
410  void *InsertPos = nullptr;
411  if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
412  return DeclarationName(Name);
413 
414  CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
415  SpecialName->ExtraKindOrNumArgs = EKind;
416  SpecialName->Type = Ty;
417  SpecialName->FETokenInfo = nullptr;
418 
419  SpecialNames->InsertNode(SpecialName, InsertPos);
420  return DeclarationName(SpecialName);
421 }
422 
425  return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
426 }
427 
430  llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
431  = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
432  (CXXLiteralOperatorNames);
433 
434  llvm::FoldingSetNodeID ID;
435  ID.AddPointer(II);
436 
437  void *InsertPos = nullptr;
438  if (CXXLiteralOperatorIdName *Name =
439  LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
440  return DeclarationName (Name);
441 
442  CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
444  LiteralName->ID = II;
445  LiteralName->FETokenInfo = nullptr;
446 
447  LiteralNames->InsertNode(LiteralName, InsertPos);
448  return DeclarationName(LiteralName);
449 }
450 
452  switch (Name.getNameKind()) {
454  break;
458  NamedType.TInfo = nullptr;
459  break;
463  break;
466  break;
470  // FIXME: ?
471  break;
473  break;
474  }
475 }
476 
478  switch (Name.getNameKind()) {
486  return false;
487 
491  if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
492  return TInfo->getType()->containsUnexpandedParameterPack();
493 
495  }
496  llvm_unreachable("All name kinds handled.");
497 }
498 
500  switch (Name.getNameKind()) {
508  return false;
509 
513  if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
514  return TInfo->getType()->isInstantiationDependentType();
515 
517  }
518  llvm_unreachable("All name kinds handled.");
519 }
520 
521 std::string DeclarationNameInfo::getAsString() const {
522  std::string Result;
523  llvm::raw_string_ostream OS(Result);
524  printName(OS);
525  return OS.str();
526 }
527 
528 void DeclarationNameInfo::printName(raw_ostream &OS) const {
529  switch (Name.getNameKind()) {
537  OS << Name;
538  return;
539 
543  if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
544  if (Name.getNameKind() == DeclarationName::CXXDestructorName)
545  OS << '~';
546  else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
547  OS << "operator ";
548  LangOptions LO;
549  LO.CPlusPlus = true;
550  LO.Bool = true;
551  OS << TInfo->getType().getAsString(PrintingPolicy(LO));
552  } else
553  OS << Name;
554  return;
555  }
556  llvm_unreachable("Unexpected declaration name kind");
557 }
558 
560  switch (Name.getNameKind()) {
562  return NameLoc;
563 
565  unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
567  }
568 
570  unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
572  }
573 
577  if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
578  return TInfo->getTypeLoc().getEndLoc();
579  else
580  return NameLoc;
581 
582  // DNInfo work in progress: FIXME.
587  return NameLoc;
588  }
589  llvm_unreachable("Unexpected declaration name kind");
590 }
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.
NameKind
NameKind - The kind of name this object contains.
QualType Type
Type - The type associated with this declaration name.
DeclarationName getCXXConstructorName(CanQualType Ty)
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
Definition: Type.h:1733
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
DeclarationName getCXXConversionFunctionName(CanQualType Ty)
std::string getAsString() const
Definition: Type.h:897
const DiagnosticBuilder & operator<<(const DiagnosticBuilder &DB, const Attr *At)
Definition: Attr.h:154
IdentifierInfo * getAsIdentifierInfo() const
A container of type source information.
Definition: Decl.h:60
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:35
bool containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
Definition: Type.h:1506
void Profile(llvm::FoldingSetNodeID &ID)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:89
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)
DeclarationName getCXXDestructorName(CanQualType Ty)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:48
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:").
Function object that provides a total ordering on QualType values.
Definition: TypeOrdering.h:29
ID
Defines the set of possible language-specific address spaces.
Definition: AddressSpaces.h:27
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)
Defines the clang::TypeLoc interface and its subclasses.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
bool isDependentType() const
Definition: Type.h:1727
QualType getCXXNameType() const
struct CXXOpName CXXOperatorName
The result type of a method or function.
Kind
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
OverloadedOperatorKind getCXXOverloadedOperator() const
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.
DeclarationName getCXXSpecialName(DeclarationName::NameKind Kind, CanQualType Ty)
Selector getObjCSelector() const
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:22
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
const T * getAs() const
Definition: Type.h:5555
bool isInstantiationDependent() const
Determine whether this name involves a template parameter.
DeclarationName getCXXLiteralOperatorName(IdentifierInfo *II)
bool containsUnexpandedParameterPack() const
Determine whether this name contains an unexpanded parameter pack.
static DeclarationName getUsingDirectiveName()
getUsingDirectiveName - Return name for all using-directives.
bool isNull() const
isNull - Return true if this QualType doesn't point to a type yet.
Definition: Type.h:633
DeclarationName getCXXOperatorName(OverloadedOperatorKind Op)