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 OS << "<deduction guide for "; 207 getCXXDeductionGuideTemplate()->getDeclName().print(OS, Policy); 208 OS << '>'; 209 return; 210 211 case DeclarationName::CXXOperatorName: { 212 static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = { 213 nullptr, 214 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 215 Spelling, 216 #include "clang/Basic/OperatorKinds.def" 217 }; 218 const char *OpName = OperatorNames[N.getCXXOverloadedOperator()]; 219 assert(OpName && "not an overloaded operator"); 220 221 OS << "operator"; 222 if (OpName[0] >= 'a' && OpName[0] <= 'z') 223 OS << ' '; 224 OS << OpName; 225 return; 226 } 227 228 case DeclarationName::CXXLiteralOperatorName: 229 OS << "operator\"\"" << N.getCXXLiteralIdentifier()->getName(); 230 return; 231 232 case DeclarationName::CXXConversionFunctionName: { 233 OS << "operator "; 234 QualType Type = N.getCXXNameType(); 235 if (const RecordType *Rec = Type->getAs<RecordType>()) { 236 OS << *Rec->getDecl(); 237 return; 238 } 239 // We know we're printing C++ here, ensure we print 'bool' properly. 240 PrintingPolicy CXXPolicy = Policy; 241 CXXPolicy.adjustForCPlusPlus(); 242 Type.print(OS, CXXPolicy); 243 return; 244 } 245 case DeclarationName::CXXUsingDirective: 246 OS << "<using-directive>"; 247 return; 248 } 249 250 llvm_unreachable("Unexpected declaration name kind"); 251 } 252 253 raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) { 254 LangOptions LO; 255 N.print(OS, PrintingPolicy(LO)); 256 return OS; 257 } 258 259 } // end namespace clang 260 261 DeclarationName::NameKind DeclarationName::getNameKind() const { 262 switch (getStoredNameKind()) { 263 case StoredIdentifier: return Identifier; 264 case StoredObjCZeroArgSelector: return ObjCZeroArgSelector; 265 case StoredObjCOneArgSelector: return ObjCOneArgSelector; 266 267 case StoredDeclarationNameExtra: 268 switch (getExtra()->ExtraKindOrNumArgs) { 269 case DeclarationNameExtra::CXXConstructor: 270 return CXXConstructorName; 271 272 case DeclarationNameExtra::CXXDestructor: 273 return CXXDestructorName; 274 275 case DeclarationNameExtra::CXXDeductionGuide: 276 return CXXDeductionGuideName; 277 278 case DeclarationNameExtra::CXXConversionFunction: 279 return CXXConversionFunctionName; 280 281 case DeclarationNameExtra::CXXLiteralOperator: 282 return CXXLiteralOperatorName; 283 284 case DeclarationNameExtra::CXXUsingDirective: 285 return CXXUsingDirective; 286 287 default: 288 // Check if we have one of the CXXOperator* enumeration values. 289 if (getExtra()->ExtraKindOrNumArgs < 290 DeclarationNameExtra::CXXUsingDirective) 291 return CXXOperatorName; 292 293 return ObjCMultiArgSelector; 294 } 295 } 296 297 // Can't actually get here. 298 llvm_unreachable("This should be unreachable!"); 299 } 300 301 bool DeclarationName::isDependentName() const { 302 QualType T = getCXXNameType(); 303 if (!T.isNull() && T->isDependentType()) 304 return true; 305 306 // A class-scope deduction guide in a dependent context has a dependent name. 307 auto *TD = getCXXDeductionGuideTemplate(); 308 if (TD && TD->getDeclContext()->isDependentContext()) 309 return true; 310 311 return false; 312 } 313 314 std::string DeclarationName::getAsString() const { 315 std::string Result; 316 llvm::raw_string_ostream OS(Result); 317 OS << *this; 318 return OS.str(); 319 } 320 321 QualType DeclarationName::getCXXNameType() const { 322 if (CXXSpecialName *CXXName = getAsCXXSpecialName()) 323 return CXXName->Type; 324 else 325 return QualType(); 326 } 327 328 TemplateDecl *DeclarationName::getCXXDeductionGuideTemplate() const { 329 if (auto *Guide = getAsCXXDeductionGuideNameExtra()) 330 return Guide->Template; 331 return nullptr; 332 } 333 334 OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const { 335 if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) { 336 unsigned value 337 = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction; 338 return static_cast<OverloadedOperatorKind>(value); 339 } else { 340 return OO_None; 341 } 342 } 343 344 IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const { 345 if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName()) 346 return CXXLit->ID; 347 else 348 return nullptr; 349 } 350 351 void *DeclarationName::getFETokenInfoAsVoidSlow() const { 352 switch (getNameKind()) { 353 case Identifier: 354 llvm_unreachable("Handled by getFETokenInfo()"); 355 356 case CXXConstructorName: 357 case CXXDestructorName: 358 case CXXConversionFunctionName: 359 return getAsCXXSpecialName()->FETokenInfo; 360 361 case CXXDeductionGuideName: 362 return getAsCXXDeductionGuideNameExtra()->FETokenInfo; 363 364 case CXXOperatorName: 365 return getAsCXXOperatorIdName()->FETokenInfo; 366 367 case CXXLiteralOperatorName: 368 return getAsCXXLiteralOperatorIdName()->FETokenInfo; 369 370 default: 371 llvm_unreachable("Declaration name has no FETokenInfo"); 372 } 373 } 374 375 void DeclarationName::setFETokenInfo(void *T) { 376 switch (getNameKind()) { 377 case Identifier: 378 getAsIdentifierInfo()->setFETokenInfo(T); 379 break; 380 381 case CXXConstructorName: 382 case CXXDestructorName: 383 case CXXConversionFunctionName: 384 getAsCXXSpecialName()->FETokenInfo = T; 385 break; 386 387 case CXXDeductionGuideName: 388 getAsCXXDeductionGuideNameExtra()->FETokenInfo = T; 389 break; 390 391 case CXXOperatorName: 392 getAsCXXOperatorIdName()->FETokenInfo = T; 393 break; 394 395 case CXXLiteralOperatorName: 396 getAsCXXLiteralOperatorIdName()->FETokenInfo = T; 397 break; 398 399 default: 400 llvm_unreachable("Declaration name has no FETokenInfo"); 401 } 402 } 403 404 DeclarationName DeclarationName::getUsingDirectiveName() { 405 // Single instance of DeclarationNameExtra for using-directive 406 static const DeclarationNameExtra UDirExtra = 407 { DeclarationNameExtra::CXXUsingDirective }; 408 409 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra); 410 Ptr |= StoredDeclarationNameExtra; 411 412 return DeclarationName(Ptr); 413 } 414 415 LLVM_DUMP_METHOD void DeclarationName::dump() const { 416 llvm::errs() << *this << '\n'; 417 } 418 419 DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) { 420 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>; 421 CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>; 422 CXXDeductionGuideNames = new llvm::FoldingSet<CXXDeductionGuideNameExtra>; 423 424 // Initialize the overloaded operator names. 425 CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS]; 426 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) { 427 CXXOperatorNames[Op].ExtraKindOrNumArgs 428 = Op + DeclarationNameExtra::CXXConversionFunction; 429 CXXOperatorNames[Op].FETokenInfo = nullptr; 430 } 431 } 432 433 DeclarationNameTable::~DeclarationNameTable() { 434 auto *SpecialNames = 435 static_cast<llvm::FoldingSet<CXXSpecialName> *>(CXXSpecialNamesImpl); 436 auto *LiteralNames = 437 static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName> *>( 438 CXXLiteralOperatorNames); 439 auto *DeductionGuideNames = 440 static_cast<llvm::FoldingSet<CXXDeductionGuideNameExtra> *>( 441 CXXDeductionGuideNames); 442 443 delete SpecialNames; 444 delete LiteralNames; 445 delete DeductionGuideNames; 446 } 447 448 DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) { 449 return getCXXSpecialName(DeclarationName::CXXConstructorName, 450 Ty.getUnqualifiedType()); 451 } 452 453 DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) { 454 return getCXXSpecialName(DeclarationName::CXXDestructorName, 455 Ty.getUnqualifiedType()); 456 } 457 458 DeclarationName 459 DeclarationNameTable::getCXXDeductionGuideName(TemplateDecl *Template) { 460 Template = cast<TemplateDecl>(Template->getCanonicalDecl()); 461 462 auto *DeductionGuideNames = 463 static_cast<llvm::FoldingSet<CXXDeductionGuideNameExtra> *>( 464 CXXDeductionGuideNames); 465 466 llvm::FoldingSetNodeID ID; 467 ID.AddPointer(Template); 468 469 void *InsertPos = nullptr; 470 if (auto *Name = DeductionGuideNames->FindNodeOrInsertPos(ID, InsertPos)) 471 return DeclarationName(Name); 472 473 auto *Name = new (Ctx) CXXDeductionGuideNameExtra; 474 Name->ExtraKindOrNumArgs = DeclarationNameExtra::CXXDeductionGuide; 475 Name->Template = Template; 476 Name->FETokenInfo = nullptr; 477 478 DeductionGuideNames->InsertNode(Name, InsertPos); 479 return DeclarationName(Name); 480 } 481 482 DeclarationName 483 DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) { 484 return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty); 485 } 486 487 DeclarationName 488 DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind, 489 CanQualType Ty) { 490 assert(Kind >= DeclarationName::CXXConstructorName && 491 Kind <= DeclarationName::CXXConversionFunctionName && 492 "Kind must be a C++ special name kind"); 493 llvm::FoldingSet<CXXSpecialName> *SpecialNames 494 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl); 495 496 DeclarationNameExtra::ExtraKind EKind; 497 switch (Kind) { 498 case DeclarationName::CXXConstructorName: 499 EKind = DeclarationNameExtra::CXXConstructor; 500 assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified"); 501 break; 502 case DeclarationName::CXXDestructorName: 503 EKind = DeclarationNameExtra::CXXDestructor; 504 assert(!Ty.hasQualifiers() && "Destructor type must be unqualified"); 505 break; 506 case DeclarationName::CXXConversionFunctionName: 507 EKind = DeclarationNameExtra::CXXConversionFunction; 508 break; 509 default: 510 return DeclarationName(); 511 } 512 513 // Unique selector, to guarantee there is one per name. 514 llvm::FoldingSetNodeID ID; 515 ID.AddInteger(EKind); 516 ID.AddPointer(Ty.getAsOpaquePtr()); 517 518 void *InsertPos = nullptr; 519 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos)) 520 return DeclarationName(Name); 521 522 CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName; 523 SpecialName->ExtraKindOrNumArgs = EKind; 524 SpecialName->Type = Ty; 525 SpecialName->FETokenInfo = nullptr; 526 527 SpecialNames->InsertNode(SpecialName, InsertPos); 528 return DeclarationName(SpecialName); 529 } 530 531 DeclarationName 532 DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) { 533 return DeclarationName(&CXXOperatorNames[(unsigned)Op]); 534 } 535 536 DeclarationName 537 DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) { 538 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames 539 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*> 540 (CXXLiteralOperatorNames); 541 542 llvm::FoldingSetNodeID ID; 543 ID.AddPointer(II); 544 545 void *InsertPos = nullptr; 546 if (CXXLiteralOperatorIdName *Name = 547 LiteralNames->FindNodeOrInsertPos(ID, InsertPos)) 548 return DeclarationName (Name); 549 550 CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName; 551 LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator; 552 LiteralName->ID = II; 553 LiteralName->FETokenInfo = nullptr; 554 555 LiteralNames->InsertNode(LiteralName, InsertPos); 556 return DeclarationName(LiteralName); 557 } 558 559 DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) { 560 switch (Name.getNameKind()) { 561 case DeclarationName::Identifier: 562 case DeclarationName::CXXDeductionGuideName: 563 break; 564 case DeclarationName::CXXConstructorName: 565 case DeclarationName::CXXDestructorName: 566 case DeclarationName::CXXConversionFunctionName: 567 NamedType.TInfo = nullptr; 568 break; 569 case DeclarationName::CXXOperatorName: 570 CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding(); 571 CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding(); 572 break; 573 case DeclarationName::CXXLiteralOperatorName: 574 CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding(); 575 break; 576 case DeclarationName::ObjCZeroArgSelector: 577 case DeclarationName::ObjCOneArgSelector: 578 case DeclarationName::ObjCMultiArgSelector: 579 // FIXME: ? 580 break; 581 case DeclarationName::CXXUsingDirective: 582 break; 583 } 584 } 585 586 bool DeclarationNameInfo::containsUnexpandedParameterPack() const { 587 switch (Name.getNameKind()) { 588 case DeclarationName::Identifier: 589 case DeclarationName::ObjCZeroArgSelector: 590 case DeclarationName::ObjCOneArgSelector: 591 case DeclarationName::ObjCMultiArgSelector: 592 case DeclarationName::CXXOperatorName: 593 case DeclarationName::CXXLiteralOperatorName: 594 case DeclarationName::CXXUsingDirective: 595 case DeclarationName::CXXDeductionGuideName: 596 return false; 597 598 case DeclarationName::CXXConstructorName: 599 case DeclarationName::CXXDestructorName: 600 case DeclarationName::CXXConversionFunctionName: 601 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) 602 return TInfo->getType()->containsUnexpandedParameterPack(); 603 604 return Name.getCXXNameType()->containsUnexpandedParameterPack(); 605 } 606 llvm_unreachable("All name kinds handled."); 607 } 608 609 bool DeclarationNameInfo::isInstantiationDependent() const { 610 switch (Name.getNameKind()) { 611 case DeclarationName::Identifier: 612 case DeclarationName::ObjCZeroArgSelector: 613 case DeclarationName::ObjCOneArgSelector: 614 case DeclarationName::ObjCMultiArgSelector: 615 case DeclarationName::CXXOperatorName: 616 case DeclarationName::CXXLiteralOperatorName: 617 case DeclarationName::CXXUsingDirective: 618 case DeclarationName::CXXDeductionGuideName: 619 return false; 620 621 case DeclarationName::CXXConstructorName: 622 case DeclarationName::CXXDestructorName: 623 case DeclarationName::CXXConversionFunctionName: 624 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) 625 return TInfo->getType()->isInstantiationDependentType(); 626 627 return Name.getCXXNameType()->isInstantiationDependentType(); 628 } 629 llvm_unreachable("All name kinds handled."); 630 } 631 632 std::string DeclarationNameInfo::getAsString() const { 633 std::string Result; 634 llvm::raw_string_ostream OS(Result); 635 printName(OS); 636 return OS.str(); 637 } 638 639 void DeclarationNameInfo::printName(raw_ostream &OS) const { 640 switch (Name.getNameKind()) { 641 case DeclarationName::Identifier: 642 case DeclarationName::ObjCZeroArgSelector: 643 case DeclarationName::ObjCOneArgSelector: 644 case DeclarationName::ObjCMultiArgSelector: 645 case DeclarationName::CXXOperatorName: 646 case DeclarationName::CXXLiteralOperatorName: 647 case DeclarationName::CXXUsingDirective: 648 case DeclarationName::CXXDeductionGuideName: 649 OS << Name; 650 return; 651 652 case DeclarationName::CXXConstructorName: 653 case DeclarationName::CXXDestructorName: 654 case DeclarationName::CXXConversionFunctionName: 655 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) { 656 if (Name.getNameKind() == DeclarationName::CXXDestructorName) 657 OS << '~'; 658 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName) 659 OS << "operator "; 660 LangOptions LO; 661 LO.CPlusPlus = true; 662 LO.Bool = true; 663 PrintingPolicy PP(LO); 664 PP.SuppressScope = true; 665 OS << TInfo->getType().getAsString(PP); 666 } else 667 OS << Name; 668 return; 669 } 670 llvm_unreachable("Unexpected declaration name kind"); 671 } 672 673 SourceLocation DeclarationNameInfo::getEndLoc() const { 674 switch (Name.getNameKind()) { 675 case DeclarationName::Identifier: 676 case DeclarationName::CXXDeductionGuideName: 677 return NameLoc; 678 679 case DeclarationName::CXXOperatorName: { 680 unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc; 681 return SourceLocation::getFromRawEncoding(raw); 682 } 683 684 case DeclarationName::CXXLiteralOperatorName: { 685 unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc; 686 return SourceLocation::getFromRawEncoding(raw); 687 } 688 689 case DeclarationName::CXXConstructorName: 690 case DeclarationName::CXXDestructorName: 691 case DeclarationName::CXXConversionFunctionName: 692 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) 693 return TInfo->getTypeLoc().getEndLoc(); 694 else 695 return NameLoc; 696 697 // DNInfo work in progress: FIXME. 698 case DeclarationName::ObjCZeroArgSelector: 699 case DeclarationName::ObjCOneArgSelector: 700 case DeclarationName::ObjCMultiArgSelector: 701 case DeclarationName::CXXUsingDirective: 702 return NameLoc; 703 } 704 llvm_unreachable("Unexpected declaration name kind"); 705 } 706