1 //===- DeclarationName.cpp - Declaration names implementation -------------===//
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 
15 #include "clang/AST/DeclarationName.h"
16 #include "clang/AST/ASTContext.h"
17 #include "clang/AST/Decl.h"
18 #include "clang/AST/DeclBase.h"
19 #include "clang/AST/DeclCXX.h"
20 #include "clang/AST/DeclTemplate.h"
21 #include "clang/AST/PrettyPrinter.h"
22 #include "clang/AST/Type.h"
23 #include "clang/AST/TypeLoc.h"
24 #include "clang/AST/TypeOrdering.h"
25 #include "clang/Basic/IdentifierTable.h"
26 #include "clang/Basic/LLVM.h"
27 #include "clang/Basic/LangOptions.h"
28 #include "clang/Basic/OperatorKinds.h"
29 #include "clang/Basic/SourceLocation.h"
30 #include "llvm/ADT/FoldingSet.h"
31 #include "llvm/Support/Casting.h"
32 #include "llvm/Support/Compiler.h"
33 #include "llvm/Support/ErrorHandling.h"
34 #include "llvm/Support/raw_ostream.h"
35 #include <algorithm>
36 #include <cassert>
37 #include <cstdint>
38 #include <string>
39 
40 using namespace clang;
41 
compareInt(unsigned A,unsigned B)42 static int compareInt(unsigned A, unsigned B) {
43   return (A < B ? -1 : (A > B ? 1 : 0));
44 }
45 
compare(DeclarationName LHS,DeclarationName RHS)46 int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
47   if (LHS.getNameKind() != RHS.getNameKind())
48     return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
49 
50   switch (LHS.getNameKind()) {
51   case DeclarationName::Identifier: {
52     IdentifierInfo *LII = LHS.castAsIdentifierInfo();
53     IdentifierInfo *RII = RHS.castAsIdentifierInfo();
54     if (!LII)
55       return RII ? -1 : 0;
56     if (!RII)
57       return 1;
58 
59     return LII->getName().compare(RII->getName());
60   }
61 
62   case DeclarationName::ObjCZeroArgSelector:
63   case DeclarationName::ObjCOneArgSelector:
64   case DeclarationName::ObjCMultiArgSelector: {
65     Selector LHSSelector = LHS.getObjCSelector();
66     Selector RHSSelector = RHS.getObjCSelector();
67     // getNumArgs for ZeroArgSelector returns 0, but we still need to compare.
68     if (LHS.getNameKind() == DeclarationName::ObjCZeroArgSelector &&
69         RHS.getNameKind() == DeclarationName::ObjCZeroArgSelector) {
70       return LHSSelector.getAsIdentifierInfo()->getName().compare(
71           RHSSelector.getAsIdentifierInfo()->getName());
72     }
73     unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
74     for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
75       switch (LHSSelector.getNameForSlot(I).compare(
76           RHSSelector.getNameForSlot(I))) {
77       case -1:
78         return -1;
79       case 1:
80         return 1;
81       default:
82         break;
83       }
84     }
85 
86     return compareInt(LN, RN);
87   }
88 
89   case DeclarationName::CXXConstructorName:
90   case DeclarationName::CXXDestructorName:
91   case DeclarationName::CXXConversionFunctionName:
92     if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
93       return -1;
94     if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
95       return 1;
96     return 0;
97 
98   case DeclarationName::CXXDeductionGuideName:
99     // We never want to compare deduction guide names for templates from
100     // different scopes, so just compare the template-name.
101     return compare(LHS.getCXXDeductionGuideTemplate()->getDeclName(),
102                    RHS.getCXXDeductionGuideTemplate()->getDeclName());
103 
104   case DeclarationName::CXXOperatorName:
105     return compareInt(LHS.getCXXOverloadedOperator(),
106                       RHS.getCXXOverloadedOperator());
107 
108   case DeclarationName::CXXLiteralOperatorName:
109     return LHS.getCXXLiteralIdentifier()->getName().compare(
110         RHS.getCXXLiteralIdentifier()->getName());
111 
112   case DeclarationName::CXXUsingDirective:
113     return 0;
114   }
115 
116   llvm_unreachable("Invalid DeclarationName Kind!");
117 }
118 
printCXXConstructorDestructorName(QualType ClassType,raw_ostream & OS,PrintingPolicy Policy)119 static void printCXXConstructorDestructorName(QualType ClassType,
120                                               raw_ostream &OS,
121                                               PrintingPolicy Policy) {
122   // We know we're printing C++ here. Ensure we print types properly.
123   Policy.adjustForCPlusPlus();
124 
125   if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) {
126     OS << *ClassRec->getDecl();
127     return;
128   }
129   if (Policy.SuppressTemplateArgsInCXXConstructors) {
130     if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) {
131       OS << *InjTy->getDecl();
132       return;
133     }
134   }
135   ClassType.print(OS, Policy);
136 }
137 
print(raw_ostream & OS,const PrintingPolicy & Policy)138 void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) {
139   switch (getNameKind()) {
140   case DeclarationName::Identifier:
141     if (const IdentifierInfo *II = getAsIdentifierInfo())
142       OS << II->getName();
143     return;
144 
145   case DeclarationName::ObjCZeroArgSelector:
146   case DeclarationName::ObjCOneArgSelector:
147   case DeclarationName::ObjCMultiArgSelector:
148     getObjCSelector().print(OS);
149     return;
150 
151   case DeclarationName::CXXConstructorName:
152     return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy);
153 
154   case DeclarationName::CXXDestructorName:
155     OS << '~';
156     return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy);
157 
158   case DeclarationName::CXXDeductionGuideName:
159     OS << "<deduction guide for ";
160     getCXXDeductionGuideTemplate()->getDeclName().print(OS, Policy);
161     OS << '>';
162     return;
163 
164   case DeclarationName::CXXOperatorName: {
165     static const char *const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
166         nullptr,
167 #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly)  \
168   Spelling,
169 #include "clang/Basic/OperatorKinds.def"
170     };
171     const char *OpName = OperatorNames[getCXXOverloadedOperator()];
172     assert(OpName && "not an overloaded operator");
173 
174     OS << "operator";
175     if (OpName[0] >= 'a' && OpName[0] <= 'z')
176       OS << ' ';
177     OS << OpName;
178     return;
179   }
180 
181   case DeclarationName::CXXLiteralOperatorName:
182     OS << "operator\"\"" << getCXXLiteralIdentifier()->getName();
183     return;
184 
185   case DeclarationName::CXXConversionFunctionName: {
186     OS << "operator ";
187     QualType Type = getCXXNameType();
188     if (const RecordType *Rec = Type->getAs<RecordType>()) {
189       OS << *Rec->getDecl();
190       return;
191     }
192     // We know we're printing C++ here, ensure we print 'bool' properly.
193     PrintingPolicy CXXPolicy = Policy;
194     CXXPolicy.adjustForCPlusPlus();
195     Type.print(OS, CXXPolicy);
196     return;
197   }
198   case DeclarationName::CXXUsingDirective:
199     OS << "<using-directive>";
200     return;
201   }
202 
203   llvm_unreachable("Unexpected declaration name kind");
204 }
205 
206 namespace clang {
207 
operator <<(raw_ostream & OS,DeclarationName N)208 raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
209   LangOptions LO;
210   N.print(OS, PrintingPolicy(LO));
211   return OS;
212 }
213 
214 } // namespace clang
215 
isDependentName() const216 bool DeclarationName::isDependentName() const {
217   QualType T = getCXXNameType();
218   if (!T.isNull() && T->isDependentType())
219     return true;
220 
221   // A class-scope deduction guide in a dependent context has a dependent name.
222   auto *TD = getCXXDeductionGuideTemplate();
223   if (TD && TD->getDeclContext()->isDependentContext())
224     return true;
225 
226   return false;
227 }
228 
getAsString() const229 std::string DeclarationName::getAsString() const {
230   std::string Result;
231   llvm::raw_string_ostream OS(Result);
232   OS << *this;
233   return OS.str();
234 }
235 
getFETokenInfoSlow() const236 void *DeclarationName::getFETokenInfoSlow() const {
237   switch (getNameKind()) {
238   case Identifier:
239     llvm_unreachable("case Identifier already handled by getFETokenInfo!");
240   case CXXConstructorName:
241   case CXXDestructorName:
242   case CXXConversionFunctionName:
243     return castAsCXXSpecialNameExtra()->FETokenInfo;
244   case CXXOperatorName:
245     return castAsCXXOperatorIdName()->FETokenInfo;
246   case CXXDeductionGuideName:
247     return castAsCXXDeductionGuideNameExtra()->FETokenInfo;
248   case CXXLiteralOperatorName:
249     return castAsCXXLiteralOperatorIdName()->FETokenInfo;
250   default:
251     llvm_unreachable("DeclarationName has no FETokenInfo!");
252   }
253 }
254 
setFETokenInfoSlow(void * T)255 void DeclarationName::setFETokenInfoSlow(void *T) {
256   switch (getNameKind()) {
257   case Identifier:
258     llvm_unreachable("case Identifier already handled by setFETokenInfo!");
259   case CXXConstructorName:
260   case CXXDestructorName:
261   case CXXConversionFunctionName:
262     castAsCXXSpecialNameExtra()->FETokenInfo = T;
263     break;
264   case CXXOperatorName:
265     castAsCXXOperatorIdName()->FETokenInfo = T;
266     break;
267   case CXXDeductionGuideName:
268     castAsCXXDeductionGuideNameExtra()->FETokenInfo = T;
269     break;
270   case CXXLiteralOperatorName:
271     castAsCXXLiteralOperatorIdName()->FETokenInfo = T;
272     break;
273   default:
274     llvm_unreachable("DeclarationName has no FETokenInfo!");
275   }
276 }
277 
dump() const278 LLVM_DUMP_METHOD void DeclarationName::dump() const {
279   llvm::errs() << *this << '\n';
280 }
281 
DeclarationNameTable(const ASTContext & C)282 DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
283   // Initialize the overloaded operator names.
284   for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op)
285     CXXOperatorNames[Op].Kind = static_cast<OverloadedOperatorKind>(Op);
286 }
287 
288 DeclarationName
getCXXDeductionGuideName(TemplateDecl * Template)289 DeclarationNameTable::getCXXDeductionGuideName(TemplateDecl *Template) {
290   Template = cast<TemplateDecl>(Template->getCanonicalDecl());
291 
292   llvm::FoldingSetNodeID ID;
293   ID.AddPointer(Template);
294 
295   void *InsertPos = nullptr;
296   if (auto *Name = CXXDeductionGuideNames.FindNodeOrInsertPos(ID, InsertPos))
297     return DeclarationName(Name);
298 
299   auto *Name = new (Ctx) detail::CXXDeductionGuideNameExtra(Template);
300   CXXDeductionGuideNames.InsertNode(Name, InsertPos);
301   return DeclarationName(Name);
302 }
303 
getCXXConstructorName(CanQualType Ty)304 DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
305   // The type of constructors is unqualified.
306   Ty = Ty.getUnqualifiedType();
307   // Do we already have this C++ constructor name ?
308   llvm::FoldingSetNodeID ID;
309   ID.AddPointer(Ty.getAsOpaquePtr());
310   void *InsertPos = nullptr;
311   if (auto *Name = CXXConstructorNames.FindNodeOrInsertPos(ID, InsertPos))
312     return {Name, DeclarationName::StoredCXXConstructorName};
313 
314   // We have to create it.
315   auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
316   CXXConstructorNames.InsertNode(SpecialName, InsertPos);
317   return {SpecialName, DeclarationName::StoredCXXConstructorName};
318 }
319 
getCXXDestructorName(CanQualType Ty)320 DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
321   // The type of destructors is unqualified.
322   Ty = Ty.getUnqualifiedType();
323   // Do we already have this C++ destructor name ?
324   llvm::FoldingSetNodeID ID;
325   ID.AddPointer(Ty.getAsOpaquePtr());
326   void *InsertPos = nullptr;
327   if (auto *Name = CXXDestructorNames.FindNodeOrInsertPos(ID, InsertPos))
328     return {Name, DeclarationName::StoredCXXDestructorName};
329 
330   // We have to create it.
331   auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
332   CXXDestructorNames.InsertNode(SpecialName, InsertPos);
333   return {SpecialName, DeclarationName::StoredCXXDestructorName};
334 }
335 
336 DeclarationName
getCXXConversionFunctionName(CanQualType Ty)337 DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
338   // Do we already have this C++ conversion function name ?
339   llvm::FoldingSetNodeID ID;
340   ID.AddPointer(Ty.getAsOpaquePtr());
341   void *InsertPos = nullptr;
342   if (auto *Name =
343           CXXConversionFunctionNames.FindNodeOrInsertPos(ID, InsertPos))
344     return {Name, DeclarationName::StoredCXXConversionFunctionName};
345 
346   // We have to create it.
347   auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
348   CXXConversionFunctionNames.InsertNode(SpecialName, InsertPos);
349   return {SpecialName, DeclarationName::StoredCXXConversionFunctionName};
350 }
351 
352 DeclarationName
getCXXSpecialName(DeclarationName::NameKind Kind,CanQualType Ty)353 DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
354                                         CanQualType Ty) {
355   switch (Kind) {
356   case DeclarationName::CXXConstructorName:
357     return getCXXConstructorName(Ty);
358   case DeclarationName::CXXDestructorName:
359     return getCXXDestructorName(Ty);
360   case DeclarationName::CXXConversionFunctionName:
361     return getCXXConversionFunctionName(Ty);
362   default:
363     llvm_unreachable("Invalid kind in getCXXSpecialName!");
364   }
365 }
366 
367 DeclarationName
getCXXLiteralOperatorName(IdentifierInfo * II)368 DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
369   llvm::FoldingSetNodeID ID;
370   ID.AddPointer(II);
371 
372   void *InsertPos = nullptr;
373   if (auto *Name = CXXLiteralOperatorNames.FindNodeOrInsertPos(ID, InsertPos))
374     return DeclarationName(Name);
375 
376   auto *LiteralName = new (Ctx) detail::CXXLiteralOperatorIdName(II);
377   CXXLiteralOperatorNames.InsertNode(LiteralName, InsertPos);
378   return DeclarationName(LiteralName);
379 }
380 
DeclarationNameLoc(DeclarationName Name)381 DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
382   switch (Name.getNameKind()) {
383   case DeclarationName::Identifier:
384   case DeclarationName::CXXDeductionGuideName:
385     break;
386   case DeclarationName::CXXConstructorName:
387   case DeclarationName::CXXDestructorName:
388   case DeclarationName::CXXConversionFunctionName:
389     NamedType.TInfo = nullptr;
390     break;
391   case DeclarationName::CXXOperatorName:
392     CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
393     CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
394     break;
395   case DeclarationName::CXXLiteralOperatorName:
396     CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
397     break;
398   case DeclarationName::ObjCZeroArgSelector:
399   case DeclarationName::ObjCOneArgSelector:
400   case DeclarationName::ObjCMultiArgSelector:
401     // FIXME: ?
402     break;
403   case DeclarationName::CXXUsingDirective:
404     break;
405   }
406 }
407 
containsUnexpandedParameterPack() const408 bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
409   switch (Name.getNameKind()) {
410   case DeclarationName::Identifier:
411   case DeclarationName::ObjCZeroArgSelector:
412   case DeclarationName::ObjCOneArgSelector:
413   case DeclarationName::ObjCMultiArgSelector:
414   case DeclarationName::CXXOperatorName:
415   case DeclarationName::CXXLiteralOperatorName:
416   case DeclarationName::CXXUsingDirective:
417   case DeclarationName::CXXDeductionGuideName:
418     return false;
419 
420   case DeclarationName::CXXConstructorName:
421   case DeclarationName::CXXDestructorName:
422   case DeclarationName::CXXConversionFunctionName:
423     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
424       return TInfo->getType()->containsUnexpandedParameterPack();
425 
426     return Name.getCXXNameType()->containsUnexpandedParameterPack();
427   }
428   llvm_unreachable("All name kinds handled.");
429 }
430 
isInstantiationDependent() const431 bool DeclarationNameInfo::isInstantiationDependent() const {
432   switch (Name.getNameKind()) {
433   case DeclarationName::Identifier:
434   case DeclarationName::ObjCZeroArgSelector:
435   case DeclarationName::ObjCOneArgSelector:
436   case DeclarationName::ObjCMultiArgSelector:
437   case DeclarationName::CXXOperatorName:
438   case DeclarationName::CXXLiteralOperatorName:
439   case DeclarationName::CXXUsingDirective:
440   case DeclarationName::CXXDeductionGuideName:
441     return false;
442 
443   case DeclarationName::CXXConstructorName:
444   case DeclarationName::CXXDestructorName:
445   case DeclarationName::CXXConversionFunctionName:
446     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
447       return TInfo->getType()->isInstantiationDependentType();
448 
449     return Name.getCXXNameType()->isInstantiationDependentType();
450   }
451   llvm_unreachable("All name kinds handled.");
452 }
453 
getAsString() const454 std::string DeclarationNameInfo::getAsString() const {
455   std::string Result;
456   llvm::raw_string_ostream OS(Result);
457   printName(OS);
458   return OS.str();
459 }
460 
printName(raw_ostream & OS) const461 void DeclarationNameInfo::printName(raw_ostream &OS) const {
462   switch (Name.getNameKind()) {
463   case DeclarationName::Identifier:
464   case DeclarationName::ObjCZeroArgSelector:
465   case DeclarationName::ObjCOneArgSelector:
466   case DeclarationName::ObjCMultiArgSelector:
467   case DeclarationName::CXXOperatorName:
468   case DeclarationName::CXXLiteralOperatorName:
469   case DeclarationName::CXXUsingDirective:
470   case DeclarationName::CXXDeductionGuideName:
471     OS << Name;
472     return;
473 
474   case DeclarationName::CXXConstructorName:
475   case DeclarationName::CXXDestructorName:
476   case DeclarationName::CXXConversionFunctionName:
477     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
478       if (Name.getNameKind() == DeclarationName::CXXDestructorName)
479         OS << '~';
480       else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
481         OS << "operator ";
482       LangOptions LO;
483       LO.CPlusPlus = true;
484       LO.Bool = true;
485       PrintingPolicy PP(LO);
486       PP.SuppressScope = true;
487       OS << TInfo->getType().getAsString(PP);
488     } else
489       OS << Name;
490     return;
491   }
492   llvm_unreachable("Unexpected declaration name kind");
493 }
494 
getEndLocPrivate() const495 SourceLocation DeclarationNameInfo::getEndLocPrivate() const {
496   switch (Name.getNameKind()) {
497   case DeclarationName::Identifier:
498   case DeclarationName::CXXDeductionGuideName:
499     return NameLoc;
500 
501   case DeclarationName::CXXOperatorName: {
502     unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
503     return SourceLocation::getFromRawEncoding(raw);
504   }
505 
506   case DeclarationName::CXXLiteralOperatorName: {
507     unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
508     return SourceLocation::getFromRawEncoding(raw);
509   }
510 
511   case DeclarationName::CXXConstructorName:
512   case DeclarationName::CXXDestructorName:
513   case DeclarationName::CXXConversionFunctionName:
514     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
515       return TInfo->getTypeLoc().getEndLoc();
516     else
517       return NameLoc;
518 
519     // DNInfo work in progress: FIXME.
520   case DeclarationName::ObjCZeroArgSelector:
521   case DeclarationName::ObjCOneArgSelector:
522   case DeclarationName::ObjCMultiArgSelector:
523   case DeclarationName::CXXUsingDirective:
524     return NameLoc;
525   }
526   llvm_unreachable("Unexpected declaration name kind");
527 }
528