DeclarationName.cpp revision 203955
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/DeclarationName.h"
15#include "clang/AST/Type.h"
16#include "clang/AST/TypeOrdering.h"
17#include "clang/AST/Decl.h"
18#include "clang/Basic/IdentifierTable.h"
19#include "llvm/ADT/DenseMap.h"
20#include "llvm/ADT/FoldingSet.h"
21#include <cstdio>
22using namespace clang;
23
24namespace clang {
25/// CXXSpecialName - Records the type associated with one of the
26/// "special" kinds of declaration names in C++, e.g., constructors,
27/// destructors, and conversion functions.
28class CXXSpecialName
29  : public DeclarationNameExtra, public llvm::FoldingSetNode {
30public:
31  /// Type - The type associated with this declaration name.
32  QualType Type;
33
34  /// FETokenInfo - Extra information associated with this declaration
35  /// name that can be used by the front end.
36  void *FETokenInfo;
37
38  void Profile(llvm::FoldingSetNodeID &ID) {
39    ID.AddInteger(ExtraKindOrNumArgs);
40    ID.AddPointer(Type.getAsOpaquePtr());
41  }
42};
43
44/// CXXOperatorIdName - Contains extra information for the name of an
45/// overloaded operator in C++, such as "operator+.
46class CXXOperatorIdName : public DeclarationNameExtra {
47public:
48  /// FETokenInfo - Extra information associated with this operator
49  /// name that can be used by the front end.
50  void *FETokenInfo;
51};
52
53/// CXXLiberalOperatorName - Contains the actual identifier that makes up the
54/// name.
55///
56/// This identifier is stored here rather than directly in DeclarationName so as
57/// to allow Objective-C selectors, which are about a million times more common,
58/// to consume minimal memory.
59class CXXLiteralOperatorIdName
60  : public DeclarationNameExtra, public llvm::FoldingSetNode {
61public:
62  IdentifierInfo *ID;
63
64  void Profile(llvm::FoldingSetNodeID &FSID) {
65    FSID.AddPointer(ID);
66  }
67};
68
69static int compareInt(unsigned A, unsigned B) {
70  return (A < B ? -1 : (A > B ? 1 : 0));
71}
72
73int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
74  if (LHS.getNameKind() != RHS.getNameKind())
75    return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
76
77  switch (LHS.getNameKind()) {
78  case DeclarationName::Identifier: {
79    IdentifierInfo *LII = LHS.getAsIdentifierInfo();
80    IdentifierInfo *RII = RHS.getAsIdentifierInfo();
81    if (!LII) return RII ? -1 : 0;
82    if (!RII) return 1;
83
84    return LII->getName().compare(RII->getName());
85  }
86
87  case DeclarationName::ObjCZeroArgSelector:
88  case DeclarationName::ObjCOneArgSelector:
89  case DeclarationName::ObjCMultiArgSelector: {
90    Selector LHSSelector = LHS.getObjCSelector();
91    Selector RHSSelector = RHS.getObjCSelector();
92    unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
93    for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
94      IdentifierInfo *LHSId = LHSSelector.getIdentifierInfoForSlot(I);
95      IdentifierInfo *RHSId = RHSSelector.getIdentifierInfoForSlot(I);
96
97      switch (LHSId->getName().compare(RHSId->getName())) {
98      case -1: return true;
99      case 1: return false;
100      default: break;
101      }
102    }
103
104    return compareInt(LN, RN);
105  }
106
107  case DeclarationName::CXXConstructorName:
108  case DeclarationName::CXXDestructorName:
109  case DeclarationName::CXXConversionFunctionName:
110    if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
111      return -1;
112    if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
113      return 1;
114    return 0;
115
116  case DeclarationName::CXXOperatorName:
117    return compareInt(LHS.getCXXOverloadedOperator(),
118                      RHS.getCXXOverloadedOperator());
119
120  case DeclarationName::CXXLiteralOperatorName:
121    return LHS.getCXXLiteralIdentifier()->getName().compare(
122                                   RHS.getCXXLiteralIdentifier()->getName());
123
124  case DeclarationName::CXXUsingDirective:
125    return 0;
126  }
127
128  return 0;
129}
130
131} // end namespace clang
132
133DeclarationName::DeclarationName(Selector Sel) {
134  if (!Sel.getAsOpaquePtr()) {
135    Ptr = 0;
136    return;
137  }
138
139  switch (Sel.getNumArgs()) {
140  case 0:
141    Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
142    assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
143    Ptr |= StoredObjCZeroArgSelector;
144    break;
145
146  case 1:
147    Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
148    assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
149    Ptr |= StoredObjCOneArgSelector;
150    break;
151
152  default:
153    Ptr = Sel.InfoPtr & ~Selector::ArgFlags;
154    assert((Ptr & PtrMask) == 0 && "Improperly aligned MultiKeywordSelector");
155    Ptr |= StoredDeclarationNameExtra;
156    break;
157  }
158}
159
160DeclarationName::NameKind DeclarationName::getNameKind() const {
161  switch (getStoredNameKind()) {
162  case StoredIdentifier:          return Identifier;
163  case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
164  case StoredObjCOneArgSelector:  return ObjCOneArgSelector;
165
166  case StoredDeclarationNameExtra:
167    switch (getExtra()->ExtraKindOrNumArgs) {
168    case DeclarationNameExtra::CXXConstructor:
169      return CXXConstructorName;
170
171    case DeclarationNameExtra::CXXDestructor:
172      return CXXDestructorName;
173
174    case DeclarationNameExtra::CXXConversionFunction:
175      return CXXConversionFunctionName;
176
177    case DeclarationNameExtra::CXXLiteralOperator:
178      return CXXLiteralOperatorName;
179
180    case DeclarationNameExtra::CXXUsingDirective:
181      return CXXUsingDirective;
182
183    default:
184      // Check if we have one of the CXXOperator* enumeration values.
185      if (getExtra()->ExtraKindOrNumArgs <
186            DeclarationNameExtra::CXXUsingDirective)
187        return CXXOperatorName;
188
189      return ObjCMultiArgSelector;
190    }
191    break;
192  }
193
194  // Can't actually get here.
195  assert(0 && "This should be unreachable!");
196  return Identifier;
197}
198
199bool DeclarationName::isDependentName() const {
200  QualType T = getCXXNameType();
201  return !T.isNull() && T->isDependentType();
202}
203
204std::string DeclarationName::getAsString() const {
205  switch (getNameKind()) {
206  case Identifier:
207    if (const IdentifierInfo *II = getAsIdentifierInfo())
208      return II->getName();
209    return "";
210
211  case ObjCZeroArgSelector:
212  case ObjCOneArgSelector:
213  case ObjCMultiArgSelector:
214    return getObjCSelector().getAsString();
215
216  case CXXConstructorName: {
217    QualType ClassType = getCXXNameType();
218    if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
219      return ClassRec->getDecl()->getNameAsString();
220    return ClassType.getAsString();
221  }
222
223  case CXXDestructorName: {
224    std::string Result = "~";
225    QualType Type = getCXXNameType();
226    if (const RecordType *Rec = Type->getAs<RecordType>())
227      Result += Rec->getDecl()->getNameAsString();
228    else
229      Result += Type.getAsString();
230    return Result;
231  }
232
233  case CXXOperatorName: {
234    static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
235      0,
236#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
237      Spelling,
238#include "clang/Basic/OperatorKinds.def"
239    };
240    const char *OpName = OperatorNames[getCXXOverloadedOperator()];
241    assert(OpName && "not an overloaded operator");
242
243    std::string Result = "operator";
244    if (OpName[0] >= 'a' && OpName[0] <= 'z')
245      Result += ' ';
246    Result += OpName;
247    return Result;
248  }
249
250  case CXXLiteralOperatorName: {
251    return "operator \"\" " + std::string(getCXXLiteralIdentifier()->getName());
252  }
253
254  case CXXConversionFunctionName: {
255    std::string Result = "operator ";
256    QualType Type = getCXXNameType();
257    if (const RecordType *Rec = Type->getAs<RecordType>())
258      Result += Rec->getDecl()->getNameAsString();
259    else
260      Result += Type.getAsString();
261    return Result;
262  }
263  case CXXUsingDirective:
264    return "<using-directive>";
265  }
266
267  assert(false && "Unexpected declaration name kind");
268  return "";
269}
270
271QualType DeclarationName::getCXXNameType() const {
272  if (CXXSpecialName *CXXName = getAsCXXSpecialName())
273    return CXXName->Type;
274  else
275    return QualType();
276}
277
278OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
279  if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
280    unsigned value
281      = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
282    return static_cast<OverloadedOperatorKind>(value);
283  } else {
284    return OO_None;
285  }
286}
287
288IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
289  if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
290    return CXXLit->ID;
291  else
292    return 0;
293}
294
295Selector DeclarationName::getObjCSelector() const {
296  switch (getNameKind()) {
297  case ObjCZeroArgSelector:
298    return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 0);
299
300  case ObjCOneArgSelector:
301    return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 1);
302
303  case ObjCMultiArgSelector:
304    return Selector(reinterpret_cast<MultiKeywordSelector *>(Ptr & ~PtrMask));
305
306  default:
307    break;
308  }
309
310  return Selector();
311}
312
313void *DeclarationName::getFETokenInfoAsVoid() const {
314  switch (getNameKind()) {
315  case Identifier:
316    return getAsIdentifierInfo()->getFETokenInfo<void>();
317
318  case CXXConstructorName:
319  case CXXDestructorName:
320  case CXXConversionFunctionName:
321    return getAsCXXSpecialName()->FETokenInfo;
322
323  case CXXOperatorName:
324    return getAsCXXOperatorIdName()->FETokenInfo;
325
326  case CXXLiteralOperatorName:
327    return getCXXLiteralIdentifier()->getFETokenInfo<void>();
328
329  default:
330    assert(false && "Declaration name has no FETokenInfo");
331  }
332  return 0;
333}
334
335void DeclarationName::setFETokenInfo(void *T) {
336  switch (getNameKind()) {
337  case Identifier:
338    getAsIdentifierInfo()->setFETokenInfo(T);
339    break;
340
341  case CXXConstructorName:
342  case CXXDestructorName:
343  case CXXConversionFunctionName:
344    getAsCXXSpecialName()->FETokenInfo = T;
345    break;
346
347  case CXXOperatorName:
348    getAsCXXOperatorIdName()->FETokenInfo = T;
349    break;
350
351  case CXXLiteralOperatorName:
352    getCXXLiteralIdentifier()->setFETokenInfo(T);
353    break;
354
355  default:
356    assert(false && "Declaration name has no FETokenInfo");
357  }
358}
359
360DeclarationName DeclarationName::getUsingDirectiveName() {
361  // Single instance of DeclarationNameExtra for using-directive
362  static const DeclarationNameExtra UDirExtra =
363    { DeclarationNameExtra::CXXUsingDirective };
364
365  uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
366  Ptr |= StoredDeclarationNameExtra;
367
368  return DeclarationName(Ptr);
369}
370
371void DeclarationName::dump() const {
372  fprintf(stderr, "%s\n", getAsString().c_str());
373}
374
375DeclarationNameTable::DeclarationNameTable() {
376  CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
377  CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
378
379  // Initialize the overloaded operator names.
380  CXXOperatorNames = new CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
381  for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
382    CXXOperatorNames[Op].ExtraKindOrNumArgs
383      = Op + DeclarationNameExtra::CXXConversionFunction;
384    CXXOperatorNames[Op].FETokenInfo = 0;
385  }
386}
387
388DeclarationNameTable::~DeclarationNameTable() {
389  llvm::FoldingSet<CXXSpecialName> *SpecialNames =
390    static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
391  llvm::FoldingSetIterator<CXXSpecialName>
392                           SI = SpecialNames->begin(), SE = SpecialNames->end();
393
394  while (SI != SE) {
395    CXXSpecialName *n = &*SI++;
396    delete n;
397  }
398
399
400  llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
401    = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
402                                                      (CXXLiteralOperatorNames);
403  llvm::FoldingSetIterator<CXXLiteralOperatorIdName>
404                           LI = LiteralNames->begin(), LE = LiteralNames->end();
405
406  while (LI != LE) {
407    CXXLiteralOperatorIdName *n = &*LI++;
408    delete n;
409  }
410
411  delete SpecialNames;
412  delete LiteralNames;
413  delete [] CXXOperatorNames;
414}
415
416DeclarationName
417DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
418                                        CanQualType Ty) {
419  assert(Kind >= DeclarationName::CXXConstructorName &&
420         Kind <= DeclarationName::CXXConversionFunctionName &&
421         "Kind must be a C++ special name kind");
422  llvm::FoldingSet<CXXSpecialName> *SpecialNames
423    = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
424
425  DeclarationNameExtra::ExtraKind EKind;
426  switch (Kind) {
427  case DeclarationName::CXXConstructorName:
428    EKind = DeclarationNameExtra::CXXConstructor;
429    assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
430    break;
431  case DeclarationName::CXXDestructorName:
432    EKind = DeclarationNameExtra::CXXDestructor;
433    assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
434    break;
435  case DeclarationName::CXXConversionFunctionName:
436    EKind = DeclarationNameExtra::CXXConversionFunction;
437    break;
438  default:
439    return DeclarationName();
440  }
441
442  // Unique selector, to guarantee there is one per name.
443  llvm::FoldingSetNodeID ID;
444  ID.AddInteger(EKind);
445  ID.AddPointer(Ty.getAsOpaquePtr());
446
447  void *InsertPos = 0;
448  if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
449    return DeclarationName(Name);
450
451  CXXSpecialName *SpecialName = new CXXSpecialName;
452  SpecialName->ExtraKindOrNumArgs = EKind;
453  SpecialName->Type = Ty;
454  SpecialName->FETokenInfo = 0;
455
456  SpecialNames->InsertNode(SpecialName, InsertPos);
457  return DeclarationName(SpecialName);
458}
459
460DeclarationName
461DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
462  return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
463}
464
465DeclarationName
466DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
467  llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
468    = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
469                                                      (CXXLiteralOperatorNames);
470
471  llvm::FoldingSetNodeID ID;
472  ID.AddPointer(II);
473
474  void *InsertPos = 0;
475  if (CXXLiteralOperatorIdName *Name =
476                               LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
477    return DeclarationName (Name);
478
479  CXXLiteralOperatorIdName *LiteralName = new CXXLiteralOperatorIdName;
480  LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
481  LiteralName->ID = II;
482
483  LiteralNames->InsertNode(LiteralName, InsertPos);
484  return DeclarationName(LiteralName);
485}
486
487unsigned
488llvm::DenseMapInfo<clang::DeclarationName>::
489getHashValue(clang::DeclarationName N) {
490  return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr());
491}
492
493