DeclarationName.cpp revision 263508
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"
16#include "clang/AST/DeclarationName.h"
17#include "clang/AST/Type.h"
18#include "clang/AST/TypeLoc.h"
19#include "clang/AST/TypeOrdering.h"
20#include "clang/Basic/IdentifierTable.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"
25using namespace clang;
26
27namespace 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.
31class CXXSpecialName
32  : public DeclarationNameExtra, public llvm::FoldingSetNode {
33public:
34  /// Type - The type associated with this declaration name.
35  QualType Type;
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+.
49class CXXOperatorIdName : public DeclarationNameExtra {
50public:
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.
62class CXXLiteralOperatorIdName
63  : public DeclarationNameExtra, public llvm::FoldingSetNode {
64public:
65  IdentifierInfo *ID;
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
76static int compareInt(unsigned A, unsigned B) {
77  return (A < B ? -1 : (A > B ? 1 : 0));
78}
79
80int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
81  if (LHS.getNameKind() != RHS.getNameKind())
82    return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
83
84  switch (LHS.getNameKind()) {
85  case DeclarationName::Identifier: {
86    IdentifierInfo *LII = LHS.getAsIdentifierInfo();
87    IdentifierInfo *RII = RHS.getAsIdentifierInfo();
88    if (!LII) return RII ? -1 : 0;
89    if (!RII) return 1;
90
91    return LII->getName().compare(RII->getName());
92  }
93
94  case DeclarationName::ObjCZeroArgSelector:
95  case DeclarationName::ObjCOneArgSelector:
96  case DeclarationName::ObjCMultiArgSelector: {
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
112  case DeclarationName::CXXConstructorName:
113  case DeclarationName::CXXDestructorName:
114  case DeclarationName::CXXConversionFunctionName:
115    if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
116      return -1;
117    if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
118      return 1;
119    return 0;
120
121  case DeclarationName::CXXOperatorName:
122    return compareInt(LHS.getCXXOverloadedOperator(),
123                      RHS.getCXXOverloadedOperator());
124
125  case DeclarationName::CXXLiteralOperatorName:
126    return LHS.getCXXLiteralIdentifier()->getName().compare(
127                                   RHS.getCXXLiteralIdentifier()->getName());
128
129  case DeclarationName::CXXUsingDirective:
130    return 0;
131  }
132
133  llvm_unreachable("Invalid DeclarationName Kind!");
134}
135
136raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
137  switch (N.getNameKind()) {
138  case DeclarationName::Identifier:
139    if (const IdentifierInfo *II = N.getAsIdentifierInfo())
140      OS << II->getName();
141    return OS;
142
143  case DeclarationName::ObjCZeroArgSelector:
144  case DeclarationName::ObjCOneArgSelector:
145  case DeclarationName::ObjCMultiArgSelector:
146    return OS << N.getObjCSelector().getAsString();
147
148  case DeclarationName::CXXConstructorName: {
149    QualType ClassType = N.getCXXNameType();
150    if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
151      return OS << *ClassRec->getDecl();
152    return OS << ClassType.getAsString();
153  }
154
155  case DeclarationName::CXXDestructorName: {
156    OS << '~';
157    QualType Type = N.getCXXNameType();
158    if (const RecordType *Rec = Type->getAs<RecordType>())
159      return OS << *Rec->getDecl();
160    return OS << Type.getAsString();
161  }
162
163  case DeclarationName::CXXOperatorName: {
164    static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
165      0,
166#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
167      Spelling,
168#include "clang/Basic/OperatorKinds.def"
169    };
170    const char *OpName = OperatorNames[N.getCXXOverloadedOperator()];
171    assert(OpName && "not an overloaded operator");
172
173    OS << "operator";
174    if (OpName[0] >= 'a' && OpName[0] <= 'z')
175      OS << ' ';
176    return OS << OpName;
177  }
178
179  case DeclarationName::CXXLiteralOperatorName:
180    return OS << "operator \"\" " << N.getCXXLiteralIdentifier()->getName();
181
182  case DeclarationName::CXXConversionFunctionName: {
183    OS << "operator ";
184    QualType Type = N.getCXXNameType();
185    if (const RecordType *Rec = Type->getAs<RecordType>())
186      return OS << *Rec->getDecl();
187    return OS << Type.getAsString();
188  }
189  case DeclarationName::CXXUsingDirective:
190    return OS << "<using-directive>";
191  }
192
193  llvm_unreachable("Unexpected declaration name kind");
194}
195
196} // end namespace clang
197
198DeclarationName::NameKind DeclarationName::getNameKind() const {
199  switch (getStoredNameKind()) {
200  case StoredIdentifier:          return Identifier;
201  case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
202  case StoredObjCOneArgSelector:  return ObjCOneArgSelector;
203
204  case StoredDeclarationNameExtra:
205    switch (getExtra()->ExtraKindOrNumArgs) {
206    case DeclarationNameExtra::CXXConstructor:
207      return CXXConstructorName;
208
209    case DeclarationNameExtra::CXXDestructor:
210      return CXXDestructorName;
211
212    case DeclarationNameExtra::CXXConversionFunction:
213      return CXXConversionFunctionName;
214
215    case DeclarationNameExtra::CXXLiteralOperator:
216      return CXXLiteralOperatorName;
217
218    case DeclarationNameExtra::CXXUsingDirective:
219      return CXXUsingDirective;
220
221    default:
222      // Check if we have one of the CXXOperator* enumeration values.
223      if (getExtra()->ExtraKindOrNumArgs <
224            DeclarationNameExtra::CXXUsingDirective)
225        return CXXOperatorName;
226
227      return ObjCMultiArgSelector;
228    }
229  }
230
231  // Can't actually get here.
232  llvm_unreachable("This should be unreachable!");
233}
234
235bool DeclarationName::isDependentName() const {
236  QualType T = getCXXNameType();
237  return !T.isNull() && T->isDependentType();
238}
239
240std::string DeclarationName::getAsString() const {
241  std::string Result;
242  llvm::raw_string_ostream OS(Result);
243  OS << *this;
244  return OS.str();
245}
246
247QualType DeclarationName::getCXXNameType() const {
248  if (CXXSpecialName *CXXName = getAsCXXSpecialName())
249    return CXXName->Type;
250  else
251    return QualType();
252}
253
254OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
255  if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
256    unsigned value
257      = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
258    return static_cast<OverloadedOperatorKind>(value);
259  } else {
260    return OO_None;
261  }
262}
263
264IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
265  if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
266    return CXXLit->ID;
267  else
268    return 0;
269}
270
271void *DeclarationName::getFETokenInfoAsVoidSlow() const {
272  switch (getNameKind()) {
273  case Identifier:
274    llvm_unreachable("Handled by getFETokenInfo()");
275
276  case CXXConstructorName:
277  case CXXDestructorName:
278  case CXXConversionFunctionName:
279    return getAsCXXSpecialName()->FETokenInfo;
280
281  case CXXOperatorName:
282    return getAsCXXOperatorIdName()->FETokenInfo;
283
284  case CXXLiteralOperatorName:
285    return getAsCXXLiteralOperatorIdName()->FETokenInfo;
286
287  default:
288    llvm_unreachable("Declaration name has no FETokenInfo");
289  }
290}
291
292void DeclarationName::setFETokenInfo(void *T) {
293  switch (getNameKind()) {
294  case Identifier:
295    getAsIdentifierInfo()->setFETokenInfo(T);
296    break;
297
298  case CXXConstructorName:
299  case CXXDestructorName:
300  case CXXConversionFunctionName:
301    getAsCXXSpecialName()->FETokenInfo = T;
302    break;
303
304  case CXXOperatorName:
305    getAsCXXOperatorIdName()->FETokenInfo = T;
306    break;
307
308  case CXXLiteralOperatorName:
309    getAsCXXLiteralOperatorIdName()->FETokenInfo = T;
310    break;
311
312  default:
313    llvm_unreachable("Declaration name has no FETokenInfo");
314  }
315}
316
317DeclarationName DeclarationName::getUsingDirectiveName() {
318  // Single instance of DeclarationNameExtra for using-directive
319  static const DeclarationNameExtra UDirExtra =
320    { DeclarationNameExtra::CXXUsingDirective };
321
322  uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
323  Ptr |= StoredDeclarationNameExtra;
324
325  return DeclarationName(Ptr);
326}
327
328void DeclarationName::dump() const {
329  llvm::errs() << *this << '\n';
330}
331
332DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
333  CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
334  CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
335
336  // Initialize the overloaded operator names.
337  CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
338  for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
339    CXXOperatorNames[Op].ExtraKindOrNumArgs
340      = Op + DeclarationNameExtra::CXXConversionFunction;
341    CXXOperatorNames[Op].FETokenInfo = 0;
342  }
343}
344
345DeclarationNameTable::~DeclarationNameTable() {
346  llvm::FoldingSet<CXXSpecialName> *SpecialNames =
347    static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
348  llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
349    = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
350        (CXXLiteralOperatorNames);
351
352  delete SpecialNames;
353  delete LiteralNames;
354}
355
356DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
357  return getCXXSpecialName(DeclarationName::CXXConstructorName,
358                           Ty.getUnqualifiedType());
359}
360
361DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
362  return getCXXSpecialName(DeclarationName::CXXDestructorName,
363                           Ty.getUnqualifiedType());
364}
365
366DeclarationName
367DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
368  return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty);
369}
370
371DeclarationName
372DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
373                                        CanQualType Ty) {
374  assert(Kind >= DeclarationName::CXXConstructorName &&
375         Kind <= DeclarationName::CXXConversionFunctionName &&
376         "Kind must be a C++ special name kind");
377  llvm::FoldingSet<CXXSpecialName> *SpecialNames
378    = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
379
380  DeclarationNameExtra::ExtraKind EKind;
381  switch (Kind) {
382  case DeclarationName::CXXConstructorName:
383    EKind = DeclarationNameExtra::CXXConstructor;
384    assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
385    break;
386  case DeclarationName::CXXDestructorName:
387    EKind = DeclarationNameExtra::CXXDestructor;
388    assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
389    break;
390  case DeclarationName::CXXConversionFunctionName:
391    EKind = DeclarationNameExtra::CXXConversionFunction;
392    break;
393  default:
394    return DeclarationName();
395  }
396
397  // Unique selector, to guarantee there is one per name.
398  llvm::FoldingSetNodeID ID;
399  ID.AddInteger(EKind);
400  ID.AddPointer(Ty.getAsOpaquePtr());
401
402  void *InsertPos = 0;
403  if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
404    return DeclarationName(Name);
405
406  CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
407  SpecialName->ExtraKindOrNumArgs = EKind;
408  SpecialName->Type = Ty;
409  SpecialName->FETokenInfo = 0;
410
411  SpecialNames->InsertNode(SpecialName, InsertPos);
412  return DeclarationName(SpecialName);
413}
414
415DeclarationName
416DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
417  return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
418}
419
420DeclarationName
421DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
422  llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
423    = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
424                                                      (CXXLiteralOperatorNames);
425
426  llvm::FoldingSetNodeID ID;
427  ID.AddPointer(II);
428
429  void *InsertPos = 0;
430  if (CXXLiteralOperatorIdName *Name =
431                               LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
432    return DeclarationName (Name);
433
434  CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
435  LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
436  LiteralName->ID = II;
437  LiteralName->FETokenInfo = 0;
438
439  LiteralNames->InsertNode(LiteralName, InsertPos);
440  return DeclarationName(LiteralName);
441}
442
443DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
444  switch (Name.getNameKind()) {
445  case DeclarationName::Identifier:
446    break;
447  case DeclarationName::CXXConstructorName:
448  case DeclarationName::CXXDestructorName:
449  case DeclarationName::CXXConversionFunctionName:
450    NamedType.TInfo = 0;
451    break;
452  case DeclarationName::CXXOperatorName:
453    CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
454    CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
455    break;
456  case DeclarationName::CXXLiteralOperatorName:
457    CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
458    break;
459  case DeclarationName::ObjCZeroArgSelector:
460  case DeclarationName::ObjCOneArgSelector:
461  case DeclarationName::ObjCMultiArgSelector:
462    // FIXME: ?
463    break;
464  case DeclarationName::CXXUsingDirective:
465    break;
466  }
467}
468
469bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
470  switch (Name.getNameKind()) {
471  case DeclarationName::Identifier:
472  case DeclarationName::ObjCZeroArgSelector:
473  case DeclarationName::ObjCOneArgSelector:
474  case DeclarationName::ObjCMultiArgSelector:
475  case DeclarationName::CXXOperatorName:
476  case DeclarationName::CXXLiteralOperatorName:
477  case DeclarationName::CXXUsingDirective:
478    return false;
479
480  case DeclarationName::CXXConstructorName:
481  case DeclarationName::CXXDestructorName:
482  case DeclarationName::CXXConversionFunctionName:
483    if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
484      return TInfo->getType()->containsUnexpandedParameterPack();
485
486    return Name.getCXXNameType()->containsUnexpandedParameterPack();
487  }
488  llvm_unreachable("All name kinds handled.");
489}
490
491bool DeclarationNameInfo::isInstantiationDependent() const {
492  switch (Name.getNameKind()) {
493  case DeclarationName::Identifier:
494  case DeclarationName::ObjCZeroArgSelector:
495  case DeclarationName::ObjCOneArgSelector:
496  case DeclarationName::ObjCMultiArgSelector:
497  case DeclarationName::CXXOperatorName:
498  case DeclarationName::CXXLiteralOperatorName:
499  case DeclarationName::CXXUsingDirective:
500    return false;
501
502  case DeclarationName::CXXConstructorName:
503  case DeclarationName::CXXDestructorName:
504  case DeclarationName::CXXConversionFunctionName:
505    if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
506      return TInfo->getType()->isInstantiationDependentType();
507
508    return Name.getCXXNameType()->isInstantiationDependentType();
509  }
510  llvm_unreachable("All name kinds handled.");
511}
512
513std::string DeclarationNameInfo::getAsString() const {
514  std::string Result;
515  llvm::raw_string_ostream OS(Result);
516  printName(OS);
517  return OS.str();
518}
519
520void DeclarationNameInfo::printName(raw_ostream &OS) const {
521  switch (Name.getNameKind()) {
522  case DeclarationName::Identifier:
523  case DeclarationName::ObjCZeroArgSelector:
524  case DeclarationName::ObjCOneArgSelector:
525  case DeclarationName::ObjCMultiArgSelector:
526  case DeclarationName::CXXOperatorName:
527  case DeclarationName::CXXLiteralOperatorName:
528  case DeclarationName::CXXUsingDirective:
529    OS << Name;
530    return;
531
532  case DeclarationName::CXXConstructorName:
533  case DeclarationName::CXXDestructorName:
534  case DeclarationName::CXXConversionFunctionName:
535    if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
536      if (Name.getNameKind() == DeclarationName::CXXDestructorName)
537        OS << '~';
538      else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
539        OS << "operator ";
540      OS << TInfo->getType().getAsString();
541    } else
542      OS << Name;
543    return;
544  }
545  llvm_unreachable("Unexpected declaration name kind");
546}
547
548SourceLocation DeclarationNameInfo::getEndLoc() const {
549  switch (Name.getNameKind()) {
550  case DeclarationName::Identifier:
551    return NameLoc;
552
553  case DeclarationName::CXXOperatorName: {
554    unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
555    return SourceLocation::getFromRawEncoding(raw);
556  }
557
558  case DeclarationName::CXXLiteralOperatorName: {
559    unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
560    return SourceLocation::getFromRawEncoding(raw);
561  }
562
563  case DeclarationName::CXXConstructorName:
564  case DeclarationName::CXXDestructorName:
565  case DeclarationName::CXXConversionFunctionName:
566    if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
567      return TInfo->getTypeLoc().getEndLoc();
568    else
569      return NameLoc;
570
571    // DNInfo work in progress: FIXME.
572  case DeclarationName::ObjCZeroArgSelector:
573  case DeclarationName::ObjCOneArgSelector:
574  case DeclarationName::ObjCMultiArgSelector:
575  case DeclarationName::CXXUsingDirective:
576    return NameLoc;
577  }
578  llvm_unreachable("Unexpected declaration name kind");
579}
580