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