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