Home | History | Annotate | Download | only in AST
      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 
     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 
     71   void Profile(llvm::FoldingSetNodeID &FSID) {
     72     FSID.AddPointer(ID);
     73   }
     74 };
     75 
     76 static int compareInt(unsigned A, unsigned B) {
     77   return (A < B ? -1 : (A > B ? 1 : 0));
     78 }
     79 
     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 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 
    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 
    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 
    227 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 
    264 bool DeclarationName::isDependentName() const {
    265   QualType T = getCXXNameType();
    266   return !T.isNull() && T->isDependentType();
    267 }
    268 
    269 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 
    276 QualType DeclarationName::getCXXNameType() const {
    277   if (CXXSpecialName *CXXName = getAsCXXSpecialName())
    278     return CXXName->Type;
    279   else
    280     return QualType();
    281 }
    282 
    283 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 
    293 IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
    294   if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
    295     return CXXLit->ID;
    296   else
    297     return nullptr;
    298 }
    299 
    300 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 
    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 
    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 
    357 LLVM_DUMP_METHOD void DeclarationName::dump() const {
    358   llvm::errs() << *this << '\n';
    359 }
    360 
    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 
    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 
    385 DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
    386   return getCXXSpecialName(DeclarationName::CXXConstructorName,
    387                            Ty.getUnqualifiedType());
    388 }
    389 
    390 DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
    391   return getCXXSpecialName(DeclarationName::CXXDestructorName,
    392                            Ty.getUnqualifiedType());
    393 }
    394 
    395 DeclarationName
    396 DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
    397   return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty);
    398 }
    399 
    400 DeclarationName
    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
    445 DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
    446   return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
    447 }
    448 
    449 DeclarationName
    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 
    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 
    498 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 
    520 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 
    542 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 
    549 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 
    580 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