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