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/DeclarationName.h"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/DeclCXX.h"
17 #include "clang/AST/DeclTemplate.h"
18 #include "clang/AST/Type.h"
19 #include "clang/AST/TypeLoc.h"
20 #include "clang/AST/TypeOrdering.h"
21 #include "clang/Basic/IdentifierTable.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 
41   void Profile(llvm::FoldingSetNodeID &ID) {
42     ID.AddInteger(ExtraKindOrNumArgs);
43     ID.AddPointer(Type.getAsOpaquePtr());
44   }
45 };
46 
47 /// Contains extra information for the name of a C++ deduction guide.
48 class CXXDeductionGuideNameExtra : public DeclarationNameExtra,
49                                    public llvm::FoldingSetNode {
50 public:
51   /// The template named by the deduction guide.
52   TemplateDecl *Template;
53 
54   /// FETokenInfo - Extra information associated with this operator
55   /// name that can be used by the front end.
56   void *FETokenInfo;
57 
58   void Profile(llvm::FoldingSetNodeID &ID) {
59     ID.AddPointer(Template);
60   }
61 };
62 
63 /// CXXOperatorIdName - Contains extra information for the name of an
64 /// overloaded operator in C++, such as "operator+.
65 class CXXOperatorIdName : public DeclarationNameExtra {
66 public:
67   /// FETokenInfo - Extra information associated with this operator
68   /// name that can be used by the front end.
69   void *FETokenInfo;
70 };
71 
72 /// CXXLiteralOperatorName - Contains the actual identifier that makes up the
73 /// name.
74 ///
75 /// This identifier is stored here rather than directly in DeclarationName so as
76 /// to allow Objective-C selectors, which are about a million times more common,
77 /// to consume minimal memory.
78 class CXXLiteralOperatorIdName
79   : public DeclarationNameExtra, public llvm::FoldingSetNode {
80 public:
81   IdentifierInfo *ID;
82 
83   /// FETokenInfo - Extra information associated with this operator
84   /// name that can be used by the front end.
85   void *FETokenInfo;
86 
87   void Profile(llvm::FoldingSetNodeID &FSID) {
88     FSID.AddPointer(ID);
89   }
90 };
91 
92 static int compareInt(unsigned A, unsigned B) {
93   return (A < B ? -1 : (A > B ? 1 : 0));
94 }
95 
96 int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
97   if (LHS.getNameKind() != RHS.getNameKind())
98     return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
99 
100   switch (LHS.getNameKind()) {
101   case DeclarationName::Identifier: {
102     IdentifierInfo *LII = LHS.getAsIdentifierInfo();
103     IdentifierInfo *RII = RHS.getAsIdentifierInfo();
104     if (!LII) return RII ? -1 : 0;
105     if (!RII) return 1;
106 
107     return LII->getName().compare(RII->getName());
108   }
109 
110   case DeclarationName::ObjCZeroArgSelector:
111   case DeclarationName::ObjCOneArgSelector:
112   case DeclarationName::ObjCMultiArgSelector: {
113     Selector LHSSelector = LHS.getObjCSelector();
114     Selector RHSSelector = RHS.getObjCSelector();
115     // getNumArgs for ZeroArgSelector returns 0, but we still need to compare.
116     if (LHS.getNameKind() == DeclarationName::ObjCZeroArgSelector &&
117         RHS.getNameKind() == DeclarationName::ObjCZeroArgSelector) {
118       return LHSSelector.getAsIdentifierInfo()->getName().compare(
119              RHSSelector.getAsIdentifierInfo()->getName());
120     }
121     unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
122     for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
123       switch (LHSSelector.getNameForSlot(I).compare(
124                                                RHSSelector.getNameForSlot(I))) {
125       case -1: return -1;
126       case 1: return 1;
127       default: break;
128       }
129     }
130 
131     return compareInt(LN, RN);
132   }
133 
134   case DeclarationName::CXXConstructorName:
135   case DeclarationName::CXXDestructorName:
136   case DeclarationName::CXXConversionFunctionName:
137     if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
138       return -1;
139     if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
140       return 1;
141     return 0;
142 
143   case DeclarationName::CXXDeductionGuideName:
144     // We never want to compare deduction guide names for templates from
145     // different scopes, so just compare the template-name.
146     return compare(LHS.getCXXDeductionGuideTemplate()->getDeclName(),
147                    RHS.getCXXDeductionGuideTemplate()->getDeclName());
148 
149   case DeclarationName::CXXOperatorName:
150     return compareInt(LHS.getCXXOverloadedOperator(),
151                       RHS.getCXXOverloadedOperator());
152 
153   case DeclarationName::CXXLiteralOperatorName:
154     return LHS.getCXXLiteralIdentifier()->getName().compare(
155                                    RHS.getCXXLiteralIdentifier()->getName());
156 
157   case DeclarationName::CXXUsingDirective:
158     return 0;
159   }
160 
161   llvm_unreachable("Invalid DeclarationName Kind!");
162 }
163 
164 static void printCXXConstructorDestructorName(QualType ClassType,
165                                               raw_ostream &OS,
166                                               PrintingPolicy Policy) {
167   // We know we're printing C++ here. Ensure we print types properly.
168   Policy.adjustForCPlusPlus();
169 
170   if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) {
171     OS << *ClassRec->getDecl();
172     return;
173   }
174   if (Policy.SuppressTemplateArgsInCXXConstructors) {
175     if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) {
176       OS << *InjTy->getDecl();
177       return;
178     }
179   }
180   ClassType.print(OS, Policy);
181 }
182 
183 void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) {
184   DeclarationName &N = *this;
185   switch (N.getNameKind()) {
186   case DeclarationName::Identifier:
187     if (const IdentifierInfo *II = N.getAsIdentifierInfo())
188       OS << II->getName();
189     return;
190 
191   case DeclarationName::ObjCZeroArgSelector:
192   case DeclarationName::ObjCOneArgSelector:
193   case DeclarationName::ObjCMultiArgSelector:
194     N.getObjCSelector().print(OS);
195     return;
196 
197   case DeclarationName::CXXConstructorName:
198     return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy);
199 
200   case DeclarationName::CXXDestructorName: {
201     OS << '~';
202     return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy);
203   }
204 
205   case DeclarationName::CXXDeductionGuideName:
206     return getCXXDeductionGuideTemplate()->getDeclName().print(OS, Policy);
207 
208   case DeclarationName::CXXOperatorName: {
209     static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
210       nullptr,
211 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
212       Spelling,
213 #include "clang/Basic/OperatorKinds.def"
214     };
215     const char *OpName = OperatorNames[N.getCXXOverloadedOperator()];
216     assert(OpName && "not an overloaded operator");
217 
218     OS << "operator";
219     if (OpName[0] >= 'a' && OpName[0] <= 'z')
220       OS << ' ';
221     OS << OpName;
222     return;
223   }
224 
225   case DeclarationName::CXXLiteralOperatorName:
226     OS << "operator\"\"" << N.getCXXLiteralIdentifier()->getName();
227     return;
228 
229   case DeclarationName::CXXConversionFunctionName: {
230     OS << "operator ";
231     QualType Type = N.getCXXNameType();
232     if (const RecordType *Rec = Type->getAs<RecordType>()) {
233       OS << *Rec->getDecl();
234       return;
235     }
236     // We know we're printing C++ here, ensure we print 'bool' properly.
237     PrintingPolicy CXXPolicy = Policy;
238     CXXPolicy.adjustForCPlusPlus();
239     Type.print(OS, CXXPolicy);
240     return;
241   }
242   case DeclarationName::CXXUsingDirective:
243     OS << "<using-directive>";
244     return;
245   }
246 
247   llvm_unreachable("Unexpected declaration name kind");
248 }
249 
250 raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
251   LangOptions LO;
252   N.print(OS, PrintingPolicy(LO));
253   return OS;
254 }
255 
256 } // end namespace clang
257 
258 DeclarationName::NameKind DeclarationName::getNameKind() const {
259   switch (getStoredNameKind()) {
260   case StoredIdentifier:          return Identifier;
261   case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
262   case StoredObjCOneArgSelector:  return ObjCOneArgSelector;
263 
264   case StoredDeclarationNameExtra:
265     switch (getExtra()->ExtraKindOrNumArgs) {
266     case DeclarationNameExtra::CXXConstructor:
267       return CXXConstructorName;
268 
269     case DeclarationNameExtra::CXXDestructor:
270       return CXXDestructorName;
271 
272     case DeclarationNameExtra::CXXDeductionGuide:
273       return CXXDeductionGuideName;
274 
275     case DeclarationNameExtra::CXXConversionFunction:
276       return CXXConversionFunctionName;
277 
278     case DeclarationNameExtra::CXXLiteralOperator:
279       return CXXLiteralOperatorName;
280 
281     case DeclarationNameExtra::CXXUsingDirective:
282       return CXXUsingDirective;
283 
284     default:
285       // Check if we have one of the CXXOperator* enumeration values.
286       if (getExtra()->ExtraKindOrNumArgs <
287             DeclarationNameExtra::CXXUsingDirective)
288         return CXXOperatorName;
289 
290       return ObjCMultiArgSelector;
291     }
292   }
293 
294   // Can't actually get here.
295   llvm_unreachable("This should be unreachable!");
296 }
297 
298 bool DeclarationName::isDependentName() const {
299   QualType T = getCXXNameType();
300   if (!T.isNull() && T->isDependentType())
301     return true;
302 
303   // A class-scope deduction guide in a dependent context has a dependent name.
304   auto *TD = getCXXDeductionGuideTemplate();
305   if (TD && TD->getDeclContext()->isDependentContext())
306     return true;
307 
308   return false;
309 }
310 
311 std::string DeclarationName::getAsString() const {
312   std::string Result;
313   llvm::raw_string_ostream OS(Result);
314   OS << *this;
315   return OS.str();
316 }
317 
318 QualType DeclarationName::getCXXNameType() const {
319   if (CXXSpecialName *CXXName = getAsCXXSpecialName())
320     return CXXName->Type;
321   else
322     return QualType();
323 }
324 
325 TemplateDecl *DeclarationName::getCXXDeductionGuideTemplate() const {
326   if (auto *Guide = getAsCXXDeductionGuideNameExtra())
327     return Guide->Template;
328   return nullptr;
329 }
330 
331 OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
332   if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
333     unsigned value
334       = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
335     return static_cast<OverloadedOperatorKind>(value);
336   } else {
337     return OO_None;
338   }
339 }
340 
341 IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
342   if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
343     return CXXLit->ID;
344   else
345     return nullptr;
346 }
347 
348 void *DeclarationName::getFETokenInfoAsVoidSlow() const {
349   switch (getNameKind()) {
350   case Identifier:
351     llvm_unreachable("Handled by getFETokenInfo()");
352 
353   case CXXConstructorName:
354   case CXXDestructorName:
355   case CXXConversionFunctionName:
356     return getAsCXXSpecialName()->FETokenInfo;
357 
358   case CXXDeductionGuideName:
359     return getAsCXXDeductionGuideNameExtra()->FETokenInfo;
360 
361   case CXXOperatorName:
362     return getAsCXXOperatorIdName()->FETokenInfo;
363 
364   case CXXLiteralOperatorName:
365     return getAsCXXLiteralOperatorIdName()->FETokenInfo;
366 
367   default:
368     llvm_unreachable("Declaration name has no FETokenInfo");
369   }
370 }
371 
372 void DeclarationName::setFETokenInfo(void *T) {
373   switch (getNameKind()) {
374   case Identifier:
375     getAsIdentifierInfo()->setFETokenInfo(T);
376     break;
377 
378   case CXXConstructorName:
379   case CXXDestructorName:
380   case CXXConversionFunctionName:
381     getAsCXXSpecialName()->FETokenInfo = T;
382     break;
383 
384   case CXXDeductionGuideName:
385     getAsCXXDeductionGuideNameExtra()->FETokenInfo = T;
386     break;
387 
388   case CXXOperatorName:
389     getAsCXXOperatorIdName()->FETokenInfo = T;
390     break;
391 
392   case CXXLiteralOperatorName:
393     getAsCXXLiteralOperatorIdName()->FETokenInfo = T;
394     break;
395 
396   default:
397     llvm_unreachable("Declaration name has no FETokenInfo");
398   }
399 }
400 
401 DeclarationName DeclarationName::getUsingDirectiveName() {
402   // Single instance of DeclarationNameExtra for using-directive
403   static const DeclarationNameExtra UDirExtra =
404     { DeclarationNameExtra::CXXUsingDirective };
405 
406   uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
407   Ptr |= StoredDeclarationNameExtra;
408 
409   return DeclarationName(Ptr);
410 }
411 
412 LLVM_DUMP_METHOD void DeclarationName::dump() const {
413   llvm::errs() << *this << '\n';
414 }
415 
416 DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
417   CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
418   CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
419   CXXDeductionGuideNames = new llvm::FoldingSet<CXXDeductionGuideNameExtra>;
420 
421   // Initialize the overloaded operator names.
422   CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
423   for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
424     CXXOperatorNames[Op].ExtraKindOrNumArgs
425       = Op + DeclarationNameExtra::CXXConversionFunction;
426     CXXOperatorNames[Op].FETokenInfo = nullptr;
427   }
428 }
429 
430 DeclarationNameTable::~DeclarationNameTable() {
431   auto *SpecialNames =
432       static_cast<llvm::FoldingSet<CXXSpecialName> *>(CXXSpecialNamesImpl);
433   auto *LiteralNames =
434       static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName> *>(
435           CXXLiteralOperatorNames);
436   auto *DeductionGuideNames =
437       static_cast<llvm::FoldingSet<CXXDeductionGuideNameExtra> *>(
438           CXXDeductionGuideNames);
439 
440   delete SpecialNames;
441   delete LiteralNames;
442   delete DeductionGuideNames;
443 }
444 
445 DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
446   return getCXXSpecialName(DeclarationName::CXXConstructorName,
447                            Ty.getUnqualifiedType());
448 }
449 
450 DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
451   return getCXXSpecialName(DeclarationName::CXXDestructorName,
452                            Ty.getUnqualifiedType());
453 }
454 
455 DeclarationName
456 DeclarationNameTable::getCXXDeductionGuideName(TemplateDecl *Template) {
457   Template = cast<TemplateDecl>(Template->getCanonicalDecl());
458 
459   auto *DeductionGuideNames =
460       static_cast<llvm::FoldingSet<CXXDeductionGuideNameExtra> *>(
461           CXXDeductionGuideNames);
462 
463   llvm::FoldingSetNodeID ID;
464   ID.AddPointer(Template);
465 
466   void *InsertPos = nullptr;
467   if (auto *Name = DeductionGuideNames->FindNodeOrInsertPos(ID, InsertPos))
468     return DeclarationName(Name);
469 
470   auto *Name = new (Ctx) CXXDeductionGuideNameExtra;
471   Name->ExtraKindOrNumArgs = DeclarationNameExtra::CXXDeductionGuide;
472   Name->Template = Template;
473   Name->FETokenInfo = nullptr;
474 
475   DeductionGuideNames->InsertNode(Name, InsertPos);
476   return DeclarationName(Name);
477 }
478 
479 DeclarationName
480 DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
481   return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty);
482 }
483 
484 DeclarationName
485 DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
486                                         CanQualType Ty) {
487   assert(Kind >= DeclarationName::CXXConstructorName &&
488          Kind <= DeclarationName::CXXConversionFunctionName &&
489          "Kind must be a C++ special name kind");
490   llvm::FoldingSet<CXXSpecialName> *SpecialNames
491     = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
492 
493   DeclarationNameExtra::ExtraKind EKind;
494   switch (Kind) {
495   case DeclarationName::CXXConstructorName:
496     EKind = DeclarationNameExtra::CXXConstructor;
497     assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
498     break;
499   case DeclarationName::CXXDestructorName:
500     EKind = DeclarationNameExtra::CXXDestructor;
501     assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
502     break;
503   case DeclarationName::CXXConversionFunctionName:
504     EKind = DeclarationNameExtra::CXXConversionFunction;
505     break;
506   default:
507     return DeclarationName();
508   }
509 
510   // Unique selector, to guarantee there is one per name.
511   llvm::FoldingSetNodeID ID;
512   ID.AddInteger(EKind);
513   ID.AddPointer(Ty.getAsOpaquePtr());
514 
515   void *InsertPos = nullptr;
516   if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
517     return DeclarationName(Name);
518 
519   CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
520   SpecialName->ExtraKindOrNumArgs = EKind;
521   SpecialName->Type = Ty;
522   SpecialName->FETokenInfo = nullptr;
523 
524   SpecialNames->InsertNode(SpecialName, InsertPos);
525   return DeclarationName(SpecialName);
526 }
527 
528 DeclarationName
529 DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
530   return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
531 }
532 
533 DeclarationName
534 DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
535   llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
536     = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
537                                                       (CXXLiteralOperatorNames);
538 
539   llvm::FoldingSetNodeID ID;
540   ID.AddPointer(II);
541 
542   void *InsertPos = nullptr;
543   if (CXXLiteralOperatorIdName *Name =
544                                LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
545     return DeclarationName (Name);
546 
547   CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
548   LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
549   LiteralName->ID = II;
550   LiteralName->FETokenInfo = nullptr;
551 
552   LiteralNames->InsertNode(LiteralName, InsertPos);
553   return DeclarationName(LiteralName);
554 }
555 
556 DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
557   switch (Name.getNameKind()) {
558   case DeclarationName::Identifier:
559   case DeclarationName::CXXDeductionGuideName:
560     break;
561   case DeclarationName::CXXConstructorName:
562   case DeclarationName::CXXDestructorName:
563   case DeclarationName::CXXConversionFunctionName:
564     NamedType.TInfo = nullptr;
565     break;
566   case DeclarationName::CXXOperatorName:
567     CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
568     CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
569     break;
570   case DeclarationName::CXXLiteralOperatorName:
571     CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
572     break;
573   case DeclarationName::ObjCZeroArgSelector:
574   case DeclarationName::ObjCOneArgSelector:
575   case DeclarationName::ObjCMultiArgSelector:
576     // FIXME: ?
577     break;
578   case DeclarationName::CXXUsingDirective:
579     break;
580   }
581 }
582 
583 bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
584   switch (Name.getNameKind()) {
585   case DeclarationName::Identifier:
586   case DeclarationName::ObjCZeroArgSelector:
587   case DeclarationName::ObjCOneArgSelector:
588   case DeclarationName::ObjCMultiArgSelector:
589   case DeclarationName::CXXOperatorName:
590   case DeclarationName::CXXLiteralOperatorName:
591   case DeclarationName::CXXUsingDirective:
592   case DeclarationName::CXXDeductionGuideName:
593     return false;
594 
595   case DeclarationName::CXXConstructorName:
596   case DeclarationName::CXXDestructorName:
597   case DeclarationName::CXXConversionFunctionName:
598     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
599       return TInfo->getType()->containsUnexpandedParameterPack();
600 
601     return Name.getCXXNameType()->containsUnexpandedParameterPack();
602   }
603   llvm_unreachable("All name kinds handled.");
604 }
605 
606 bool DeclarationNameInfo::isInstantiationDependent() const {
607   switch (Name.getNameKind()) {
608   case DeclarationName::Identifier:
609   case DeclarationName::ObjCZeroArgSelector:
610   case DeclarationName::ObjCOneArgSelector:
611   case DeclarationName::ObjCMultiArgSelector:
612   case DeclarationName::CXXOperatorName:
613   case DeclarationName::CXXLiteralOperatorName:
614   case DeclarationName::CXXUsingDirective:
615   case DeclarationName::CXXDeductionGuideName:
616     return false;
617 
618   case DeclarationName::CXXConstructorName:
619   case DeclarationName::CXXDestructorName:
620   case DeclarationName::CXXConversionFunctionName:
621     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
622       return TInfo->getType()->isInstantiationDependentType();
623 
624     return Name.getCXXNameType()->isInstantiationDependentType();
625   }
626   llvm_unreachable("All name kinds handled.");
627 }
628 
629 std::string DeclarationNameInfo::getAsString() const {
630   std::string Result;
631   llvm::raw_string_ostream OS(Result);
632   printName(OS);
633   return OS.str();
634 }
635 
636 void DeclarationNameInfo::printName(raw_ostream &OS) const {
637   switch (Name.getNameKind()) {
638   case DeclarationName::Identifier:
639   case DeclarationName::ObjCZeroArgSelector:
640   case DeclarationName::ObjCOneArgSelector:
641   case DeclarationName::ObjCMultiArgSelector:
642   case DeclarationName::CXXOperatorName:
643   case DeclarationName::CXXLiteralOperatorName:
644   case DeclarationName::CXXUsingDirective:
645   case DeclarationName::CXXDeductionGuideName:
646     OS << Name;
647     return;
648 
649   case DeclarationName::CXXConstructorName:
650   case DeclarationName::CXXDestructorName:
651   case DeclarationName::CXXConversionFunctionName:
652     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
653       if (Name.getNameKind() == DeclarationName::CXXDestructorName)
654         OS << '~';
655       else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
656         OS << "operator ";
657       LangOptions LO;
658       LO.CPlusPlus = true;
659       LO.Bool = true;
660       OS << TInfo->getType().getAsString(PrintingPolicy(LO));
661     } else
662       OS << Name;
663     return;
664   }
665   llvm_unreachable("Unexpected declaration name kind");
666 }
667 
668 SourceLocation DeclarationNameInfo::getEndLoc() const {
669   switch (Name.getNameKind()) {
670   case DeclarationName::Identifier:
671   case DeclarationName::CXXDeductionGuideName:
672     return NameLoc;
673 
674   case DeclarationName::CXXOperatorName: {
675     unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
676     return SourceLocation::getFromRawEncoding(raw);
677   }
678 
679   case DeclarationName::CXXLiteralOperatorName: {
680     unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
681     return SourceLocation::getFromRawEncoding(raw);
682   }
683 
684   case DeclarationName::CXXConstructorName:
685   case DeclarationName::CXXDestructorName:
686   case DeclarationName::CXXConversionFunctionName:
687     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
688       return TInfo->getTypeLoc().getEndLoc();
689     else
690       return NameLoc;
691 
692     // DNInfo work in progress: FIXME.
693   case DeclarationName::ObjCZeroArgSelector:
694   case DeclarationName::ObjCOneArgSelector:
695   case DeclarationName::ObjCMultiArgSelector:
696   case DeclarationName::CXXUsingDirective:
697     return NameLoc;
698   }
699   llvm_unreachable("Unexpected declaration name kind");
700 }
701