Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/AST/DeclarationName.cpp
35260 views
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/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>
39
40
using namespace clang;
41
42
static int compareInt(unsigned A, unsigned B) {
43
return (A < B ? -1 : (A > B ? 1 : 0));
44
}
45
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
if (int Compare = LHSSelector.getNameForSlot(I).compare(
76
RHSSelector.getNameForSlot(I)))
77
return Compare;
78
}
79
80
return compareInt(LN, RN);
81
}
82
83
case DeclarationName::CXXConstructorName:
84
case DeclarationName::CXXDestructorName:
85
case DeclarationName::CXXConversionFunctionName:
86
if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
87
return -1;
88
if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
89
return 1;
90
return 0;
91
92
case DeclarationName::CXXDeductionGuideName:
93
// We never want to compare deduction guide names for templates from
94
// different scopes, so just compare the template-name.
95
return compare(LHS.getCXXDeductionGuideTemplate()->getDeclName(),
96
RHS.getCXXDeductionGuideTemplate()->getDeclName());
97
98
case DeclarationName::CXXOperatorName:
99
return compareInt(LHS.getCXXOverloadedOperator(),
100
RHS.getCXXOverloadedOperator());
101
102
case DeclarationName::CXXLiteralOperatorName:
103
return LHS.getCXXLiteralIdentifier()->getName().compare(
104
RHS.getCXXLiteralIdentifier()->getName());
105
106
case DeclarationName::CXXUsingDirective:
107
return 0;
108
}
109
110
llvm_unreachable("Invalid DeclarationName Kind!");
111
}
112
113
static void printCXXConstructorDestructorName(QualType ClassType,
114
raw_ostream &OS,
115
PrintingPolicy Policy) {
116
// We know we're printing C++ here. Ensure we print types properly.
117
Policy.adjustForCPlusPlus();
118
119
if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) {
120
ClassRec->getDecl()->printName(OS, Policy);
121
return;
122
}
123
if (Policy.SuppressTemplateArgsInCXXConstructors) {
124
if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) {
125
InjTy->getDecl()->printName(OS, Policy);
126
return;
127
}
128
}
129
ClassType.print(OS, Policy);
130
}
131
132
void DeclarationName::print(raw_ostream &OS,
133
const PrintingPolicy &Policy) const {
134
switch (getNameKind()) {
135
case DeclarationName::Identifier:
136
if (const IdentifierInfo *II = getAsIdentifierInfo()) {
137
StringRef Name = II->getName();
138
// If this is a mangled OpenMP variant name we strip off the mangling for
139
// printing. It should not be visible to the user at all.
140
if (II->isMangledOpenMPVariantName()) {
141
std::pair<StringRef, StringRef> NameContextPair =
142
Name.split(getOpenMPVariantManglingSeparatorStr());
143
OS << NameContextPair.first << "["
144
<< OMPTraitInfo(NameContextPair.second) << "]";
145
} else {
146
OS << Name;
147
}
148
}
149
return;
150
151
case DeclarationName::ObjCZeroArgSelector:
152
case DeclarationName::ObjCOneArgSelector:
153
case DeclarationName::ObjCMultiArgSelector:
154
getObjCSelector().print(OS);
155
return;
156
157
case DeclarationName::CXXConstructorName:
158
return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy);
159
160
case DeclarationName::CXXDestructorName:
161
OS << '~';
162
return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy);
163
164
case DeclarationName::CXXDeductionGuideName:
165
OS << "<deduction guide for ";
166
getCXXDeductionGuideTemplate()->getDeclName().print(OS, Policy);
167
OS << '>';
168
return;
169
170
case DeclarationName::CXXOperatorName: {
171
const char *OpName = getOperatorSpelling(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
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
216
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
229
std::string DeclarationName::getAsString() const {
230
std::string Result;
231
llvm::raw_string_ostream OS(Result);
232
OS << *this;
233
return Result;
234
}
235
236
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
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
278
LLVM_DUMP_METHOD void DeclarationName::dump() const {
279
llvm::errs() << *this << '\n';
280
}
281
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
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
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
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
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
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
368
DeclarationNameTable::getCXXLiteralOperatorName(const 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
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
setNamedTypeLoc(nullptr);
390
break;
391
case DeclarationName::CXXOperatorName:
392
setCXXOperatorNameRange(SourceRange());
393
break;
394
case DeclarationName::CXXLiteralOperatorName:
395
setCXXLiteralOperatorNameLoc(SourceLocation());
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.getNamedTypeInfo())
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.getNamedTypeInfo())
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
OS << *this;
457
return Result;
458
}
459
460
raw_ostream &clang::operator<<(raw_ostream &OS, DeclarationNameInfo DNInfo) {
461
LangOptions LO;
462
DNInfo.printName(OS, PrintingPolicy(LangOptions()));
463
return OS;
464
}
465
466
void DeclarationNameInfo::printName(raw_ostream &OS, PrintingPolicy Policy) const {
467
switch (Name.getNameKind()) {
468
case DeclarationName::Identifier:
469
case DeclarationName::ObjCZeroArgSelector:
470
case DeclarationName::ObjCOneArgSelector:
471
case DeclarationName::ObjCMultiArgSelector:
472
case DeclarationName::CXXOperatorName:
473
case DeclarationName::CXXLiteralOperatorName:
474
case DeclarationName::CXXUsingDirective:
475
case DeclarationName::CXXDeductionGuideName:
476
Name.print(OS, Policy);
477
return;
478
479
case DeclarationName::CXXConstructorName:
480
case DeclarationName::CXXDestructorName:
481
case DeclarationName::CXXConversionFunctionName:
482
if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo()) {
483
if (Name.getNameKind() == DeclarationName::CXXDestructorName)
484
OS << '~';
485
else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
486
OS << "operator ";
487
LangOptions LO;
488
Policy.adjustForCPlusPlus();
489
Policy.SuppressScope = true;
490
OS << TInfo->getType().getAsString(Policy);
491
} else
492
Name.print(OS, Policy);
493
return;
494
}
495
llvm_unreachable("Unexpected declaration name kind");
496
}
497
498
SourceLocation DeclarationNameInfo::getEndLocPrivate() const {
499
switch (Name.getNameKind()) {
500
case DeclarationName::Identifier:
501
case DeclarationName::CXXDeductionGuideName:
502
return NameLoc;
503
504
case DeclarationName::CXXOperatorName:
505
return LocInfo.getCXXOperatorNameEndLoc();
506
507
case DeclarationName::CXXLiteralOperatorName:
508
return LocInfo.getCXXLiteralOperatorNameLoc();
509
510
case DeclarationName::CXXConstructorName:
511
case DeclarationName::CXXDestructorName:
512
case DeclarationName::CXXConversionFunctionName:
513
if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo())
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
528