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