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
136 } // end namespace clang
137
getNameKind() const138 DeclarationName::NameKind DeclarationName::getNameKind() const {
139 switch (getStoredNameKind()) {
140 case StoredIdentifier: return Identifier;
141 case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
142 case StoredObjCOneArgSelector: return ObjCOneArgSelector;
143
144 case StoredDeclarationNameExtra:
145 switch (getExtra()->ExtraKindOrNumArgs) {
146 case DeclarationNameExtra::CXXConstructor:
147 return CXXConstructorName;
148
149 case DeclarationNameExtra::CXXDestructor:
150 return CXXDestructorName;
151
152 case DeclarationNameExtra::CXXConversionFunction:
153 return CXXConversionFunctionName;
154
155 case DeclarationNameExtra::CXXLiteralOperator:
156 return CXXLiteralOperatorName;
157
158 case DeclarationNameExtra::CXXUsingDirective:
159 return CXXUsingDirective;
160
161 default:
162 // Check if we have one of the CXXOperator* enumeration values.
163 if (getExtra()->ExtraKindOrNumArgs <
164 DeclarationNameExtra::CXXUsingDirective)
165 return CXXOperatorName;
166
167 return ObjCMultiArgSelector;
168 }
169 }
170
171 // Can't actually get here.
172 llvm_unreachable("This should be unreachable!");
173 }
174
isDependentName() const175 bool DeclarationName::isDependentName() const {
176 QualType T = getCXXNameType();
177 return !T.isNull() && T->isDependentType();
178 }
179
getAsString() const180 std::string DeclarationName::getAsString() const {
181 std::string Result;
182 llvm::raw_string_ostream OS(Result);
183 printName(OS);
184 return OS.str();
185 }
186
printName(raw_ostream & OS) const187 void DeclarationName::printName(raw_ostream &OS) const {
188 switch (getNameKind()) {
189 case Identifier:
190 if (const IdentifierInfo *II = getAsIdentifierInfo())
191 OS << II->getName();
192 return;
193
194 case ObjCZeroArgSelector:
195 case ObjCOneArgSelector:
196 case ObjCMultiArgSelector:
197 OS << getObjCSelector().getAsString();
198 return;
199
200 case CXXConstructorName: {
201 QualType ClassType = getCXXNameType();
202 if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
203 OS << *ClassRec->getDecl();
204 else
205 OS << ClassType.getAsString();
206 return;
207 }
208
209 case CXXDestructorName: {
210 OS << '~';
211 QualType Type = getCXXNameType();
212 if (const RecordType *Rec = Type->getAs<RecordType>())
213 OS << *Rec->getDecl();
214 else
215 OS << Type.getAsString();
216 return;
217 }
218
219 case CXXOperatorName: {
220 static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
221 0,
222 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
223 Spelling,
224 #include "clang/Basic/OperatorKinds.def"
225 };
226 const char *OpName = OperatorNames[getCXXOverloadedOperator()];
227 assert(OpName && "not an overloaded operator");
228
229 OS << "operator";
230 if (OpName[0] >= 'a' && OpName[0] <= 'z')
231 OS << ' ';
232 OS << OpName;
233 return;
234 }
235
236 case CXXLiteralOperatorName:
237 OS << "operator \"\" " << getCXXLiteralIdentifier()->getName();
238 return;
239
240 case CXXConversionFunctionName: {
241 OS << "operator ";
242 QualType Type = getCXXNameType();
243 if (const RecordType *Rec = Type->getAs<RecordType>())
244 OS << *Rec->getDecl();
245 else
246 OS << Type.getAsString();
247 return;
248 }
249 case CXXUsingDirective:
250 OS << "<using-directive>";
251 return;
252 }
253
254 llvm_unreachable("Unexpected declaration name kind");
255 }
256
getCXXNameType() const257 QualType DeclarationName::getCXXNameType() const {
258 if (CXXSpecialName *CXXName = getAsCXXSpecialName())
259 return CXXName->Type;
260 else
261 return QualType();
262 }
263
getCXXOverloadedOperator() const264 OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
265 if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
266 unsigned value
267 = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
268 return static_cast<OverloadedOperatorKind>(value);
269 } else {
270 return OO_None;
271 }
272 }
273
getCXXLiteralIdentifier() const274 IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
275 if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
276 return CXXLit->ID;
277 else
278 return 0;
279 }
280
getFETokenInfoAsVoidSlow() const281 void *DeclarationName::getFETokenInfoAsVoidSlow() const {
282 switch (getNameKind()) {
283 case Identifier:
284 llvm_unreachable("Handled by getFETokenInfo()");
285
286 case CXXConstructorName:
287 case CXXDestructorName:
288 case CXXConversionFunctionName:
289 return getAsCXXSpecialName()->FETokenInfo;
290
291 case CXXOperatorName:
292 return getAsCXXOperatorIdName()->FETokenInfo;
293
294 case CXXLiteralOperatorName:
295 return getAsCXXLiteralOperatorIdName()->FETokenInfo;
296
297 default:
298 llvm_unreachable("Declaration name has no FETokenInfo");
299 }
300 }
301
setFETokenInfo(void * T)302 void DeclarationName::setFETokenInfo(void *T) {
303 switch (getNameKind()) {
304 case Identifier:
305 getAsIdentifierInfo()->setFETokenInfo(T);
306 break;
307
308 case CXXConstructorName:
309 case CXXDestructorName:
310 case CXXConversionFunctionName:
311 getAsCXXSpecialName()->FETokenInfo = T;
312 break;
313
314 case CXXOperatorName:
315 getAsCXXOperatorIdName()->FETokenInfo = T;
316 break;
317
318 case CXXLiteralOperatorName:
319 getAsCXXLiteralOperatorIdName()->FETokenInfo = T;
320 break;
321
322 default:
323 llvm_unreachable("Declaration name has no FETokenInfo");
324 }
325 }
326
getUsingDirectiveName()327 DeclarationName DeclarationName::getUsingDirectiveName() {
328 // Single instance of DeclarationNameExtra for using-directive
329 static const DeclarationNameExtra UDirExtra =
330 { DeclarationNameExtra::CXXUsingDirective };
331
332 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
333 Ptr |= StoredDeclarationNameExtra;
334
335 return DeclarationName(Ptr);
336 }
337
dump() const338 void DeclarationName::dump() const {
339 printName(llvm::errs());
340 llvm::errs() << '\n';
341 }
342
DeclarationNameTable(const ASTContext & C)343 DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
344 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
345 CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
346
347 // Initialize the overloaded operator names.
348 CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
349 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
350 CXXOperatorNames[Op].ExtraKindOrNumArgs
351 = Op + DeclarationNameExtra::CXXConversionFunction;
352 CXXOperatorNames[Op].FETokenInfo = 0;
353 }
354 }
355
~DeclarationNameTable()356 DeclarationNameTable::~DeclarationNameTable() {
357 llvm::FoldingSet<CXXSpecialName> *SpecialNames =
358 static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
359 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
360 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
361 (CXXLiteralOperatorNames);
362
363 delete SpecialNames;
364 delete LiteralNames;
365 }
366
getCXXConstructorName(CanQualType Ty)367 DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
368 return getCXXSpecialName(DeclarationName::CXXConstructorName,
369 Ty.getUnqualifiedType());
370 }
371
getCXXDestructorName(CanQualType Ty)372 DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
373 return getCXXSpecialName(DeclarationName::CXXDestructorName,
374 Ty.getUnqualifiedType());
375 }
376
377 DeclarationName
getCXXConversionFunctionName(CanQualType Ty)378 DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
379 return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty);
380 }
381
382 DeclarationName
getCXXSpecialName(DeclarationName::NameKind Kind,CanQualType Ty)383 DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
384 CanQualType Ty) {
385 assert(Kind >= DeclarationName::CXXConstructorName &&
386 Kind <= DeclarationName::CXXConversionFunctionName &&
387 "Kind must be a C++ special name kind");
388 llvm::FoldingSet<CXXSpecialName> *SpecialNames
389 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
390
391 DeclarationNameExtra::ExtraKind EKind;
392 switch (Kind) {
393 case DeclarationName::CXXConstructorName:
394 EKind = DeclarationNameExtra::CXXConstructor;
395 assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
396 break;
397 case DeclarationName::CXXDestructorName:
398 EKind = DeclarationNameExtra::CXXDestructor;
399 assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
400 break;
401 case DeclarationName::CXXConversionFunctionName:
402 EKind = DeclarationNameExtra::CXXConversionFunction;
403 break;
404 default:
405 return DeclarationName();
406 }
407
408 // Unique selector, to guarantee there is one per name.
409 llvm::FoldingSetNodeID ID;
410 ID.AddInteger(EKind);
411 ID.AddPointer(Ty.getAsOpaquePtr());
412
413 void *InsertPos = 0;
414 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
415 return DeclarationName(Name);
416
417 CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
418 SpecialName->ExtraKindOrNumArgs = EKind;
419 SpecialName->Type = Ty;
420 SpecialName->FETokenInfo = 0;
421
422 SpecialNames->InsertNode(SpecialName, InsertPos);
423 return DeclarationName(SpecialName);
424 }
425
426 DeclarationName
getCXXOperatorName(OverloadedOperatorKind Op)427 DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
428 return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
429 }
430
431 DeclarationName
getCXXLiteralOperatorName(IdentifierInfo * II)432 DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
433 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
434 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
435 (CXXLiteralOperatorNames);
436
437 llvm::FoldingSetNodeID ID;
438 ID.AddPointer(II);
439
440 void *InsertPos = 0;
441 if (CXXLiteralOperatorIdName *Name =
442 LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
443 return DeclarationName (Name);
444
445 CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
446 LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
447 LiteralName->ID = II;
448 LiteralName->FETokenInfo = 0;
449
450 LiteralNames->InsertNode(LiteralName, InsertPos);
451 return DeclarationName(LiteralName);
452 }
453
DeclarationNameLoc(DeclarationName Name)454 DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
455 switch (Name.getNameKind()) {
456 case DeclarationName::Identifier:
457 break;
458 case DeclarationName::CXXConstructorName:
459 case DeclarationName::CXXDestructorName:
460 case DeclarationName::CXXConversionFunctionName:
461 NamedType.TInfo = 0;
462 break;
463 case DeclarationName::CXXOperatorName:
464 CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
465 CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
466 break;
467 case DeclarationName::CXXLiteralOperatorName:
468 CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
469 break;
470 case DeclarationName::ObjCZeroArgSelector:
471 case DeclarationName::ObjCOneArgSelector:
472 case DeclarationName::ObjCMultiArgSelector:
473 // FIXME: ?
474 break;
475 case DeclarationName::CXXUsingDirective:
476 break;
477 }
478 }
479
containsUnexpandedParameterPack() const480 bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
481 switch (Name.getNameKind()) {
482 case DeclarationName::Identifier:
483 case DeclarationName::ObjCZeroArgSelector:
484 case DeclarationName::ObjCOneArgSelector:
485 case DeclarationName::ObjCMultiArgSelector:
486 case DeclarationName::CXXOperatorName:
487 case DeclarationName::CXXLiteralOperatorName:
488 case DeclarationName::CXXUsingDirective:
489 return false;
490
491 case DeclarationName::CXXConstructorName:
492 case DeclarationName::CXXDestructorName:
493 case DeclarationName::CXXConversionFunctionName:
494 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
495 return TInfo->getType()->containsUnexpandedParameterPack();
496
497 return Name.getCXXNameType()->containsUnexpandedParameterPack();
498 }
499 llvm_unreachable("All name kinds handled.");
500 }
501
isInstantiationDependent() const502 bool DeclarationNameInfo::isInstantiationDependent() const {
503 switch (Name.getNameKind()) {
504 case DeclarationName::Identifier:
505 case DeclarationName::ObjCZeroArgSelector:
506 case DeclarationName::ObjCOneArgSelector:
507 case DeclarationName::ObjCMultiArgSelector:
508 case DeclarationName::CXXOperatorName:
509 case DeclarationName::CXXLiteralOperatorName:
510 case DeclarationName::CXXUsingDirective:
511 return false;
512
513 case DeclarationName::CXXConstructorName:
514 case DeclarationName::CXXDestructorName:
515 case DeclarationName::CXXConversionFunctionName:
516 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
517 return TInfo->getType()->isInstantiationDependentType();
518
519 return Name.getCXXNameType()->isInstantiationDependentType();
520 }
521 llvm_unreachable("All name kinds handled.");
522 }
523
getAsString() const524 std::string DeclarationNameInfo::getAsString() const {
525 std::string Result;
526 llvm::raw_string_ostream OS(Result);
527 printName(OS);
528 return OS.str();
529 }
530
printName(raw_ostream & OS) const531 void DeclarationNameInfo::printName(raw_ostream &OS) const {
532 switch (Name.getNameKind()) {
533 case DeclarationName::Identifier:
534 case DeclarationName::ObjCZeroArgSelector:
535 case DeclarationName::ObjCOneArgSelector:
536 case DeclarationName::ObjCMultiArgSelector:
537 case DeclarationName::CXXOperatorName:
538 case DeclarationName::CXXLiteralOperatorName:
539 case DeclarationName::CXXUsingDirective:
540 Name.printName(OS);
541 return;
542
543 case DeclarationName::CXXConstructorName:
544 case DeclarationName::CXXDestructorName:
545 case DeclarationName::CXXConversionFunctionName:
546 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
547 if (Name.getNameKind() == DeclarationName::CXXDestructorName)
548 OS << '~';
549 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
550 OS << "operator ";
551 OS << TInfo->getType().getAsString();
552 }
553 else
554 Name.printName(OS);
555 return;
556 }
557 llvm_unreachable("Unexpected declaration name kind");
558 }
559
getEndLoc() const560 SourceLocation DeclarationNameInfo::getEndLoc() const {
561 switch (Name.getNameKind()) {
562 case DeclarationName::Identifier:
563 return NameLoc;
564
565 case DeclarationName::CXXOperatorName: {
566 unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
567 return SourceLocation::getFromRawEncoding(raw);
568 }
569
570 case DeclarationName::CXXLiteralOperatorName: {
571 unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
572 return SourceLocation::getFromRawEncoding(raw);
573 }
574
575 case DeclarationName::CXXConstructorName:
576 case DeclarationName::CXXDestructorName:
577 case DeclarationName::CXXConversionFunctionName:
578 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
579 return TInfo->getTypeLoc().getEndLoc();
580 else
581 return NameLoc;
582
583 // DNInfo work in progress: FIXME.
584 case DeclarationName::ObjCZeroArgSelector:
585 case DeclarationName::ObjCOneArgSelector:
586 case DeclarationName::ObjCMultiArgSelector:
587 case DeclarationName::CXXUsingDirective:
588 return NameLoc;
589 }
590 llvm_unreachable("Unexpected declaration name kind");
591 }
592