[docs] Fix build-docs.sh
[llvm-project.git] / clang / lib / AST / DeclarationName.cpp
blobb2232ddfced327924fbb4484c1697d0de5a12e98
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.
12 //===----------------------------------------------------------------------===//
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/OpenMPClause.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>
40 using namespace clang;
42 static int compareInt(unsigned A, unsigned B) {
43 return (A < B ? -1 : (A > B ? 1 : 0));
46 int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
47 if (LHS.getNameKind() != RHS.getNameKind())
48 return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
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;
59 return LII->getName().compare(RII->getName());
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());
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;
86 return compareInt(LN, RN);
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;
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());
104 case DeclarationName::CXXOperatorName:
105 return compareInt(LHS.getCXXOverloadedOperator(),
106 RHS.getCXXOverloadedOperator());
108 case DeclarationName::CXXLiteralOperatorName:
109 return LHS.getCXXLiteralIdentifier()->getName().compare(
110 RHS.getCXXLiteralIdentifier()->getName());
112 case DeclarationName::CXXUsingDirective:
113 return 0;
116 llvm_unreachable("Invalid DeclarationName Kind!");
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();
125 if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) {
126 OS << *ClassRec->getDecl();
127 return;
129 if (Policy.SuppressTemplateArgsInCXXConstructors) {
130 if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) {
131 OS << *InjTy->getDecl();
132 return;
135 ClassType.print(OS, Policy);
138 void DeclarationName::print(raw_ostream &OS,
139 const PrintingPolicy &Policy) const {
140 switch (getNameKind()) {
141 case DeclarationName::Identifier:
142 if (const IdentifierInfo *II = getAsIdentifierInfo()) {
143 StringRef Name = II->getName();
144 // If this is a mangled OpenMP variant name we strip off the mangling for
145 // printing. It should not be visible to the user at all.
146 if (II->isMangledOpenMPVariantName()) {
147 std::pair<StringRef, StringRef> NameContextPair =
148 Name.split(getOpenMPVariantManglingSeparatorStr());
149 OS << NameContextPair.first << "["
150 << OMPTraitInfo(NameContextPair.second) << "]";
151 } else {
152 OS << Name;
155 return;
157 case DeclarationName::ObjCZeroArgSelector:
158 case DeclarationName::ObjCOneArgSelector:
159 case DeclarationName::ObjCMultiArgSelector:
160 getObjCSelector().print(OS);
161 return;
163 case DeclarationName::CXXConstructorName:
164 return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy);
166 case DeclarationName::CXXDestructorName:
167 OS << '~';
168 return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy);
170 case DeclarationName::CXXDeductionGuideName:
171 OS << "<deduction guide for ";
172 getCXXDeductionGuideTemplate()->getDeclName().print(OS, Policy);
173 OS << '>';
174 return;
176 case DeclarationName::CXXOperatorName: {
177 const char *OpName = getOperatorSpelling(getCXXOverloadedOperator());
178 assert(OpName && "not an overloaded operator");
180 OS << "operator";
181 if (OpName[0] >= 'a' && OpName[0] <= 'z')
182 OS << ' ';
183 OS << OpName;
184 return;
187 case DeclarationName::CXXLiteralOperatorName:
188 OS << "operator\"\"" << getCXXLiteralIdentifier()->getName();
189 return;
191 case DeclarationName::CXXConversionFunctionName: {
192 OS << "operator ";
193 QualType Type = getCXXNameType();
194 if (const RecordType *Rec = Type->getAs<RecordType>()) {
195 OS << *Rec->getDecl();
196 return;
198 // We know we're printing C++ here, ensure we print 'bool' properly.
199 PrintingPolicy CXXPolicy = Policy;
200 CXXPolicy.adjustForCPlusPlus();
201 Type.print(OS, CXXPolicy);
202 return;
204 case DeclarationName::CXXUsingDirective:
205 OS << "<using-directive>";
206 return;
209 llvm_unreachable("Unexpected declaration name kind");
212 namespace clang {
214 raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
215 LangOptions LO;
216 N.print(OS, PrintingPolicy(LO));
217 return OS;
220 } // namespace clang
222 bool DeclarationName::isDependentName() const {
223 QualType T = getCXXNameType();
224 if (!T.isNull() && T->isDependentType())
225 return true;
227 // A class-scope deduction guide in a dependent context has a dependent name.
228 auto *TD = getCXXDeductionGuideTemplate();
229 if (TD && TD->getDeclContext()->isDependentContext())
230 return true;
232 return false;
235 std::string DeclarationName::getAsString() const {
236 std::string Result;
237 llvm::raw_string_ostream OS(Result);
238 OS << *this;
239 return Result;
242 void *DeclarationName::getFETokenInfoSlow() const {
243 switch (getNameKind()) {
244 case Identifier:
245 llvm_unreachable("case Identifier already handled by getFETokenInfo!");
246 case CXXConstructorName:
247 case CXXDestructorName:
248 case CXXConversionFunctionName:
249 return castAsCXXSpecialNameExtra()->FETokenInfo;
250 case CXXOperatorName:
251 return castAsCXXOperatorIdName()->FETokenInfo;
252 case CXXDeductionGuideName:
253 return castAsCXXDeductionGuideNameExtra()->FETokenInfo;
254 case CXXLiteralOperatorName:
255 return castAsCXXLiteralOperatorIdName()->FETokenInfo;
256 default:
257 llvm_unreachable("DeclarationName has no FETokenInfo!");
261 void DeclarationName::setFETokenInfoSlow(void *T) {
262 switch (getNameKind()) {
263 case Identifier:
264 llvm_unreachable("case Identifier already handled by setFETokenInfo!");
265 case CXXConstructorName:
266 case CXXDestructorName:
267 case CXXConversionFunctionName:
268 castAsCXXSpecialNameExtra()->FETokenInfo = T;
269 break;
270 case CXXOperatorName:
271 castAsCXXOperatorIdName()->FETokenInfo = T;
272 break;
273 case CXXDeductionGuideName:
274 castAsCXXDeductionGuideNameExtra()->FETokenInfo = T;
275 break;
276 case CXXLiteralOperatorName:
277 castAsCXXLiteralOperatorIdName()->FETokenInfo = T;
278 break;
279 default:
280 llvm_unreachable("DeclarationName has no FETokenInfo!");
284 LLVM_DUMP_METHOD void DeclarationName::dump() const {
285 llvm::errs() << *this << '\n';
288 DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
289 // Initialize the overloaded operator names.
290 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op)
291 CXXOperatorNames[Op].Kind = static_cast<OverloadedOperatorKind>(Op);
294 DeclarationName
295 DeclarationNameTable::getCXXDeductionGuideName(TemplateDecl *Template) {
296 Template = cast<TemplateDecl>(Template->getCanonicalDecl());
298 llvm::FoldingSetNodeID ID;
299 ID.AddPointer(Template);
301 void *InsertPos = nullptr;
302 if (auto *Name = CXXDeductionGuideNames.FindNodeOrInsertPos(ID, InsertPos))
303 return DeclarationName(Name);
305 auto *Name = new (Ctx) detail::CXXDeductionGuideNameExtra(Template);
306 CXXDeductionGuideNames.InsertNode(Name, InsertPos);
307 return DeclarationName(Name);
310 DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
311 // The type of constructors is unqualified.
312 Ty = Ty.getUnqualifiedType();
313 // Do we already have this C++ constructor name ?
314 llvm::FoldingSetNodeID ID;
315 ID.AddPointer(Ty.getAsOpaquePtr());
316 void *InsertPos = nullptr;
317 if (auto *Name = CXXConstructorNames.FindNodeOrInsertPos(ID, InsertPos))
318 return {Name, DeclarationName::StoredCXXConstructorName};
320 // We have to create it.
321 auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
322 CXXConstructorNames.InsertNode(SpecialName, InsertPos);
323 return {SpecialName, DeclarationName::StoredCXXConstructorName};
326 DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
327 // The type of destructors is unqualified.
328 Ty = Ty.getUnqualifiedType();
329 // Do we already have this C++ destructor name ?
330 llvm::FoldingSetNodeID ID;
331 ID.AddPointer(Ty.getAsOpaquePtr());
332 void *InsertPos = nullptr;
333 if (auto *Name = CXXDestructorNames.FindNodeOrInsertPos(ID, InsertPos))
334 return {Name, DeclarationName::StoredCXXDestructorName};
336 // We have to create it.
337 auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
338 CXXDestructorNames.InsertNode(SpecialName, InsertPos);
339 return {SpecialName, DeclarationName::StoredCXXDestructorName};
342 DeclarationName
343 DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
344 // Do we already have this C++ conversion function name ?
345 llvm::FoldingSetNodeID ID;
346 ID.AddPointer(Ty.getAsOpaquePtr());
347 void *InsertPos = nullptr;
348 if (auto *Name =
349 CXXConversionFunctionNames.FindNodeOrInsertPos(ID, InsertPos))
350 return {Name, DeclarationName::StoredCXXConversionFunctionName};
352 // We have to create it.
353 auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
354 CXXConversionFunctionNames.InsertNode(SpecialName, InsertPos);
355 return {SpecialName, DeclarationName::StoredCXXConversionFunctionName};
358 DeclarationName
359 DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
360 CanQualType Ty) {
361 switch (Kind) {
362 case DeclarationName::CXXConstructorName:
363 return getCXXConstructorName(Ty);
364 case DeclarationName::CXXDestructorName:
365 return getCXXDestructorName(Ty);
366 case DeclarationName::CXXConversionFunctionName:
367 return getCXXConversionFunctionName(Ty);
368 default:
369 llvm_unreachable("Invalid kind in getCXXSpecialName!");
373 DeclarationName
374 DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
375 llvm::FoldingSetNodeID ID;
376 ID.AddPointer(II);
378 void *InsertPos = nullptr;
379 if (auto *Name = CXXLiteralOperatorNames.FindNodeOrInsertPos(ID, InsertPos))
380 return DeclarationName(Name);
382 auto *LiteralName = new (Ctx) detail::CXXLiteralOperatorIdName(II);
383 CXXLiteralOperatorNames.InsertNode(LiteralName, InsertPos);
384 return DeclarationName(LiteralName);
387 DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
388 switch (Name.getNameKind()) {
389 case DeclarationName::Identifier:
390 case DeclarationName::CXXDeductionGuideName:
391 break;
392 case DeclarationName::CXXConstructorName:
393 case DeclarationName::CXXDestructorName:
394 case DeclarationName::CXXConversionFunctionName:
395 setNamedTypeLoc(nullptr);
396 break;
397 case DeclarationName::CXXOperatorName:
398 setCXXOperatorNameRange(SourceRange());
399 break;
400 case DeclarationName::CXXLiteralOperatorName:
401 setCXXLiteralOperatorNameLoc(SourceLocation());
402 break;
403 case DeclarationName::ObjCZeroArgSelector:
404 case DeclarationName::ObjCOneArgSelector:
405 case DeclarationName::ObjCMultiArgSelector:
406 // FIXME: ?
407 break;
408 case DeclarationName::CXXUsingDirective:
409 break;
413 bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
414 switch (Name.getNameKind()) {
415 case DeclarationName::Identifier:
416 case DeclarationName::ObjCZeroArgSelector:
417 case DeclarationName::ObjCOneArgSelector:
418 case DeclarationName::ObjCMultiArgSelector:
419 case DeclarationName::CXXOperatorName:
420 case DeclarationName::CXXLiteralOperatorName:
421 case DeclarationName::CXXUsingDirective:
422 case DeclarationName::CXXDeductionGuideName:
423 return false;
425 case DeclarationName::CXXConstructorName:
426 case DeclarationName::CXXDestructorName:
427 case DeclarationName::CXXConversionFunctionName:
428 if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo())
429 return TInfo->getType()->containsUnexpandedParameterPack();
431 return Name.getCXXNameType()->containsUnexpandedParameterPack();
433 llvm_unreachable("All name kinds handled.");
436 bool DeclarationNameInfo::isInstantiationDependent() const {
437 switch (Name.getNameKind()) {
438 case DeclarationName::Identifier:
439 case DeclarationName::ObjCZeroArgSelector:
440 case DeclarationName::ObjCOneArgSelector:
441 case DeclarationName::ObjCMultiArgSelector:
442 case DeclarationName::CXXOperatorName:
443 case DeclarationName::CXXLiteralOperatorName:
444 case DeclarationName::CXXUsingDirective:
445 case DeclarationName::CXXDeductionGuideName:
446 return false;
448 case DeclarationName::CXXConstructorName:
449 case DeclarationName::CXXDestructorName:
450 case DeclarationName::CXXConversionFunctionName:
451 if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo())
452 return TInfo->getType()->isInstantiationDependentType();
454 return Name.getCXXNameType()->isInstantiationDependentType();
456 llvm_unreachable("All name kinds handled.");
459 std::string DeclarationNameInfo::getAsString() const {
460 std::string Result;
461 llvm::raw_string_ostream OS(Result);
462 OS << *this;
463 return Result;
466 raw_ostream &clang::operator<<(raw_ostream &OS, DeclarationNameInfo DNInfo) {
467 LangOptions LO;
468 DNInfo.printName(OS, PrintingPolicy(LangOptions()));
469 return OS;
472 void DeclarationNameInfo::printName(raw_ostream &OS, PrintingPolicy Policy) const {
473 switch (Name.getNameKind()) {
474 case DeclarationName::Identifier:
475 case DeclarationName::ObjCZeroArgSelector:
476 case DeclarationName::ObjCOneArgSelector:
477 case DeclarationName::ObjCMultiArgSelector:
478 case DeclarationName::CXXOperatorName:
479 case DeclarationName::CXXLiteralOperatorName:
480 case DeclarationName::CXXUsingDirective:
481 case DeclarationName::CXXDeductionGuideName:
482 Name.print(OS, Policy);
483 return;
485 case DeclarationName::CXXConstructorName:
486 case DeclarationName::CXXDestructorName:
487 case DeclarationName::CXXConversionFunctionName:
488 if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo()) {
489 if (Name.getNameKind() == DeclarationName::CXXDestructorName)
490 OS << '~';
491 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
492 OS << "operator ";
493 LangOptions LO;
494 Policy.adjustForCPlusPlus();
495 Policy.SuppressScope = true;
496 OS << TInfo->getType().getAsString(Policy);
497 } else
498 Name.print(OS, Policy);
499 return;
501 llvm_unreachable("Unexpected declaration name kind");
504 SourceLocation DeclarationNameInfo::getEndLocPrivate() const {
505 switch (Name.getNameKind()) {
506 case DeclarationName::Identifier:
507 case DeclarationName::CXXDeductionGuideName:
508 return NameLoc;
510 case DeclarationName::CXXOperatorName:
511 return LocInfo.getCXXOperatorNameEndLoc();
513 case DeclarationName::CXXLiteralOperatorName:
514 return LocInfo.getCXXLiteralOperatorNameLoc();
516 case DeclarationName::CXXConstructorName:
517 case DeclarationName::CXXDestructorName:
518 case DeclarationName::CXXConversionFunctionName:
519 if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo())
520 return TInfo->getTypeLoc().getEndLoc();
521 else
522 return NameLoc;
524 // DNInfo work in progress: FIXME.
525 case DeclarationName::ObjCZeroArgSelector:
526 case DeclarationName::ObjCOneArgSelector:
527 case DeclarationName::ObjCMultiArgSelector:
528 case DeclarationName::CXXUsingDirective:
529 return NameLoc;
531 llvm_unreachable("Unexpected declaration name kind");