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