clang API Documentation
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 }