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