DeclarationName.cpp revision 200583
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 : public DeclarationNameExtra {
60public:
61  IdentifierInfo *ID;
62};
63
64bool operator<(DeclarationName LHS, DeclarationName RHS) {
65  if (LHS.getNameKind() != RHS.getNameKind())
66    return LHS.getNameKind() < RHS.getNameKind();
67
68  switch (LHS.getNameKind()) {
69  case DeclarationName::Identifier:
70    return LHS.getAsIdentifierInfo()->getName() <
71                                         RHS.getAsIdentifierInfo()->getName();
72
73  case DeclarationName::ObjCZeroArgSelector:
74  case DeclarationName::ObjCOneArgSelector:
75  case DeclarationName::ObjCMultiArgSelector: {
76    Selector LHSSelector = LHS.getObjCSelector();
77    Selector RHSSelector = RHS.getObjCSelector();
78    for (unsigned I = 0,
79               N = std::min(LHSSelector.getNumArgs(), RHSSelector.getNumArgs());
80         I != N; ++I) {
81      IdentifierInfo *LHSId = LHSSelector.getIdentifierInfoForSlot(I);
82      IdentifierInfo *RHSId = RHSSelector.getIdentifierInfoForSlot(I);
83      if (!LHSId || !RHSId)
84        return LHSId && !RHSId;
85
86      switch (LHSId->getName().compare(RHSId->getName())) {
87      case -1: return true;
88      case 1: return false;
89      default: break;
90      }
91    }
92
93    return LHSSelector.getNumArgs() < RHSSelector.getNumArgs();
94  }
95
96  case DeclarationName::CXXConstructorName:
97  case DeclarationName::CXXDestructorName:
98  case DeclarationName::CXXConversionFunctionName:
99    return QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType());
100
101  case DeclarationName::CXXOperatorName:
102    return LHS.getCXXOverloadedOperator() < RHS.getCXXOverloadedOperator();
103
104  case DeclarationName::CXXLiteralOperatorName:
105    return LHS.getCXXLiteralIdentifier()->getName() <
106                                       RHS.getCXXLiteralIdentifier()->getName();
107
108  case DeclarationName::CXXUsingDirective:
109    return false;
110  }
111
112  return false;
113}
114
115} // end namespace clang
116
117DeclarationName::DeclarationName(Selector Sel) {
118  if (!Sel.getAsOpaquePtr()) {
119    Ptr = 0;
120    return;
121  }
122
123  switch (Sel.getNumArgs()) {
124  case 0:
125    Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
126    assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
127    Ptr |= StoredObjCZeroArgSelector;
128    break;
129
130  case 1:
131    Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
132    assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
133    Ptr |= StoredObjCOneArgSelector;
134    break;
135
136  default:
137    Ptr = Sel.InfoPtr & ~Selector::ArgFlags;
138    assert((Ptr & PtrMask) == 0 && "Improperly aligned MultiKeywordSelector");
139    Ptr |= StoredDeclarationNameExtra;
140    break;
141  }
142}
143
144DeclarationName::NameKind DeclarationName::getNameKind() const {
145  switch (getStoredNameKind()) {
146  case StoredIdentifier:          return Identifier;
147  case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
148  case StoredObjCOneArgSelector:  return ObjCOneArgSelector;
149
150  case StoredDeclarationNameExtra:
151    switch (getExtra()->ExtraKindOrNumArgs) {
152    case DeclarationNameExtra::CXXConstructor:
153      return CXXConstructorName;
154
155    case DeclarationNameExtra::CXXDestructor:
156      return CXXDestructorName;
157
158    case DeclarationNameExtra::CXXConversionFunction:
159      return CXXConversionFunctionName;
160
161    case DeclarationNameExtra::CXXLiteralOperator:
162      return CXXLiteralOperatorName;
163
164    case DeclarationNameExtra::CXXUsingDirective:
165      return CXXUsingDirective;
166
167    default:
168      // Check if we have one of the CXXOperator* enumeration values.
169      if (getExtra()->ExtraKindOrNumArgs <
170            DeclarationNameExtra::CXXUsingDirective)
171        return CXXOperatorName;
172
173      return ObjCMultiArgSelector;
174    }
175    break;
176  }
177
178  // Can't actually get here.
179  assert(0 && "This should be unreachable!");
180  return Identifier;
181}
182
183std::string DeclarationName::getAsString() const {
184  switch (getNameKind()) {
185  case Identifier:
186    if (const IdentifierInfo *II = getAsIdentifierInfo())
187      return II->getName();
188    return "";
189
190  case ObjCZeroArgSelector:
191  case ObjCOneArgSelector:
192  case ObjCMultiArgSelector:
193    return getObjCSelector().getAsString();
194
195  case CXXConstructorName: {
196    QualType ClassType = getCXXNameType();
197    if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
198      return ClassRec->getDecl()->getNameAsString();
199    return ClassType.getAsString();
200  }
201
202  case CXXDestructorName: {
203    std::string Result = "~";
204    QualType Type = getCXXNameType();
205    if (const RecordType *Rec = Type->getAs<RecordType>())
206      Result += Rec->getDecl()->getNameAsString();
207    else
208      Result += Type.getAsString();
209    return Result;
210  }
211
212  case CXXOperatorName: {
213    static const char *OperatorNames[NUM_OVERLOADED_OPERATORS] = {
214      0,
215#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
216      Spelling,
217#include "clang/Basic/OperatorKinds.def"
218    };
219    const char *OpName = OperatorNames[getCXXOverloadedOperator()];
220    assert(OpName && "not an overloaded operator");
221
222    std::string Result = "operator";
223    if (OpName[0] >= 'a' && OpName[0] <= 'z')
224      Result += ' ';
225    Result += OpName;
226    return Result;
227  }
228
229  case CXXLiteralOperatorName: {
230    return "operator \"\" " + std::string(getCXXLiteralIdentifier()->getName());
231  }
232
233  case CXXConversionFunctionName: {
234    std::string Result = "operator ";
235    QualType Type = getCXXNameType();
236    if (const RecordType *Rec = Type->getAs<RecordType>())
237      Result += Rec->getDecl()->getNameAsString();
238    else
239      Result += Type.getAsString();
240    return Result;
241  }
242  case CXXUsingDirective:
243    return "<using-directive>";
244  }
245
246  assert(false && "Unexpected declaration name kind");
247  return "";
248}
249
250QualType DeclarationName::getCXXNameType() const {
251  if (CXXSpecialName *CXXName = getAsCXXSpecialName())
252    return CXXName->Type;
253  else
254    return QualType();
255}
256
257OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
258  if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
259    unsigned value
260      = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
261    return static_cast<OverloadedOperatorKind>(value);
262  } else {
263    return OO_None;
264  }
265}
266
267IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
268  if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
269    return CXXLit->ID;
270  else
271    return 0;
272}
273
274Selector DeclarationName::getObjCSelector() const {
275  switch (getNameKind()) {
276  case ObjCZeroArgSelector:
277    return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 0);
278
279  case ObjCOneArgSelector:
280    return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 1);
281
282  case ObjCMultiArgSelector:
283    return Selector(reinterpret_cast<MultiKeywordSelector *>(Ptr & ~PtrMask));
284
285  default:
286    break;
287  }
288
289  return Selector();
290}
291
292void *DeclarationName::getFETokenInfoAsVoid() const {
293  switch (getNameKind()) {
294  case Identifier:
295    return getAsIdentifierInfo()->getFETokenInfo<void>();
296
297  case CXXConstructorName:
298  case CXXDestructorName:
299  case CXXConversionFunctionName:
300    return getAsCXXSpecialName()->FETokenInfo;
301
302  case CXXOperatorName:
303    return getAsCXXOperatorIdName()->FETokenInfo;
304
305  case CXXLiteralOperatorName:
306    return getCXXLiteralIdentifier()->getFETokenInfo<void>();
307
308  default:
309    assert(false && "Declaration name has no FETokenInfo");
310  }
311  return 0;
312}
313
314void DeclarationName::setFETokenInfo(void *T) {
315  switch (getNameKind()) {
316  case Identifier:
317    getAsIdentifierInfo()->setFETokenInfo(T);
318    break;
319
320  case CXXConstructorName:
321  case CXXDestructorName:
322  case CXXConversionFunctionName:
323    getAsCXXSpecialName()->FETokenInfo = T;
324    break;
325
326  case CXXOperatorName:
327    getAsCXXOperatorIdName()->FETokenInfo = T;
328    break;
329
330  case CXXLiteralOperatorName:
331    getCXXLiteralIdentifier()->setFETokenInfo(T);
332    break;
333
334  default:
335    assert(false && "Declaration name has no FETokenInfo");
336  }
337}
338
339DeclarationName DeclarationName::getUsingDirectiveName() {
340  // Single instance of DeclarationNameExtra for using-directive
341  static const DeclarationNameExtra UDirExtra =
342    { DeclarationNameExtra::CXXUsingDirective };
343
344  uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
345  Ptr |= StoredDeclarationNameExtra;
346
347  return DeclarationName(Ptr);
348}
349
350void DeclarationName::dump() const {
351  fprintf(stderr, "%s\n", getAsString().c_str());
352}
353
354DeclarationNameTable::DeclarationNameTable() {
355  CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
356
357  // Initialize the overloaded operator names.
358  CXXOperatorNames = new CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
359  for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
360    CXXOperatorNames[Op].ExtraKindOrNumArgs
361      = Op + DeclarationNameExtra::CXXConversionFunction;
362    CXXOperatorNames[Op].FETokenInfo = 0;
363  }
364}
365
366DeclarationNameTable::~DeclarationNameTable() {
367  llvm::FoldingSet<CXXSpecialName> *set =
368    static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
369  llvm::FoldingSetIterator<CXXSpecialName> I = set->begin(), E = set->end();
370
371  while (I != E) {
372    CXXSpecialName *n = &*I++;
373    delete n;
374  }
375
376  delete set;
377  delete [] CXXOperatorNames;
378}
379
380DeclarationName
381DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
382                                        CanQualType Ty) {
383  assert(Kind >= DeclarationName::CXXConstructorName &&
384         Kind <= DeclarationName::CXXConversionFunctionName &&
385         "Kind must be a C++ special name kind");
386  llvm::FoldingSet<CXXSpecialName> *SpecialNames
387    = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
388
389  DeclarationNameExtra::ExtraKind EKind;
390  switch (Kind) {
391  case DeclarationName::CXXConstructorName:
392    EKind = DeclarationNameExtra::CXXConstructor;
393    assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
394    break;
395  case DeclarationName::CXXDestructorName:
396    EKind = DeclarationNameExtra::CXXDestructor;
397    assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
398    break;
399  case DeclarationName::CXXConversionFunctionName:
400    EKind = DeclarationNameExtra::CXXConversionFunction;
401    break;
402  default:
403    return DeclarationName();
404  }
405
406  // Unique selector, to guarantee there is one per name.
407  llvm::FoldingSetNodeID ID;
408  ID.AddInteger(EKind);
409  ID.AddPointer(Ty.getAsOpaquePtr());
410
411  void *InsertPos = 0;
412  if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
413    return DeclarationName(Name);
414
415  CXXSpecialName *SpecialName = new CXXSpecialName;
416  SpecialName->ExtraKindOrNumArgs = EKind;
417  SpecialName->Type = Ty;
418  SpecialName->FETokenInfo = 0;
419
420  SpecialNames->InsertNode(SpecialName, InsertPos);
421  return DeclarationName(SpecialName);
422}
423
424DeclarationName
425DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
426  return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
427}
428
429DeclarationName
430DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
431  CXXLiteralOperatorIdName *LiteralName = new CXXLiteralOperatorIdName;
432  LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
433  LiteralName->ID = II;
434  return DeclarationName(LiteralName);
435}
436
437unsigned
438llvm::DenseMapInfo<clang::DeclarationName>::
439getHashValue(clang::DeclarationName N) {
440  return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr());
441}
442
443