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