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,
138                             const PrintingPolicy &Policy) const {
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     const char *OpName = getOperatorSpelling(getCXXOverloadedOperator());
166     assert(OpName && "not an overloaded operator");
167 
168     OS << "operator";
169     if (OpName[0] >= 'a' && OpName[0] <= 'z')
170       OS << ' ';
171     OS << OpName;
172     return;
173   }
174 
175   case DeclarationName::CXXLiteralOperatorName:
176     OS << "operator\"\"" << getCXXLiteralIdentifier()->getName();
177     return;
178 
179   case DeclarationName::CXXConversionFunctionName: {
180     OS << "operator ";
181     QualType Type = getCXXNameType();
182     if (const RecordType *Rec = Type->getAs<RecordType>()) {
183       OS << *Rec->getDecl();
184       return;
185     }
186     // We know we're printing C++ here, ensure we print 'bool' properly.
187     PrintingPolicy CXXPolicy = Policy;
188     CXXPolicy.adjustForCPlusPlus();
189     Type.print(OS, CXXPolicy);
190     return;
191   }
192   case DeclarationName::CXXUsingDirective:
193     OS << "<using-directive>";
194     return;
195   }
196 
197   llvm_unreachable("Unexpected declaration name kind");
198 }
199 
200 namespace clang {
201 
202 raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
203   LangOptions LO;
204   N.print(OS, PrintingPolicy(LO));
205   return OS;
206 }
207 
208 } // namespace clang
209 
210 bool DeclarationName::isDependentName() const {
211   QualType T = getCXXNameType();
212   if (!T.isNull() && T->isDependentType())
213     return true;
214 
215   // A class-scope deduction guide in a dependent context has a dependent name.
216   auto *TD = getCXXDeductionGuideTemplate();
217   if (TD && TD->getDeclContext()->isDependentContext())
218     return true;
219 
220   return false;
221 }
222 
223 std::string DeclarationName::getAsString() const {
224   std::string Result;
225   llvm::raw_string_ostream OS(Result);
226   OS << *this;
227   return OS.str();
228 }
229 
230 void *DeclarationName::getFETokenInfoSlow() const {
231   switch (getNameKind()) {
232   case Identifier:
233     llvm_unreachable("case Identifier already handled by getFETokenInfo!");
234   case CXXConstructorName:
235   case CXXDestructorName:
236   case CXXConversionFunctionName:
237     return castAsCXXSpecialNameExtra()->FETokenInfo;
238   case CXXOperatorName:
239     return castAsCXXOperatorIdName()->FETokenInfo;
240   case CXXDeductionGuideName:
241     return castAsCXXDeductionGuideNameExtra()->FETokenInfo;
242   case CXXLiteralOperatorName:
243     return castAsCXXLiteralOperatorIdName()->FETokenInfo;
244   default:
245     llvm_unreachable("DeclarationName has no FETokenInfo!");
246   }
247 }
248 
249 void DeclarationName::setFETokenInfoSlow(void *T) {
250   switch (getNameKind()) {
251   case Identifier:
252     llvm_unreachable("case Identifier already handled by setFETokenInfo!");
253   case CXXConstructorName:
254   case CXXDestructorName:
255   case CXXConversionFunctionName:
256     castAsCXXSpecialNameExtra()->FETokenInfo = T;
257     break;
258   case CXXOperatorName:
259     castAsCXXOperatorIdName()->FETokenInfo = T;
260     break;
261   case CXXDeductionGuideName:
262     castAsCXXDeductionGuideNameExtra()->FETokenInfo = T;
263     break;
264   case CXXLiteralOperatorName:
265     castAsCXXLiteralOperatorIdName()->FETokenInfo = T;
266     break;
267   default:
268     llvm_unreachable("DeclarationName has no FETokenInfo!");
269   }
270 }
271 
272 LLVM_DUMP_METHOD void DeclarationName::dump() const {
273   llvm::errs() << *this << '\n';
274 }
275 
276 DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
277   // Initialize the overloaded operator names.
278   for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op)
279     CXXOperatorNames[Op].Kind = static_cast<OverloadedOperatorKind>(Op);
280 }
281 
282 DeclarationName
283 DeclarationNameTable::getCXXDeductionGuideName(TemplateDecl *Template) {
284   Template = cast<TemplateDecl>(Template->getCanonicalDecl());
285 
286   llvm::FoldingSetNodeID ID;
287   ID.AddPointer(Template);
288 
289   void *InsertPos = nullptr;
290   if (auto *Name = CXXDeductionGuideNames.FindNodeOrInsertPos(ID, InsertPos))
291     return DeclarationName(Name);
292 
293   auto *Name = new (Ctx) detail::CXXDeductionGuideNameExtra(Template);
294   CXXDeductionGuideNames.InsertNode(Name, InsertPos);
295   return DeclarationName(Name);
296 }
297 
298 DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
299   // The type of constructors is unqualified.
300   Ty = Ty.getUnqualifiedType();
301   // Do we already have this C++ constructor name ?
302   llvm::FoldingSetNodeID ID;
303   ID.AddPointer(Ty.getAsOpaquePtr());
304   void *InsertPos = nullptr;
305   if (auto *Name = CXXConstructorNames.FindNodeOrInsertPos(ID, InsertPos))
306     return {Name, DeclarationName::StoredCXXConstructorName};
307 
308   // We have to create it.
309   auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
310   CXXConstructorNames.InsertNode(SpecialName, InsertPos);
311   return {SpecialName, DeclarationName::StoredCXXConstructorName};
312 }
313 
314 DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
315   // The type of destructors is unqualified.
316   Ty = Ty.getUnqualifiedType();
317   // Do we already have this C++ destructor name ?
318   llvm::FoldingSetNodeID ID;
319   ID.AddPointer(Ty.getAsOpaquePtr());
320   void *InsertPos = nullptr;
321   if (auto *Name = CXXDestructorNames.FindNodeOrInsertPos(ID, InsertPos))
322     return {Name, DeclarationName::StoredCXXDestructorName};
323 
324   // We have to create it.
325   auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
326   CXXDestructorNames.InsertNode(SpecialName, InsertPos);
327   return {SpecialName, DeclarationName::StoredCXXDestructorName};
328 }
329 
330 DeclarationName
331 DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
332   // Do we already have this C++ conversion function name ?
333   llvm::FoldingSetNodeID ID;
334   ID.AddPointer(Ty.getAsOpaquePtr());
335   void *InsertPos = nullptr;
336   if (auto *Name =
337           CXXConversionFunctionNames.FindNodeOrInsertPos(ID, InsertPos))
338     return {Name, DeclarationName::StoredCXXConversionFunctionName};
339 
340   // We have to create it.
341   auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
342   CXXConversionFunctionNames.InsertNode(SpecialName, InsertPos);
343   return {SpecialName, DeclarationName::StoredCXXConversionFunctionName};
344 }
345 
346 DeclarationName
347 DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
348                                         CanQualType Ty) {
349   switch (Kind) {
350   case DeclarationName::CXXConstructorName:
351     return getCXXConstructorName(Ty);
352   case DeclarationName::CXXDestructorName:
353     return getCXXDestructorName(Ty);
354   case DeclarationName::CXXConversionFunctionName:
355     return getCXXConversionFunctionName(Ty);
356   default:
357     llvm_unreachable("Invalid kind in getCXXSpecialName!");
358   }
359 }
360 
361 DeclarationName
362 DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
363   llvm::FoldingSetNodeID ID;
364   ID.AddPointer(II);
365 
366   void *InsertPos = nullptr;
367   if (auto *Name = CXXLiteralOperatorNames.FindNodeOrInsertPos(ID, InsertPos))
368     return DeclarationName(Name);
369 
370   auto *LiteralName = new (Ctx) detail::CXXLiteralOperatorIdName(II);
371   CXXLiteralOperatorNames.InsertNode(LiteralName, InsertPos);
372   return DeclarationName(LiteralName);
373 }
374 
375 DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
376   switch (Name.getNameKind()) {
377   case DeclarationName::Identifier:
378   case DeclarationName::CXXDeductionGuideName:
379     break;
380   case DeclarationName::CXXConstructorName:
381   case DeclarationName::CXXDestructorName:
382   case DeclarationName::CXXConversionFunctionName:
383     NamedType.TInfo = nullptr;
384     break;
385   case DeclarationName::CXXOperatorName:
386     CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
387     CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
388     break;
389   case DeclarationName::CXXLiteralOperatorName:
390     CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
391     break;
392   case DeclarationName::ObjCZeroArgSelector:
393   case DeclarationName::ObjCOneArgSelector:
394   case DeclarationName::ObjCMultiArgSelector:
395     // FIXME: ?
396     break;
397   case DeclarationName::CXXUsingDirective:
398     break;
399   }
400 }
401 
402 bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
403   switch (Name.getNameKind()) {
404   case DeclarationName::Identifier:
405   case DeclarationName::ObjCZeroArgSelector:
406   case DeclarationName::ObjCOneArgSelector:
407   case DeclarationName::ObjCMultiArgSelector:
408   case DeclarationName::CXXOperatorName:
409   case DeclarationName::CXXLiteralOperatorName:
410   case DeclarationName::CXXUsingDirective:
411   case DeclarationName::CXXDeductionGuideName:
412     return false;
413 
414   case DeclarationName::CXXConstructorName:
415   case DeclarationName::CXXDestructorName:
416   case DeclarationName::CXXConversionFunctionName:
417     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
418       return TInfo->getType()->containsUnexpandedParameterPack();
419 
420     return Name.getCXXNameType()->containsUnexpandedParameterPack();
421   }
422   llvm_unreachable("All name kinds handled.");
423 }
424 
425 bool DeclarationNameInfo::isInstantiationDependent() const {
426   switch (Name.getNameKind()) {
427   case DeclarationName::Identifier:
428   case DeclarationName::ObjCZeroArgSelector:
429   case DeclarationName::ObjCOneArgSelector:
430   case DeclarationName::ObjCMultiArgSelector:
431   case DeclarationName::CXXOperatorName:
432   case DeclarationName::CXXLiteralOperatorName:
433   case DeclarationName::CXXUsingDirective:
434   case DeclarationName::CXXDeductionGuideName:
435     return false;
436 
437   case DeclarationName::CXXConstructorName:
438   case DeclarationName::CXXDestructorName:
439   case DeclarationName::CXXConversionFunctionName:
440     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
441       return TInfo->getType()->isInstantiationDependentType();
442 
443     return Name.getCXXNameType()->isInstantiationDependentType();
444   }
445   llvm_unreachable("All name kinds handled.");
446 }
447 
448 std::string DeclarationNameInfo::getAsString() const {
449   std::string Result;
450   llvm::raw_string_ostream OS(Result);
451   OS << *this;
452   return OS.str();
453 }
454 
455 raw_ostream &clang::operator<<(raw_ostream &OS, DeclarationNameInfo DNInfo) {
456   LangOptions LO;
457   DNInfo.printName(OS, PrintingPolicy(LangOptions()));
458   return OS;
459 }
460 
461 void DeclarationNameInfo::printName(raw_ostream &OS, PrintingPolicy Policy) 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     Name.print(OS, Policy);
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       Policy.adjustForCPlusPlus();
484       Policy.SuppressScope = true;
485       OS << TInfo->getType().getAsString(Policy);
486     } else
487       Name.print(OS, Policy);
488     return;
489   }
490   llvm_unreachable("Unexpected declaration name kind");
491 }
492 
493 SourceLocation DeclarationNameInfo::getEndLocPrivate() const {
494   switch (Name.getNameKind()) {
495   case DeclarationName::Identifier:
496   case DeclarationName::CXXDeductionGuideName:
497     return NameLoc;
498 
499   case DeclarationName::CXXOperatorName: {
500     unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
501     return SourceLocation::getFromRawEncoding(raw);
502   }
503 
504   case DeclarationName::CXXLiteralOperatorName: {
505     unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
506     return SourceLocation::getFromRawEncoding(raw);
507   }
508 
509   case DeclarationName::CXXConstructorName:
510   case DeclarationName::CXXDestructorName:
511   case DeclarationName::CXXConversionFunctionName:
512     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
513       return TInfo->getTypeLoc().getEndLoc();
514     else
515       return NameLoc;
516 
517     // DNInfo work in progress: FIXME.
518   case DeclarationName::ObjCZeroArgSelector:
519   case DeclarationName::ObjCOneArgSelector:
520   case DeclarationName::ObjCMultiArgSelector:
521   case DeclarationName::CXXUsingDirective:
522     return NameLoc;
523   }
524   llvm_unreachable("Unexpected declaration name kind");
525 }
526