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