1 //===-- DeclarationName.cpp - Declaration names implementation --*- C++ -*-===//
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 #include "clang/AST/ASTContext.h"
15 #include "clang/AST/Decl.h"
16 #include "clang/AST/DeclarationName.h"
17 #include "clang/AST/Type.h"
18 #include "clang/AST/TypeLoc.h"
19 #include "clang/AST/TypeOrdering.h"
20 #include "clang/Basic/IdentifierTable.h"
21 #include "llvm/ADT/DenseMap.h"
22 #include "llvm/ADT/FoldingSet.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/raw_ostream.h"
25 using namespace clang;
26
27 namespace clang {
28 /// CXXSpecialName - Records the type associated with one of the
29 /// "special" kinds of declaration names in C++, e.g., constructors,
30 /// destructors, and conversion functions.
31 class CXXSpecialName
32 : public DeclarationNameExtra, public llvm::FoldingSetNode {
33 public:
34 /// Type - The type associated with this declaration name.
35 QualType Type;
36
37 /// FETokenInfo - Extra information associated with this declaration
38 /// name that can be used by the front end.
39 void *FETokenInfo;
40
Profile(llvm::FoldingSetNodeID & ID)41 void Profile(llvm::FoldingSetNodeID &ID) {
42 ID.AddInteger(ExtraKindOrNumArgs);
43 ID.AddPointer(Type.getAsOpaquePtr());
44 }
45 };
46
47 /// CXXOperatorIdName - Contains extra information for the name of an
48 /// overloaded operator in C++, such as "operator+.
49 class CXXOperatorIdName : public DeclarationNameExtra {
50 public:
51 /// FETokenInfo - Extra information associated with this operator
52 /// name that can be used by the front end.
53 void *FETokenInfo;
54 };
55
56 /// CXXLiteralOperatorName - Contains the actual identifier that makes up the
57 /// name.
58 ///
59 /// This identifier is stored here rather than directly in DeclarationName so as
60 /// to allow Objective-C selectors, which are about a million times more common,
61 /// to consume minimal memory.
62 class CXXLiteralOperatorIdName
63 : public DeclarationNameExtra, public llvm::FoldingSetNode {
64 public:
65 IdentifierInfo *ID;
66
67 /// FETokenInfo - Extra information associated with this operator
68 /// name that can be used by the front end.
69 void *FETokenInfo;
70
Profile(llvm::FoldingSetNodeID & FSID)71 void Profile(llvm::FoldingSetNodeID &FSID) {
72 FSID.AddPointer(ID);
73 }
74 };
75
compareInt(unsigned A,unsigned B)76 static int compareInt(unsigned A, unsigned B) {
77 return (A < B ? -1 : (A > B ? 1 : 0));
78 }
79
compare(DeclarationName LHS,DeclarationName RHS)80 int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
81 if (LHS.getNameKind() != RHS.getNameKind())
82 return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
83
84 switch (LHS.getNameKind()) {
85 case DeclarationName::Identifier: {
86 IdentifierInfo *LII = LHS.getAsIdentifierInfo();
87 IdentifierInfo *RII = RHS.getAsIdentifierInfo();
88 if (!LII) return RII ? -1 : 0;
89 if (!RII) return 1;
90
91 return LII->getName().compare(RII->getName());
92 }
93
94 case DeclarationName::ObjCZeroArgSelector:
95 case DeclarationName::ObjCOneArgSelector:
96 case DeclarationName::ObjCMultiArgSelector: {
97 Selector LHSSelector = LHS.getObjCSelector();
98 Selector RHSSelector = RHS.getObjCSelector();
99 unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
100 for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
101 switch (LHSSelector.getNameForSlot(I).compare(
102 RHSSelector.getNameForSlot(I))) {
103 case -1: return true;
104 case 1: return false;
105 default: break;
106 }
107 }
108
109 return compareInt(LN, RN);
110 }
111
112 case DeclarationName::CXXConstructorName:
113 case DeclarationName::CXXDestructorName:
114 case DeclarationName::CXXConversionFunctionName:
115 if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
116 return -1;
117 if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
118 return 1;
119 return 0;
120
121 case DeclarationName::CXXOperatorName:
122 return compareInt(LHS.getCXXOverloadedOperator(),
123 RHS.getCXXOverloadedOperator());
124
125 case DeclarationName::CXXLiteralOperatorName:
126 return LHS.getCXXLiteralIdentifier()->getName().compare(
127 RHS.getCXXLiteralIdentifier()->getName());
128
129 case DeclarationName::CXXUsingDirective:
130 return 0;
131 }
132
133 llvm_unreachable("Invalid DeclarationName Kind!");
134 }
135
operator <<(raw_ostream & OS,DeclarationName N)136 raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
137 switch (N.getNameKind()) {
138 case DeclarationName::Identifier:
139 if (const IdentifierInfo *II = N.getAsIdentifierInfo())
140 OS << II->getName();
141 return OS;
142
143 case DeclarationName::ObjCZeroArgSelector:
144 case DeclarationName::ObjCOneArgSelector:
145 case DeclarationName::ObjCMultiArgSelector:
146 N.getObjCSelector().print(OS);
147 return OS;
148
149 case DeclarationName::CXXConstructorName: {
150 QualType ClassType = N.getCXXNameType();
151 if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
152 return OS << *ClassRec->getDecl();
153 LangOptions LO;
154 LO.CPlusPlus = true;
155 return OS << ClassType.getAsString(PrintingPolicy(LO));
156 }
157
158 case DeclarationName::CXXDestructorName: {
159 OS << '~';
160 QualType Type = N.getCXXNameType();
161 if (const RecordType *Rec = Type->getAs<RecordType>())
162 return OS << *Rec->getDecl();
163 LangOptions LO;
164 LO.CPlusPlus = true;
165 return OS << Type.getAsString(PrintingPolicy(LO));
166 }
167
168 case DeclarationName::CXXOperatorName: {
169 static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
170 nullptr,
171 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
172 Spelling,
173 #include "clang/Basic/OperatorKinds.def"
174 };
175 const char *OpName = OperatorNames[N.getCXXOverloadedOperator()];
176 assert(OpName && "not an overloaded operator");
177
178 OS << "operator";
179 if (OpName[0] >= 'a' && OpName[0] <= 'z')
180 OS << ' ';
181 return OS << OpName;
182 }
183
184 case DeclarationName::CXXLiteralOperatorName:
185 return OS << "operator \"\" " << N.getCXXLiteralIdentifier()->getName();
186
187 case DeclarationName::CXXConversionFunctionName: {
188 OS << "operator ";
189 QualType Type = N.getCXXNameType();
190 if (const RecordType *Rec = Type->getAs<RecordType>())
191 return OS << *Rec->getDecl();
192 LangOptions LO;
193 LO.CPlusPlus = true;
194 LO.Bool = true;
195 return OS << Type.getAsString(PrintingPolicy(LO));
196 }
197 case DeclarationName::CXXUsingDirective:
198 return OS << "<using-directive>";
199 }
200
201 llvm_unreachable("Unexpected declaration name kind");
202 }
203
204 } // end namespace clang
205
getNameKind() const206 DeclarationName::NameKind DeclarationName::getNameKind() const {
207 switch (getStoredNameKind()) {
208 case StoredIdentifier: return Identifier;
209 case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
210 case StoredObjCOneArgSelector: return ObjCOneArgSelector;
211
212 case StoredDeclarationNameExtra:
213 switch (getExtra()->ExtraKindOrNumArgs) {
214 case DeclarationNameExtra::CXXConstructor:
215 return CXXConstructorName;
216
217 case DeclarationNameExtra::CXXDestructor:
218 return CXXDestructorName;
219
220 case DeclarationNameExtra::CXXConversionFunction:
221 return CXXConversionFunctionName;
222
223 case DeclarationNameExtra::CXXLiteralOperator:
224 return CXXLiteralOperatorName;
225
226 case DeclarationNameExtra::CXXUsingDirective:
227 return CXXUsingDirective;
228
229 default:
230 // Check if we have one of the CXXOperator* enumeration values.
231 if (getExtra()->ExtraKindOrNumArgs <
232 DeclarationNameExtra::CXXUsingDirective)
233 return CXXOperatorName;
234
235 return ObjCMultiArgSelector;
236 }
237 }
238
239 // Can't actually get here.
240 llvm_unreachable("This should be unreachable!");
241 }
242
isDependentName() const243 bool DeclarationName::isDependentName() const {
244 QualType T = getCXXNameType();
245 return !T.isNull() && T->isDependentType();
246 }
247
getAsString() const248 std::string DeclarationName::getAsString() const {
249 std::string Result;
250 llvm::raw_string_ostream OS(Result);
251 OS << *this;
252 return OS.str();
253 }
254
getCXXNameType() const255 QualType DeclarationName::getCXXNameType() const {
256 if (CXXSpecialName *CXXName = getAsCXXSpecialName())
257 return CXXName->Type;
258 else
259 return QualType();
260 }
261
getCXXOverloadedOperator() const262 OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
263 if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
264 unsigned value
265 = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
266 return static_cast<OverloadedOperatorKind>(value);
267 } else {
268 return OO_None;
269 }
270 }
271
getCXXLiteralIdentifier() const272 IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
273 if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
274 return CXXLit->ID;
275 else
276 return nullptr;
277 }
278
getFETokenInfoAsVoidSlow() const279 void *DeclarationName::getFETokenInfoAsVoidSlow() const {
280 switch (getNameKind()) {
281 case Identifier:
282 llvm_unreachable("Handled by getFETokenInfo()");
283
284 case CXXConstructorName:
285 case CXXDestructorName:
286 case CXXConversionFunctionName:
287 return getAsCXXSpecialName()->FETokenInfo;
288
289 case CXXOperatorName:
290 return getAsCXXOperatorIdName()->FETokenInfo;
291
292 case CXXLiteralOperatorName:
293 return getAsCXXLiteralOperatorIdName()->FETokenInfo;
294
295 default:
296 llvm_unreachable("Declaration name has no FETokenInfo");
297 }
298 }
299
setFETokenInfo(void * T)300 void DeclarationName::setFETokenInfo(void *T) {
301 switch (getNameKind()) {
302 case Identifier:
303 getAsIdentifierInfo()->setFETokenInfo(T);
304 break;
305
306 case CXXConstructorName:
307 case CXXDestructorName:
308 case CXXConversionFunctionName:
309 getAsCXXSpecialName()->FETokenInfo = T;
310 break;
311
312 case CXXOperatorName:
313 getAsCXXOperatorIdName()->FETokenInfo = T;
314 break;
315
316 case CXXLiteralOperatorName:
317 getAsCXXLiteralOperatorIdName()->FETokenInfo = T;
318 break;
319
320 default:
321 llvm_unreachable("Declaration name has no FETokenInfo");
322 }
323 }
324
getUsingDirectiveName()325 DeclarationName DeclarationName::getUsingDirectiveName() {
326 // Single instance of DeclarationNameExtra for using-directive
327 static const DeclarationNameExtra UDirExtra =
328 { DeclarationNameExtra::CXXUsingDirective };
329
330 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
331 Ptr |= StoredDeclarationNameExtra;
332
333 return DeclarationName(Ptr);
334 }
335
dump() const336 void DeclarationName::dump() const {
337 llvm::errs() << *this << '\n';
338 }
339
DeclarationNameTable(const ASTContext & C)340 DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
341 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
342 CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
343
344 // Initialize the overloaded operator names.
345 CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
346 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
347 CXXOperatorNames[Op].ExtraKindOrNumArgs
348 = Op + DeclarationNameExtra::CXXConversionFunction;
349 CXXOperatorNames[Op].FETokenInfo = nullptr;
350 }
351 }
352
~DeclarationNameTable()353 DeclarationNameTable::~DeclarationNameTable() {
354 llvm::FoldingSet<CXXSpecialName> *SpecialNames =
355 static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
356 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
357 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
358 (CXXLiteralOperatorNames);
359
360 delete SpecialNames;
361 delete LiteralNames;
362 }
363
getCXXConstructorName(CanQualType Ty)364 DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
365 return getCXXSpecialName(DeclarationName::CXXConstructorName,
366 Ty.getUnqualifiedType());
367 }
368
getCXXDestructorName(CanQualType Ty)369 DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
370 return getCXXSpecialName(DeclarationName::CXXDestructorName,
371 Ty.getUnqualifiedType());
372 }
373
374 DeclarationName
getCXXConversionFunctionName(CanQualType Ty)375 DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
376 return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty);
377 }
378
379 DeclarationName
getCXXSpecialName(DeclarationName::NameKind Kind,CanQualType Ty)380 DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
381 CanQualType Ty) {
382 assert(Kind >= DeclarationName::CXXConstructorName &&
383 Kind <= DeclarationName::CXXConversionFunctionName &&
384 "Kind must be a C++ special name kind");
385 llvm::FoldingSet<CXXSpecialName> *SpecialNames
386 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
387
388 DeclarationNameExtra::ExtraKind EKind;
389 switch (Kind) {
390 case DeclarationName::CXXConstructorName:
391 EKind = DeclarationNameExtra::CXXConstructor;
392 assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
393 break;
394 case DeclarationName::CXXDestructorName:
395 EKind = DeclarationNameExtra::CXXDestructor;
396 assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
397 break;
398 case DeclarationName::CXXConversionFunctionName:
399 EKind = DeclarationNameExtra::CXXConversionFunction;
400 break;
401 default:
402 return DeclarationName();
403 }
404
405 // Unique selector, to guarantee there is one per name.
406 llvm::FoldingSetNodeID ID;
407 ID.AddInteger(EKind);
408 ID.AddPointer(Ty.getAsOpaquePtr());
409
410 void *InsertPos = nullptr;
411 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
412 return DeclarationName(Name);
413
414 CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
415 SpecialName->ExtraKindOrNumArgs = EKind;
416 SpecialName->Type = Ty;
417 SpecialName->FETokenInfo = nullptr;
418
419 SpecialNames->InsertNode(SpecialName, InsertPos);
420 return DeclarationName(SpecialName);
421 }
422
423 DeclarationName
getCXXOperatorName(OverloadedOperatorKind Op)424 DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
425 return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
426 }
427
428 DeclarationName
getCXXLiteralOperatorName(IdentifierInfo * II)429 DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
430 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
431 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
432 (CXXLiteralOperatorNames);
433
434 llvm::FoldingSetNodeID ID;
435 ID.AddPointer(II);
436
437 void *InsertPos = nullptr;
438 if (CXXLiteralOperatorIdName *Name =
439 LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
440 return DeclarationName (Name);
441
442 CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
443 LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
444 LiteralName->ID = II;
445 LiteralName->FETokenInfo = nullptr;
446
447 LiteralNames->InsertNode(LiteralName, InsertPos);
448 return DeclarationName(LiteralName);
449 }
450
DeclarationNameLoc(DeclarationName Name)451 DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
452 switch (Name.getNameKind()) {
453 case DeclarationName::Identifier:
454 break;
455 case DeclarationName::CXXConstructorName:
456 case DeclarationName::CXXDestructorName:
457 case DeclarationName::CXXConversionFunctionName:
458 NamedType.TInfo = nullptr;
459 break;
460 case DeclarationName::CXXOperatorName:
461 CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
462 CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
463 break;
464 case DeclarationName::CXXLiteralOperatorName:
465 CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
466 break;
467 case DeclarationName::ObjCZeroArgSelector:
468 case DeclarationName::ObjCOneArgSelector:
469 case DeclarationName::ObjCMultiArgSelector:
470 // FIXME: ?
471 break;
472 case DeclarationName::CXXUsingDirective:
473 break;
474 }
475 }
476
containsUnexpandedParameterPack() const477 bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
478 switch (Name.getNameKind()) {
479 case DeclarationName::Identifier:
480 case DeclarationName::ObjCZeroArgSelector:
481 case DeclarationName::ObjCOneArgSelector:
482 case DeclarationName::ObjCMultiArgSelector:
483 case DeclarationName::CXXOperatorName:
484 case DeclarationName::CXXLiteralOperatorName:
485 case DeclarationName::CXXUsingDirective:
486 return false;
487
488 case DeclarationName::CXXConstructorName:
489 case DeclarationName::CXXDestructorName:
490 case DeclarationName::CXXConversionFunctionName:
491 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
492 return TInfo->getType()->containsUnexpandedParameterPack();
493
494 return Name.getCXXNameType()->containsUnexpandedParameterPack();
495 }
496 llvm_unreachable("All name kinds handled.");
497 }
498
isInstantiationDependent() const499 bool DeclarationNameInfo::isInstantiationDependent() const {
500 switch (Name.getNameKind()) {
501 case DeclarationName::Identifier:
502 case DeclarationName::ObjCZeroArgSelector:
503 case DeclarationName::ObjCOneArgSelector:
504 case DeclarationName::ObjCMultiArgSelector:
505 case DeclarationName::CXXOperatorName:
506 case DeclarationName::CXXLiteralOperatorName:
507 case DeclarationName::CXXUsingDirective:
508 return false;
509
510 case DeclarationName::CXXConstructorName:
511 case DeclarationName::CXXDestructorName:
512 case DeclarationName::CXXConversionFunctionName:
513 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
514 return TInfo->getType()->isInstantiationDependentType();
515
516 return Name.getCXXNameType()->isInstantiationDependentType();
517 }
518 llvm_unreachable("All name kinds handled.");
519 }
520
getAsString() const521 std::string DeclarationNameInfo::getAsString() const {
522 std::string Result;
523 llvm::raw_string_ostream OS(Result);
524 printName(OS);
525 return OS.str();
526 }
527
printName(raw_ostream & OS) const528 void DeclarationNameInfo::printName(raw_ostream &OS) const {
529 switch (Name.getNameKind()) {
530 case DeclarationName::Identifier:
531 case DeclarationName::ObjCZeroArgSelector:
532 case DeclarationName::ObjCOneArgSelector:
533 case DeclarationName::ObjCMultiArgSelector:
534 case DeclarationName::CXXOperatorName:
535 case DeclarationName::CXXLiteralOperatorName:
536 case DeclarationName::CXXUsingDirective:
537 OS << Name;
538 return;
539
540 case DeclarationName::CXXConstructorName:
541 case DeclarationName::CXXDestructorName:
542 case DeclarationName::CXXConversionFunctionName:
543 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
544 if (Name.getNameKind() == DeclarationName::CXXDestructorName)
545 OS << '~';
546 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
547 OS << "operator ";
548 LangOptions LO;
549 LO.CPlusPlus = true;
550 LO.Bool = true;
551 OS << TInfo->getType().getAsString(PrintingPolicy(LO));
552 } else
553 OS << Name;
554 return;
555 }
556 llvm_unreachable("Unexpected declaration name kind");
557 }
558
getEndLoc() const559 SourceLocation DeclarationNameInfo::getEndLoc() const {
560 switch (Name.getNameKind()) {
561 case DeclarationName::Identifier:
562 return NameLoc;
563
564 case DeclarationName::CXXOperatorName: {
565 unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
566 return SourceLocation::getFromRawEncoding(raw);
567 }
568
569 case DeclarationName::CXXLiteralOperatorName: {
570 unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
571 return SourceLocation::getFromRawEncoding(raw);
572 }
573
574 case DeclarationName::CXXConstructorName:
575 case DeclarationName::CXXDestructorName:
576 case DeclarationName::CXXConversionFunctionName:
577 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
578 return TInfo->getTypeLoc().getEndLoc();
579 else
580 return NameLoc;
581
582 // DNInfo work in progress: FIXME.
583 case DeclarationName::ObjCZeroArgSelector:
584 case DeclarationName::ObjCOneArgSelector:
585 case DeclarationName::ObjCMultiArgSelector:
586 case DeclarationName::CXXUsingDirective:
587 return NameLoc;
588 }
589 llvm_unreachable("Unexpected declaration name kind");
590 }
591