• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Profile(llvm::FoldingSetNodeID & ID)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 
Profile(llvm::FoldingSetNodeID & FSID)71   void Profile(llvm::FoldingSetNodeID &FSID) {
72     FSID.AddPointer(ID);
73   }
74 };
75 
compareInt(unsigned A,unsigned B)76 static int compareInt(unsigned A, unsigned B) {
77   return (A < B ? -1 : (A > B ? 1 : 0));
78 }
79 
compare(DeclarationName LHS,DeclarationName RHS)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 } // end namespace clang
137 
getNameKind() const138 DeclarationName::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 
isDependentName() const175 bool DeclarationName::isDependentName() const {
176   QualType T = getCXXNameType();
177   return !T.isNull() && T->isDependentType();
178 }
179 
getAsString() const180 std::string DeclarationName::getAsString() const {
181   std::string Result;
182   llvm::raw_string_ostream OS(Result);
183   printName(OS);
184   return OS.str();
185 }
186 
printName(raw_ostream & OS) const187 void 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 
getCXXNameType() const257 QualType DeclarationName::getCXXNameType() const {
258   if (CXXSpecialName *CXXName = getAsCXXSpecialName())
259     return CXXName->Type;
260   else
261     return QualType();
262 }
263 
getCXXOverloadedOperator() const264 OverloadedOperatorKind 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 
getCXXLiteralIdentifier() const274 IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
275   if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
276     return CXXLit->ID;
277   else
278     return 0;
279 }
280 
getFETokenInfoAsVoidSlow() const281 void *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 
setFETokenInfo(void * T)302 void 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 
getUsingDirectiveName()327 DeclarationName 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 
dump() const338 void DeclarationName::dump() const {
339   printName(llvm::errs());
340   llvm::errs() << '\n';
341 }
342 
DeclarationNameTable(const ASTContext & C)343 DeclarationNameTable::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 
~DeclarationNameTable()356 DeclarationNameTable::~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 
367 DeclarationName
getCXXSpecialName(DeclarationName::NameKind Kind,CanQualType Ty)368 DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
369                                         CanQualType Ty) {
370   assert(Kind >= DeclarationName::CXXConstructorName &&
371          Kind <= DeclarationName::CXXConversionFunctionName &&
372          "Kind must be a C++ special name kind");
373   llvm::FoldingSet<CXXSpecialName> *SpecialNames
374     = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
375 
376   DeclarationNameExtra::ExtraKind EKind;
377   switch (Kind) {
378   case DeclarationName::CXXConstructorName:
379     EKind = DeclarationNameExtra::CXXConstructor;
380     assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
381     break;
382   case DeclarationName::CXXDestructorName:
383     EKind = DeclarationNameExtra::CXXDestructor;
384     assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
385     break;
386   case DeclarationName::CXXConversionFunctionName:
387     EKind = DeclarationNameExtra::CXXConversionFunction;
388     break;
389   default:
390     return DeclarationName();
391   }
392 
393   // Unique selector, to guarantee there is one per name.
394   llvm::FoldingSetNodeID ID;
395   ID.AddInteger(EKind);
396   ID.AddPointer(Ty.getAsOpaquePtr());
397 
398   void *InsertPos = 0;
399   if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
400     return DeclarationName(Name);
401 
402   CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
403   SpecialName->ExtraKindOrNumArgs = EKind;
404   SpecialName->Type = Ty;
405   SpecialName->FETokenInfo = 0;
406 
407   SpecialNames->InsertNode(SpecialName, InsertPos);
408   return DeclarationName(SpecialName);
409 }
410 
411 DeclarationName
getCXXOperatorName(OverloadedOperatorKind Op)412 DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
413   return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
414 }
415 
416 DeclarationName
getCXXLiteralOperatorName(IdentifierInfo * II)417 DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
418   llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
419     = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
420                                                       (CXXLiteralOperatorNames);
421 
422   llvm::FoldingSetNodeID ID;
423   ID.AddPointer(II);
424 
425   void *InsertPos = 0;
426   if (CXXLiteralOperatorIdName *Name =
427                                LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
428     return DeclarationName (Name);
429 
430   CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
431   LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
432   LiteralName->ID = II;
433   LiteralName->FETokenInfo = 0;
434 
435   LiteralNames->InsertNode(LiteralName, InsertPos);
436   return DeclarationName(LiteralName);
437 }
438 
DeclarationNameLoc(DeclarationName Name)439 DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
440   switch (Name.getNameKind()) {
441   case DeclarationName::Identifier:
442     break;
443   case DeclarationName::CXXConstructorName:
444   case DeclarationName::CXXDestructorName:
445   case DeclarationName::CXXConversionFunctionName:
446     NamedType.TInfo = 0;
447     break;
448   case DeclarationName::CXXOperatorName:
449     CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
450     CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
451     break;
452   case DeclarationName::CXXLiteralOperatorName:
453     CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
454     break;
455   case DeclarationName::ObjCZeroArgSelector:
456   case DeclarationName::ObjCOneArgSelector:
457   case DeclarationName::ObjCMultiArgSelector:
458     // FIXME: ?
459     break;
460   case DeclarationName::CXXUsingDirective:
461     break;
462   }
463 }
464 
containsUnexpandedParameterPack() const465 bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
466   switch (Name.getNameKind()) {
467   case DeclarationName::Identifier:
468   case DeclarationName::ObjCZeroArgSelector:
469   case DeclarationName::ObjCOneArgSelector:
470   case DeclarationName::ObjCMultiArgSelector:
471   case DeclarationName::CXXOperatorName:
472   case DeclarationName::CXXLiteralOperatorName:
473   case DeclarationName::CXXUsingDirective:
474     return false;
475 
476   case DeclarationName::CXXConstructorName:
477   case DeclarationName::CXXDestructorName:
478   case DeclarationName::CXXConversionFunctionName:
479     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
480       return TInfo->getType()->containsUnexpandedParameterPack();
481 
482     return Name.getCXXNameType()->containsUnexpandedParameterPack();
483   }
484   llvm_unreachable("All name kinds handled.");
485 }
486 
isInstantiationDependent() const487 bool DeclarationNameInfo::isInstantiationDependent() const {
488   switch (Name.getNameKind()) {
489   case DeclarationName::Identifier:
490   case DeclarationName::ObjCZeroArgSelector:
491   case DeclarationName::ObjCOneArgSelector:
492   case DeclarationName::ObjCMultiArgSelector:
493   case DeclarationName::CXXOperatorName:
494   case DeclarationName::CXXLiteralOperatorName:
495   case DeclarationName::CXXUsingDirective:
496     return false;
497 
498   case DeclarationName::CXXConstructorName:
499   case DeclarationName::CXXDestructorName:
500   case DeclarationName::CXXConversionFunctionName:
501     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
502       return TInfo->getType()->isInstantiationDependentType();
503 
504     return Name.getCXXNameType()->isInstantiationDependentType();
505   }
506   llvm_unreachable("All name kinds handled.");
507 }
508 
getAsString() const509 std::string DeclarationNameInfo::getAsString() const {
510   std::string Result;
511   llvm::raw_string_ostream OS(Result);
512   printName(OS);
513   return OS.str();
514 }
515 
printName(raw_ostream & OS) const516 void DeclarationNameInfo::printName(raw_ostream &OS) const {
517   switch (Name.getNameKind()) {
518   case DeclarationName::Identifier:
519   case DeclarationName::ObjCZeroArgSelector:
520   case DeclarationName::ObjCOneArgSelector:
521   case DeclarationName::ObjCMultiArgSelector:
522   case DeclarationName::CXXOperatorName:
523   case DeclarationName::CXXLiteralOperatorName:
524   case DeclarationName::CXXUsingDirective:
525     Name.printName(OS);
526     return;
527 
528   case DeclarationName::CXXConstructorName:
529   case DeclarationName::CXXDestructorName:
530   case DeclarationName::CXXConversionFunctionName:
531     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
532       if (Name.getNameKind() == DeclarationName::CXXDestructorName)
533         OS << '~';
534       else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
535         OS << "operator ";
536       OS << TInfo->getType().getAsString();
537     }
538     else
539       Name.printName(OS);
540     return;
541   }
542   llvm_unreachable("Unexpected declaration name kind");
543 }
544 
getEndLoc() const545 SourceLocation DeclarationNameInfo::getEndLoc() const {
546   switch (Name.getNameKind()) {
547   case DeclarationName::Identifier:
548     return NameLoc;
549 
550   case DeclarationName::CXXOperatorName: {
551     unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
552     return SourceLocation::getFromRawEncoding(raw);
553   }
554 
555   case DeclarationName::CXXLiteralOperatorName: {
556     unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
557     return SourceLocation::getFromRawEncoding(raw);
558   }
559 
560   case DeclarationName::CXXConstructorName:
561   case DeclarationName::CXXDestructorName:
562   case DeclarationName::CXXConversionFunctionName:
563     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
564       return TInfo->getTypeLoc().getEndLoc();
565     else
566       return NameLoc;
567 
568     // DNInfo work in progress: FIXME.
569   case DeclarationName::ObjCZeroArgSelector:
570   case DeclarationName::ObjCOneArgSelector:
571   case DeclarationName::ObjCMultiArgSelector:
572   case DeclarationName::CXXUsingDirective:
573     return NameLoc;
574   }
575   llvm_unreachable("Unexpected declaration name kind");
576 }
577