• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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