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    N.getObjCSelector().print(OS);
147    return OS;
148
149  case DeclarationName::CXXConstructorName: {
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
158  case DeclarationName::CXXDestructorName: {
159    OS << '~';
160    QualType Type = N.getCXXNameType();
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
168  case DeclarationName::CXXOperatorName: {
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
184  case DeclarationName::CXXLiteralOperatorName:
185    return OS << "operator \"\" " << N.getCXXLiteralIdentifier()->getName();
186
187  case DeclarationName::CXXConversionFunctionName: {
188    OS << "operator ";
189    QualType Type = N.getCXXNameType();
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  }
197  case DeclarationName::CXXUsingDirective:
198    return OS << "<using-directive>";
199  }
200
201  llvm_unreachable("Unexpected declaration name kind");
202}
203
204} // end namespace clang
205
206DeclarationName::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) {
214    case DeclarationNameExtra::CXXConstructor:
215      return CXXConstructorName;
216
217    case DeclarationNameExtra::CXXDestructor:
218      return CXXDestructorName;
219
220    case DeclarationNameExtra::CXXConversionFunction:
221      return CXXConversionFunctionName;
222
223    case DeclarationNameExtra::CXXLiteralOperator:
224      return CXXLiteralOperatorName;
225
226    case DeclarationNameExtra::CXXUsingDirective:
227      return CXXUsingDirective;
228
229    default:
230      // Check if we have one of the CXXOperator* enumeration values.
231      if (getExtra()->ExtraKindOrNumArgs <
232            DeclarationNameExtra::CXXUsingDirective)
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
243bool DeclarationName::isDependentName() const {
244  QualType T = getCXXNameType();
245  return !T.isNull() && T->isDependentType();
246}
247
248std::string DeclarationName::getAsString() const {
249  std::string Result;
250  llvm::raw_string_ostream OS(Result);
251  OS << *this;
252  return OS.str();
253}
254
255QualType DeclarationName::getCXXNameType() const {
256  if (CXXSpecialName *CXXName = getAsCXXSpecialName())
257    return CXXName->Type;
258  else
259    return QualType();
260}
261
262OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
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
272IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
273  if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
274    return CXXLit->ID;
275  else
276    return nullptr;
277}
278
279void *DeclarationName::getFETokenInfoAsVoidSlow() const {
280  switch (getNameKind()) {
281  case Identifier:
282    llvm_unreachable("Handled by getFETokenInfo()");
283
284  case CXXConstructorName:
285  case CXXDestructorName:
286  case CXXConversionFunctionName:
287    return getAsCXXSpecialName()->FETokenInfo;
288
289  case CXXOperatorName:
290    return getAsCXXOperatorIdName()->FETokenInfo;
291
292  case CXXLiteralOperatorName:
293    return getAsCXXLiteralOperatorIdName()->FETokenInfo;
294
295  default:
296    llvm_unreachable("Declaration name has no FETokenInfo");
297  }
298}
299
300void DeclarationName::setFETokenInfo(void *T) {
301  switch (getNameKind()) {
302  case Identifier:
303    getAsIdentifierInfo()->setFETokenInfo(T);
304    break;
305
306  case CXXConstructorName:
307  case CXXDestructorName:
308  case CXXConversionFunctionName:
309    getAsCXXSpecialName()->FETokenInfo = T;
310    break;
311
312  case CXXOperatorName:
313    getAsCXXOperatorIdName()->FETokenInfo = T;
314    break;
315
316  case CXXLiteralOperatorName:
317    getAsCXXLiteralOperatorIdName()->FETokenInfo = T;
318    break;
319
320  default:
321    llvm_unreachable("Declaration name has no FETokenInfo");
322  }
323}
324
325DeclarationName DeclarationName::getUsingDirectiveName() {
326  // Single instance of DeclarationNameExtra for using-directive
327  static const DeclarationNameExtra UDirExtra =
328    { DeclarationNameExtra::CXXUsingDirective };
329
330  uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
331  Ptr |= StoredDeclarationNameExtra;
332
333  return DeclarationName(Ptr);
334}
335
336void DeclarationName::dump() const {
337  llvm::errs() << *this << '\n';
338}
339
340DeclarationNameTable::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
348      = Op + DeclarationNameExtra::CXXConversionFunction;
349    CXXOperatorNames[Op].FETokenInfo = nullptr;
350  }
351}
352
353DeclarationNameTable::~DeclarationNameTable() {
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
364DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
365  return getCXXSpecialName(DeclarationName::CXXConstructorName,
366                           Ty.getUnqualifiedType());
367}
368
369DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
370  return getCXXSpecialName(DeclarationName::CXXDestructorName,
371                           Ty.getUnqualifiedType());
372}
373
374DeclarationName
375DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
376  return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty);
377}
378
379DeclarationName
380DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
381                                        CanQualType Ty) {
382  assert(Kind >= DeclarationName::CXXConstructorName &&
383         Kind <= DeclarationName::CXXConversionFunctionName &&
384         "Kind must be a C++ special name kind");
385  llvm::FoldingSet<CXXSpecialName> *SpecialNames
386    = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
387
388  DeclarationNameExtra::ExtraKind EKind;
389  switch (Kind) {
390  case DeclarationName::CXXConstructorName:
391    EKind = DeclarationNameExtra::CXXConstructor;
392    assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
393    break;
394  case DeclarationName::CXXDestructorName:
395    EKind = DeclarationNameExtra::CXXDestructor;
396    assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
397    break;
398  case DeclarationName::CXXConversionFunctionName:
399    EKind = DeclarationNameExtra::CXXConversionFunction;
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
423DeclarationName
424DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
425  return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
426}
427
428DeclarationName
429DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
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;
443  LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
444  LiteralName->ID = II;
445  LiteralName->FETokenInfo = nullptr;
446
447  LiteralNames->InsertNode(LiteralName, InsertPos);
448  return DeclarationName(LiteralName);
449}
450
451DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
452  switch (Name.getNameKind()) {
453  case DeclarationName::Identifier:
454    break;
455  case DeclarationName::CXXConstructorName:
456  case DeclarationName::CXXDestructorName:
457  case DeclarationName::CXXConversionFunctionName:
458    NamedType.TInfo = nullptr;
459    break;
460  case DeclarationName::CXXOperatorName:
461    CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
462    CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
463    break;
464  case DeclarationName::CXXLiteralOperatorName:
465    CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
466    break;
467  case DeclarationName::ObjCZeroArgSelector:
468  case DeclarationName::ObjCOneArgSelector:
469  case DeclarationName::ObjCMultiArgSelector:
470    // FIXME: ?
471    break;
472  case DeclarationName::CXXUsingDirective:
473    break;
474  }
475}
476
477bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
478  switch (Name.getNameKind()) {
479  case DeclarationName::Identifier:
480  case DeclarationName::ObjCZeroArgSelector:
481  case DeclarationName::ObjCOneArgSelector:
482  case DeclarationName::ObjCMultiArgSelector:
483  case DeclarationName::CXXOperatorName:
484  case DeclarationName::CXXLiteralOperatorName:
485  case DeclarationName::CXXUsingDirective:
486    return false;
487
488  case DeclarationName::CXXConstructorName:
489  case DeclarationName::CXXDestructorName:
490  case DeclarationName::CXXConversionFunctionName:
491    if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
492      return TInfo->getType()->containsUnexpandedParameterPack();
493
494    return Name.getCXXNameType()->containsUnexpandedParameterPack();
495  }
496  llvm_unreachable("All name kinds handled.");
497}
498
499bool DeclarationNameInfo::isInstantiationDependent() const {
500  switch (Name.getNameKind()) {
501  case DeclarationName::Identifier:
502  case DeclarationName::ObjCZeroArgSelector:
503  case DeclarationName::ObjCOneArgSelector:
504  case DeclarationName::ObjCMultiArgSelector:
505  case DeclarationName::CXXOperatorName:
506  case DeclarationName::CXXLiteralOperatorName:
507  case DeclarationName::CXXUsingDirective:
508    return false;
509
510  case DeclarationName::CXXConstructorName:
511  case DeclarationName::CXXDestructorName:
512  case DeclarationName::CXXConversionFunctionName:
513    if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
514      return TInfo->getType()->isInstantiationDependentType();
515
516    return Name.getCXXNameType()->isInstantiationDependentType();
517  }
518  llvm_unreachable("All name kinds handled.");
519}
520
521std::string DeclarationNameInfo::getAsString() const {
522  std::string Result;
523  llvm::raw_string_ostream OS(Result);
524  printName(OS);
525  return OS.str();
526}
527
528void DeclarationNameInfo::printName(raw_ostream &OS) const {
529  switch (Name.getNameKind()) {
530  case DeclarationName::Identifier:
531  case DeclarationName::ObjCZeroArgSelector:
532  case DeclarationName::ObjCOneArgSelector:
533  case DeclarationName::ObjCMultiArgSelector:
534  case DeclarationName::CXXOperatorName:
535  case DeclarationName::CXXLiteralOperatorName:
536  case DeclarationName::CXXUsingDirective:
537    OS << Name;
538    return;
539
540  case DeclarationName::CXXConstructorName:
541  case DeclarationName::CXXDestructorName:
542  case DeclarationName::CXXConversionFunctionName:
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
559SourceLocation DeclarationNameInfo::getEndLoc() const {
560  switch (Name.getNameKind()) {
561  case DeclarationName::Identifier:
562    return NameLoc;
563
564  case DeclarationName::CXXOperatorName: {
565    unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
566    return SourceLocation::getFromRawEncoding(raw);
567  }
568
569  case DeclarationName::CXXLiteralOperatorName: {
570    unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
571    return SourceLocation::getFromRawEncoding(raw);
572  }
573
574  case DeclarationName::CXXConstructorName:
575  case DeclarationName::CXXDestructorName:
576  case DeclarationName::CXXConversionFunctionName:
577    if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
578      return TInfo->getTypeLoc().getEndLoc();
579    else
580      return NameLoc;
581
582    // DNInfo work in progress: FIXME.
583  case DeclarationName::ObjCZeroArgSelector:
584  case DeclarationName::ObjCOneArgSelector:
585  case DeclarationName::ObjCMultiArgSelector:
586  case DeclarationName::CXXUsingDirective:
587    return NameLoc;
588  }
589  llvm_unreachable("Unexpected declaration name kind");
590}
591