clang API Documentation

DeclarationName.cpp
Go to the documentation of this file.
00001 //===-- DeclarationName.cpp - Declaration names implementation --*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements the DeclarationName and DeclarationNameTable
00011 // classes.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 #include "clang/AST/ASTContext.h"
00015 #include "clang/AST/Decl.h"
00016 #include "clang/AST/DeclarationName.h"
00017 #include "clang/AST/Type.h"
00018 #include "clang/AST/TypeLoc.h"
00019 #include "clang/AST/TypeOrdering.h"
00020 #include "clang/Basic/IdentifierTable.h"
00021 #include "llvm/ADT/DenseMap.h"
00022 #include "llvm/ADT/FoldingSet.h"
00023 #include "llvm/Support/ErrorHandling.h"
00024 #include "llvm/Support/raw_ostream.h"
00025 using namespace clang;
00026 
00027 namespace clang {
00028 /// CXXSpecialName - Records the type associated with one of the
00029 /// "special" kinds of declaration names in C++, e.g., constructors,
00030 /// destructors, and conversion functions.
00031 class CXXSpecialName
00032   : public DeclarationNameExtra, public llvm::FoldingSetNode {
00033 public:
00034   /// Type - The type associated with this declaration name.
00035   QualType Type;
00036 
00037   /// FETokenInfo - Extra information associated with this declaration
00038   /// name that can be used by the front end.
00039   void *FETokenInfo;
00040 
00041   void Profile(llvm::FoldingSetNodeID &ID) {
00042     ID.AddInteger(ExtraKindOrNumArgs);
00043     ID.AddPointer(Type.getAsOpaquePtr());
00044   }
00045 };
00046 
00047 /// CXXOperatorIdName - Contains extra information for the name of an
00048 /// overloaded operator in C++, such as "operator+.
00049 class CXXOperatorIdName : public DeclarationNameExtra {
00050 public:
00051   /// FETokenInfo - Extra information associated with this operator
00052   /// name that can be used by the front end.
00053   void *FETokenInfo;
00054 };
00055 
00056 /// CXXLiteralOperatorName - Contains the actual identifier that makes up the
00057 /// name.
00058 ///
00059 /// This identifier is stored here rather than directly in DeclarationName so as
00060 /// to allow Objective-C selectors, which are about a million times more common,
00061 /// to consume minimal memory.
00062 class CXXLiteralOperatorIdName
00063   : public DeclarationNameExtra, public llvm::FoldingSetNode {
00064 public:
00065   IdentifierInfo *ID;
00066 
00067   /// FETokenInfo - Extra information associated with this operator
00068   /// name that can be used by the front end.
00069   void *FETokenInfo;
00070 
00071   void Profile(llvm::FoldingSetNodeID &FSID) {
00072     FSID.AddPointer(ID);
00073   }
00074 };
00075 
00076 static int compareInt(unsigned A, unsigned B) {
00077   return (A < B ? -1 : (A > B ? 1 : 0));
00078 }
00079 
00080 int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
00081   if (LHS.getNameKind() != RHS.getNameKind())
00082     return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
00083   
00084   switch (LHS.getNameKind()) {
00085   case DeclarationName::Identifier: {
00086     IdentifierInfo *LII = LHS.getAsIdentifierInfo();
00087     IdentifierInfo *RII = RHS.getAsIdentifierInfo();
00088     if (!LII) return RII ? -1 : 0;
00089     if (!RII) return 1;
00090     
00091     return LII->getName().compare(RII->getName());
00092   }
00093 
00094   case DeclarationName::ObjCZeroArgSelector:
00095   case DeclarationName::ObjCOneArgSelector:
00096   case DeclarationName::ObjCMultiArgSelector: {
00097     Selector LHSSelector = LHS.getObjCSelector();
00098     Selector RHSSelector = RHS.getObjCSelector();
00099     unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
00100     for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
00101       switch (LHSSelector.getNameForSlot(I).compare(
00102                                                RHSSelector.getNameForSlot(I))) {
00103       case -1: return true;
00104       case 1: return false;
00105       default: break;
00106       }
00107     }
00108 
00109     return compareInt(LN, RN);
00110   }
00111   
00112   case DeclarationName::CXXConstructorName:
00113   case DeclarationName::CXXDestructorName:
00114   case DeclarationName::CXXConversionFunctionName:
00115     if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
00116       return -1;
00117     if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
00118       return 1;
00119     return 0;
00120               
00121   case DeclarationName::CXXOperatorName:
00122     return compareInt(LHS.getCXXOverloadedOperator(),
00123                       RHS.getCXXOverloadedOperator());
00124 
00125   case DeclarationName::CXXLiteralOperatorName:
00126     return LHS.getCXXLiteralIdentifier()->getName().compare(
00127                                    RHS.getCXXLiteralIdentifier()->getName());
00128               
00129   case DeclarationName::CXXUsingDirective:
00130     return 0;
00131   }
00132 
00133   llvm_unreachable("Invalid DeclarationName Kind!");
00134 }
00135 
00136 raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
00137   switch (N.getNameKind()) {
00138   case DeclarationName::Identifier:
00139     if (const IdentifierInfo *II = N.getAsIdentifierInfo())
00140       OS << II->getName();
00141     return OS;
00142 
00143   case DeclarationName::ObjCZeroArgSelector:
00144   case DeclarationName::ObjCOneArgSelector:
00145   case DeclarationName::ObjCMultiArgSelector:
00146     N.getObjCSelector().print(OS);
00147     return OS;
00148 
00149   case DeclarationName::CXXConstructorName: {
00150     QualType ClassType = N.getCXXNameType();
00151     if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
00152       return OS << *ClassRec->getDecl();
00153     LangOptions LO;
00154     LO.CPlusPlus = true;
00155     return OS << ClassType.getAsString(PrintingPolicy(LO));
00156   }
00157 
00158   case DeclarationName::CXXDestructorName: {
00159     OS << '~';
00160     QualType Type = N.getCXXNameType();
00161     if (const RecordType *Rec = Type->getAs<RecordType>())
00162       return OS << *Rec->getDecl();
00163     LangOptions LO;
00164     LO.CPlusPlus = true;
00165     return OS << Type.getAsString(PrintingPolicy(LO));
00166   }
00167 
00168   case DeclarationName::CXXOperatorName: {
00169     static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
00170       nullptr,
00171 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
00172       Spelling,
00173 #include "clang/Basic/OperatorKinds.def"
00174     };
00175     const char *OpName = OperatorNames[N.getCXXOverloadedOperator()];
00176     assert(OpName && "not an overloaded operator");
00177 
00178     OS << "operator";
00179     if (OpName[0] >= 'a' && OpName[0] <= 'z')
00180       OS << ' ';
00181     return OS << OpName;
00182   }
00183 
00184   case DeclarationName::CXXLiteralOperatorName:
00185     return OS << "operator \"\" " << N.getCXXLiteralIdentifier()->getName();
00186 
00187   case DeclarationName::CXXConversionFunctionName: {
00188     OS << "operator ";
00189     QualType Type = N.getCXXNameType();
00190     if (const RecordType *Rec = Type->getAs<RecordType>())
00191       return OS << *Rec->getDecl();
00192     LangOptions LO;
00193     LO.CPlusPlus = true;
00194     LO.Bool = true;
00195     return OS << Type.getAsString(PrintingPolicy(LO));
00196   }
00197   case DeclarationName::CXXUsingDirective:
00198     return OS << "<using-directive>";
00199   }
00200 
00201   llvm_unreachable("Unexpected declaration name kind");
00202 }
00203 
00204 } // end namespace clang
00205 
00206 DeclarationName::NameKind DeclarationName::getNameKind() const {
00207   switch (getStoredNameKind()) {
00208   case StoredIdentifier:          return Identifier;
00209   case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
00210   case StoredObjCOneArgSelector:  return ObjCOneArgSelector;
00211 
00212   case StoredDeclarationNameExtra:
00213     switch (getExtra()->ExtraKindOrNumArgs) {
00214     case DeclarationNameExtra::CXXConstructor:
00215       return CXXConstructorName;
00216 
00217     case DeclarationNameExtra::CXXDestructor:
00218       return CXXDestructorName;
00219 
00220     case DeclarationNameExtra::CXXConversionFunction:
00221       return CXXConversionFunctionName;
00222 
00223     case DeclarationNameExtra::CXXLiteralOperator:
00224       return CXXLiteralOperatorName;
00225 
00226     case DeclarationNameExtra::CXXUsingDirective:
00227       return CXXUsingDirective;
00228 
00229     default:
00230       // Check if we have one of the CXXOperator* enumeration values.
00231       if (getExtra()->ExtraKindOrNumArgs <
00232             DeclarationNameExtra::CXXUsingDirective)
00233         return CXXOperatorName;
00234 
00235       return ObjCMultiArgSelector;
00236     }
00237   }
00238 
00239   // Can't actually get here.
00240   llvm_unreachable("This should be unreachable!");
00241 }
00242 
00243 bool DeclarationName::isDependentName() const {
00244   QualType T = getCXXNameType();
00245   return !T.isNull() && T->isDependentType();
00246 }
00247 
00248 std::string DeclarationName::getAsString() const {
00249   std::string Result;
00250   llvm::raw_string_ostream OS(Result);
00251   OS << *this;
00252   return OS.str();
00253 }
00254 
00255 QualType DeclarationName::getCXXNameType() const {
00256   if (CXXSpecialName *CXXName = getAsCXXSpecialName())
00257     return CXXName->Type;
00258   else
00259     return QualType();
00260 }
00261 
00262 OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
00263   if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
00264     unsigned value
00265       = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
00266     return static_cast<OverloadedOperatorKind>(value);
00267   } else {
00268     return OO_None;
00269   }
00270 }
00271 
00272 IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
00273   if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
00274     return CXXLit->ID;
00275   else
00276     return nullptr;
00277 }
00278 
00279 void *DeclarationName::getFETokenInfoAsVoidSlow() const {
00280   switch (getNameKind()) {
00281   case Identifier:
00282     llvm_unreachable("Handled by getFETokenInfo()");
00283 
00284   case CXXConstructorName:
00285   case CXXDestructorName:
00286   case CXXConversionFunctionName:
00287     return getAsCXXSpecialName()->FETokenInfo;
00288 
00289   case CXXOperatorName:
00290     return getAsCXXOperatorIdName()->FETokenInfo;
00291 
00292   case CXXLiteralOperatorName:
00293     return getAsCXXLiteralOperatorIdName()->FETokenInfo;
00294 
00295   default:
00296     llvm_unreachable("Declaration name has no FETokenInfo");
00297   }
00298 }
00299 
00300 void DeclarationName::setFETokenInfo(void *T) {
00301   switch (getNameKind()) {
00302   case Identifier:
00303     getAsIdentifierInfo()->setFETokenInfo(T);
00304     break;
00305 
00306   case CXXConstructorName:
00307   case CXXDestructorName:
00308   case CXXConversionFunctionName:
00309     getAsCXXSpecialName()->FETokenInfo = T;
00310     break;
00311 
00312   case CXXOperatorName:
00313     getAsCXXOperatorIdName()->FETokenInfo = T;
00314     break;
00315 
00316   case CXXLiteralOperatorName:
00317     getAsCXXLiteralOperatorIdName()->FETokenInfo = T;
00318     break;
00319 
00320   default:
00321     llvm_unreachable("Declaration name has no FETokenInfo");
00322   }
00323 }
00324 
00325 DeclarationName DeclarationName::getUsingDirectiveName() {
00326   // Single instance of DeclarationNameExtra for using-directive
00327   static const DeclarationNameExtra UDirExtra =
00328     { DeclarationNameExtra::CXXUsingDirective };
00329 
00330   uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
00331   Ptr |= StoredDeclarationNameExtra;
00332 
00333   return DeclarationName(Ptr);
00334 }
00335 
00336 void DeclarationName::dump() const {
00337   llvm::errs() << *this << '\n';
00338 }
00339 
00340 DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
00341   CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
00342   CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
00343 
00344   // Initialize the overloaded operator names.
00345   CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
00346   for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
00347     CXXOperatorNames[Op].ExtraKindOrNumArgs
00348       = Op + DeclarationNameExtra::CXXConversionFunction;
00349     CXXOperatorNames[Op].FETokenInfo = nullptr;
00350   }
00351 }
00352 
00353 DeclarationNameTable::~DeclarationNameTable() {
00354   llvm::FoldingSet<CXXSpecialName> *SpecialNames =
00355     static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
00356   llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
00357     = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
00358         (CXXLiteralOperatorNames);
00359 
00360   delete SpecialNames;
00361   delete LiteralNames;
00362 }
00363 
00364 DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
00365   return getCXXSpecialName(DeclarationName::CXXConstructorName,
00366                            Ty.getUnqualifiedType());
00367 }
00368 
00369 DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
00370   return getCXXSpecialName(DeclarationName::CXXDestructorName,
00371                            Ty.getUnqualifiedType());
00372 }
00373 
00374 DeclarationName
00375 DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
00376   return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty);
00377 }
00378 
00379 DeclarationName
00380 DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
00381                                         CanQualType Ty) {
00382   assert(Kind >= DeclarationName::CXXConstructorName &&
00383          Kind <= DeclarationName::CXXConversionFunctionName &&
00384          "Kind must be a C++ special name kind");
00385   llvm::FoldingSet<CXXSpecialName> *SpecialNames
00386     = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
00387 
00388   DeclarationNameExtra::ExtraKind EKind;
00389   switch (Kind) {
00390   case DeclarationName::CXXConstructorName:
00391     EKind = DeclarationNameExtra::CXXConstructor;
00392     assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
00393     break;
00394   case DeclarationName::CXXDestructorName:
00395     EKind = DeclarationNameExtra::CXXDestructor;
00396     assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
00397     break;
00398   case DeclarationName::CXXConversionFunctionName:
00399     EKind = DeclarationNameExtra::CXXConversionFunction;
00400     break;
00401   default:
00402     return DeclarationName();
00403   }
00404 
00405   // Unique selector, to guarantee there is one per name.
00406   llvm::FoldingSetNodeID ID;
00407   ID.AddInteger(EKind);
00408   ID.AddPointer(Ty.getAsOpaquePtr());
00409 
00410   void *InsertPos = nullptr;
00411   if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
00412     return DeclarationName(Name);
00413 
00414   CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
00415   SpecialName->ExtraKindOrNumArgs = EKind;
00416   SpecialName->Type = Ty;
00417   SpecialName->FETokenInfo = nullptr;
00418 
00419   SpecialNames->InsertNode(SpecialName, InsertPos);
00420   return DeclarationName(SpecialName);
00421 }
00422 
00423 DeclarationName
00424 DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
00425   return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
00426 }
00427 
00428 DeclarationName
00429 DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
00430   llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
00431     = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
00432                                                       (CXXLiteralOperatorNames);
00433 
00434   llvm::FoldingSetNodeID ID;
00435   ID.AddPointer(II);
00436 
00437   void *InsertPos = nullptr;
00438   if (CXXLiteralOperatorIdName *Name =
00439                                LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
00440     return DeclarationName (Name);
00441   
00442   CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
00443   LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
00444   LiteralName->ID = II;
00445   LiteralName->FETokenInfo = nullptr;
00446 
00447   LiteralNames->InsertNode(LiteralName, InsertPos);
00448   return DeclarationName(LiteralName);
00449 }
00450 
00451 DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
00452   switch (Name.getNameKind()) {
00453   case DeclarationName::Identifier:
00454     break;
00455   case DeclarationName::CXXConstructorName:
00456   case DeclarationName::CXXDestructorName:
00457   case DeclarationName::CXXConversionFunctionName:
00458     NamedType.TInfo = nullptr;
00459     break;
00460   case DeclarationName::CXXOperatorName:
00461     CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
00462     CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
00463     break;
00464   case DeclarationName::CXXLiteralOperatorName:
00465     CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
00466     break;
00467   case DeclarationName::ObjCZeroArgSelector:
00468   case DeclarationName::ObjCOneArgSelector:
00469   case DeclarationName::ObjCMultiArgSelector:
00470     // FIXME: ?
00471     break;
00472   case DeclarationName::CXXUsingDirective:
00473     break;
00474   }
00475 }
00476 
00477 bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
00478   switch (Name.getNameKind()) {
00479   case DeclarationName::Identifier:
00480   case DeclarationName::ObjCZeroArgSelector:
00481   case DeclarationName::ObjCOneArgSelector:
00482   case DeclarationName::ObjCMultiArgSelector:
00483   case DeclarationName::CXXOperatorName:
00484   case DeclarationName::CXXLiteralOperatorName:
00485   case DeclarationName::CXXUsingDirective:
00486     return false;
00487 
00488   case DeclarationName::CXXConstructorName:
00489   case DeclarationName::CXXDestructorName:
00490   case DeclarationName::CXXConversionFunctionName:
00491     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
00492       return TInfo->getType()->containsUnexpandedParameterPack();
00493 
00494     return Name.getCXXNameType()->containsUnexpandedParameterPack();
00495   }
00496   llvm_unreachable("All name kinds handled.");
00497 }
00498 
00499 bool DeclarationNameInfo::isInstantiationDependent() const {
00500   switch (Name.getNameKind()) {
00501   case DeclarationName::Identifier:
00502   case DeclarationName::ObjCZeroArgSelector:
00503   case DeclarationName::ObjCOneArgSelector:
00504   case DeclarationName::ObjCMultiArgSelector:
00505   case DeclarationName::CXXOperatorName:
00506   case DeclarationName::CXXLiteralOperatorName:
00507   case DeclarationName::CXXUsingDirective:
00508     return false;
00509     
00510   case DeclarationName::CXXConstructorName:
00511   case DeclarationName::CXXDestructorName:
00512   case DeclarationName::CXXConversionFunctionName:
00513     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
00514       return TInfo->getType()->isInstantiationDependentType();
00515     
00516     return Name.getCXXNameType()->isInstantiationDependentType();
00517   }
00518   llvm_unreachable("All name kinds handled.");
00519 }
00520 
00521 std::string DeclarationNameInfo::getAsString() const {
00522   std::string Result;
00523   llvm::raw_string_ostream OS(Result);
00524   printName(OS);
00525   return OS.str();
00526 }
00527 
00528 void DeclarationNameInfo::printName(raw_ostream &OS) const {
00529   switch (Name.getNameKind()) {
00530   case DeclarationName::Identifier:
00531   case DeclarationName::ObjCZeroArgSelector:
00532   case DeclarationName::ObjCOneArgSelector:
00533   case DeclarationName::ObjCMultiArgSelector:
00534   case DeclarationName::CXXOperatorName:
00535   case DeclarationName::CXXLiteralOperatorName:
00536   case DeclarationName::CXXUsingDirective:
00537     OS << Name;
00538     return;
00539 
00540   case DeclarationName::CXXConstructorName:
00541   case DeclarationName::CXXDestructorName:
00542   case DeclarationName::CXXConversionFunctionName:
00543     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
00544       if (Name.getNameKind() == DeclarationName::CXXDestructorName)
00545         OS << '~';
00546       else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
00547         OS << "operator ";
00548       LangOptions LO;
00549       LO.CPlusPlus = true;
00550       LO.Bool = true;
00551       OS << TInfo->getType().getAsString(PrintingPolicy(LO));
00552     } else
00553       OS << Name;
00554     return;
00555   }
00556   llvm_unreachable("Unexpected declaration name kind");
00557 }
00558 
00559 SourceLocation DeclarationNameInfo::getEndLoc() const {
00560   switch (Name.getNameKind()) {
00561   case DeclarationName::Identifier:
00562     return NameLoc;
00563 
00564   case DeclarationName::CXXOperatorName: {
00565     unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
00566     return SourceLocation::getFromRawEncoding(raw);
00567   }
00568 
00569   case DeclarationName::CXXLiteralOperatorName: {
00570     unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
00571     return SourceLocation::getFromRawEncoding(raw);
00572   }
00573 
00574   case DeclarationName::CXXConstructorName:
00575   case DeclarationName::CXXDestructorName:
00576   case DeclarationName::CXXConversionFunctionName:
00577     if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
00578       return TInfo->getTypeLoc().getEndLoc();
00579     else
00580       return NameLoc;
00581 
00582     // DNInfo work in progress: FIXME.
00583   case DeclarationName::ObjCZeroArgSelector:
00584   case DeclarationName::ObjCOneArgSelector:
00585   case DeclarationName::ObjCMultiArgSelector:
00586   case DeclarationName::CXXUsingDirective:
00587     return NameLoc;
00588   }
00589   llvm_unreachable("Unexpected declaration name kind");
00590 }