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