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