1 //===- DeclarationName.cpp - Declaration names implementation -------------===// 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 15 #include "clang/AST/DeclarationName.h" 16 #include "clang/AST/ASTContext.h" 17 #include "clang/AST/Decl.h" 18 #include "clang/AST/DeclBase.h" 19 #include "clang/AST/DeclCXX.h" 20 #include "clang/AST/DeclTemplate.h" 21 #include "clang/AST/PrettyPrinter.h" 22 #include "clang/AST/Type.h" 23 #include "clang/AST/TypeLoc.h" 24 #include "clang/AST/TypeOrdering.h" 25 #include "clang/Basic/IdentifierTable.h" 26 #include "clang/Basic/LLVM.h" 27 #include "clang/Basic/LangOptions.h" 28 #include "clang/Basic/OperatorKinds.h" 29 #include "clang/Basic/SourceLocation.h" 30 #include "llvm/ADT/FoldingSet.h" 31 #include "llvm/Support/Casting.h" 32 #include "llvm/Support/Compiler.h" 33 #include "llvm/Support/ErrorHandling.h" 34 #include "llvm/Support/raw_ostream.h" 35 #include <algorithm> 36 #include <cassert> 37 #include <cstdint> 38 #include <string> 39 40 using namespace clang; 41 42 namespace clang { 43 44 /// CXXSpecialName - Records the type associated with one of the 45 /// "special" kinds of declaration names in C++, e.g., constructors, 46 /// destructors, and conversion functions. 47 class CXXSpecialName 48 : public DeclarationNameExtra, public llvm::FoldingSetNode { 49 public: 50 /// Type - The type associated with this declaration name. 51 QualType Type; 52 53 /// FETokenInfo - Extra information associated with this declaration 54 /// name that can be used by the front end. 55 void *FETokenInfo; 56 57 void Profile(llvm::FoldingSetNodeID &ID) { 58 ID.AddInteger(ExtraKindOrNumArgs); 59 ID.AddPointer(Type.getAsOpaquePtr()); 60 } 61 }; 62 63 /// Contains extra information for the name of a C++ deduction guide. 64 class CXXDeductionGuideNameExtra : public DeclarationNameExtra, 65 public llvm::FoldingSetNode { 66 public: 67 /// The template named by the deduction guide. 68 TemplateDecl *Template; 69 70 /// FETokenInfo - Extra information associated with this operator 71 /// name that can be used by the front end. 72 void *FETokenInfo; 73 74 void Profile(llvm::FoldingSetNodeID &ID) { 75 ID.AddPointer(Template); 76 } 77 }; 78 79 /// CXXOperatorIdName - Contains extra information for the name of an 80 /// overloaded operator in C++, such as "operator+. 81 class CXXOperatorIdName : public DeclarationNameExtra { 82 public: 83 /// FETokenInfo - Extra information associated with this operator 84 /// name that can be used by the front end. 85 void *FETokenInfo; 86 }; 87 88 /// CXXLiteralOperatorName - Contains the actual identifier that makes up the 89 /// name. 90 /// 91 /// This identifier is stored here rather than directly in DeclarationName so as 92 /// to allow Objective-C selectors, which are about a million times more common, 93 /// to consume minimal memory. 94 class CXXLiteralOperatorIdName 95 : public DeclarationNameExtra, public llvm::FoldingSetNode { 96 public: 97 IdentifierInfo *ID; 98 99 /// FETokenInfo - Extra information associated with this operator 100 /// name that can be used by the front end. 101 void *FETokenInfo; 102 103 void Profile(llvm::FoldingSetNodeID &FSID) { 104 FSID.AddPointer(ID); 105 } 106 }; 107 108 } // namespace clang 109 110 static int compareInt(unsigned A, unsigned B) { 111 return (A < B ? -1 : (A > B ? 1 : 0)); 112 } 113 114 int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) { 115 if (LHS.getNameKind() != RHS.getNameKind()) 116 return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1); 117 118 switch (LHS.getNameKind()) { 119 case DeclarationName::Identifier: { 120 IdentifierInfo *LII = LHS.getAsIdentifierInfo(); 121 IdentifierInfo *RII = RHS.getAsIdentifierInfo(); 122 if (!LII) return RII ? -1 : 0; 123 if (!RII) return 1; 124 125 return LII->getName().compare(RII->getName()); 126 } 127 128 case DeclarationName::ObjCZeroArgSelector: 129 case DeclarationName::ObjCOneArgSelector: 130 case DeclarationName::ObjCMultiArgSelector: { 131 Selector LHSSelector = LHS.getObjCSelector(); 132 Selector RHSSelector = RHS.getObjCSelector(); 133 // getNumArgs for ZeroArgSelector returns 0, but we still need to compare. 134 if (LHS.getNameKind() == DeclarationName::ObjCZeroArgSelector && 135 RHS.getNameKind() == DeclarationName::ObjCZeroArgSelector) { 136 return LHSSelector.getAsIdentifierInfo()->getName().compare( 137 RHSSelector.getAsIdentifierInfo()->getName()); 138 } 139 unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs(); 140 for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) { 141 switch (LHSSelector.getNameForSlot(I).compare( 142 RHSSelector.getNameForSlot(I))) { 143 case -1: return -1; 144 case 1: return 1; 145 default: break; 146 } 147 } 148 149 return compareInt(LN, RN); 150 } 151 152 case DeclarationName::CXXConstructorName: 153 case DeclarationName::CXXDestructorName: 154 case DeclarationName::CXXConversionFunctionName: 155 if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType())) 156 return -1; 157 if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType())) 158 return 1; 159 return 0; 160 161 case DeclarationName::CXXDeductionGuideName: 162 // We never want to compare deduction guide names for templates from 163 // different scopes, so just compare the template-name. 164 return compare(LHS.getCXXDeductionGuideTemplate()->getDeclName(), 165 RHS.getCXXDeductionGuideTemplate()->getDeclName()); 166 167 case DeclarationName::CXXOperatorName: 168 return compareInt(LHS.getCXXOverloadedOperator(), 169 RHS.getCXXOverloadedOperator()); 170 171 case DeclarationName::CXXLiteralOperatorName: 172 return LHS.getCXXLiteralIdentifier()->getName().compare( 173 RHS.getCXXLiteralIdentifier()->getName()); 174 175 case DeclarationName::CXXUsingDirective: 176 return 0; 177 } 178 179 llvm_unreachable("Invalid DeclarationName Kind!"); 180 } 181 182 static void printCXXConstructorDestructorName(QualType ClassType, 183 raw_ostream &OS, 184 PrintingPolicy Policy) { 185 // We know we're printing C++ here. Ensure we print types properly. 186 Policy.adjustForCPlusPlus(); 187 188 if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) { 189 OS << *ClassRec->getDecl(); 190 return; 191 } 192 if (Policy.SuppressTemplateArgsInCXXConstructors) { 193 if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) { 194 OS << *InjTy->getDecl(); 195 return; 196 } 197 } 198 ClassType.print(OS, Policy); 199 } 200 201 void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) { 202 DeclarationName &N = *this; 203 switch (N.getNameKind()) { 204 case DeclarationName::Identifier: 205 if (const IdentifierInfo *II = N.getAsIdentifierInfo()) 206 OS << II->getName(); 207 return; 208 209 case DeclarationName::ObjCZeroArgSelector: 210 case DeclarationName::ObjCOneArgSelector: 211 case DeclarationName::ObjCMultiArgSelector: 212 N.getObjCSelector().print(OS); 213 return; 214 215 case DeclarationName::CXXConstructorName: 216 return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy); 217 218 case DeclarationName::CXXDestructorName: 219 OS << '~'; 220 return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy); 221 222 case DeclarationName::CXXDeductionGuideName: 223 OS << "<deduction guide for "; 224 getCXXDeductionGuideTemplate()->getDeclName().print(OS, Policy); 225 OS << '>'; 226 return; 227 228 case DeclarationName::CXXOperatorName: { 229 static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = { 230 nullptr, 231 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 232 Spelling, 233 #include "clang/Basic/OperatorKinds.def" 234 }; 235 const char *OpName = OperatorNames[N.getCXXOverloadedOperator()]; 236 assert(OpName && "not an overloaded operator"); 237 238 OS << "operator"; 239 if (OpName[0] >= 'a' && OpName[0] <= 'z') 240 OS << ' '; 241 OS << OpName; 242 return; 243 } 244 245 case DeclarationName::CXXLiteralOperatorName: 246 OS << "operator\"\"" << N.getCXXLiteralIdentifier()->getName(); 247 return; 248 249 case DeclarationName::CXXConversionFunctionName: { 250 OS << "operator "; 251 QualType Type = N.getCXXNameType(); 252 if (const RecordType *Rec = Type->getAs<RecordType>()) { 253 OS << *Rec->getDecl(); 254 return; 255 } 256 // We know we're printing C++ here, ensure we print 'bool' properly. 257 PrintingPolicy CXXPolicy = Policy; 258 CXXPolicy.adjustForCPlusPlus(); 259 Type.print(OS, CXXPolicy); 260 return; 261 } 262 case DeclarationName::CXXUsingDirective: 263 OS << "<using-directive>"; 264 return; 265 } 266 267 llvm_unreachable("Unexpected declaration name kind"); 268 } 269 270 namespace clang { 271 272 raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) { 273 LangOptions LO; 274 N.print(OS, PrintingPolicy(LO)); 275 return OS; 276 } 277 278 } // namespace clang 279 280 DeclarationName::NameKind DeclarationName::getNameKind() const { 281 switch (getStoredNameKind()) { 282 case StoredIdentifier: return Identifier; 283 case StoredObjCZeroArgSelector: return ObjCZeroArgSelector; 284 case StoredObjCOneArgSelector: return ObjCOneArgSelector; 285 286 case StoredDeclarationNameExtra: 287 switch (getExtra()->ExtraKindOrNumArgs) { 288 case DeclarationNameExtra::CXXConstructor: 289 return CXXConstructorName; 290 291 case DeclarationNameExtra::CXXDestructor: 292 return CXXDestructorName; 293 294 case DeclarationNameExtra::CXXDeductionGuide: 295 return CXXDeductionGuideName; 296 297 case DeclarationNameExtra::CXXConversionFunction: 298 return CXXConversionFunctionName; 299 300 case DeclarationNameExtra::CXXLiteralOperator: 301 return CXXLiteralOperatorName; 302 303 case DeclarationNameExtra::CXXUsingDirective: 304 return CXXUsingDirective; 305 306 default: 307 // Check if we have one of the CXXOperator* enumeration values. 308 if (getExtra()->ExtraKindOrNumArgs < 309 DeclarationNameExtra::CXXUsingDirective) 310 return CXXOperatorName; 311 312 return ObjCMultiArgSelector; 313 } 314 } 315 316 // Can't actually get here. 317 llvm_unreachable("This should be unreachable!"); 318 } 319 320 bool DeclarationName::isDependentName() const { 321 QualType T = getCXXNameType(); 322 if (!T.isNull() && T->isDependentType()) 323 return true; 324 325 // A class-scope deduction guide in a dependent context has a dependent name. 326 auto *TD = getCXXDeductionGuideTemplate(); 327 if (TD && TD->getDeclContext()->isDependentContext()) 328 return true; 329 330 return false; 331 } 332 333 std::string DeclarationName::getAsString() const { 334 std::string Result; 335 llvm::raw_string_ostream OS(Result); 336 OS << *this; 337 return OS.str(); 338 } 339 340 QualType DeclarationName::getCXXNameType() const { 341 if (CXXSpecialName *CXXName = getAsCXXSpecialName()) 342 return CXXName->Type; 343 else 344 return QualType(); 345 } 346 347 TemplateDecl *DeclarationName::getCXXDeductionGuideTemplate() const { 348 if (auto *Guide = getAsCXXDeductionGuideNameExtra()) 349 return Guide->Template; 350 return nullptr; 351 } 352 353 OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const { 354 if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) { 355 unsigned value 356 = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction; 357 return static_cast<OverloadedOperatorKind>(value); 358 } else { 359 return OO_None; 360 } 361 } 362 363 IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const { 364 if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName()) 365 return CXXLit->ID; 366 else 367 return nullptr; 368 } 369 370 void *DeclarationName::getFETokenInfoAsVoidSlow() const { 371 switch (getNameKind()) { 372 case Identifier: 373 llvm_unreachable("Handled by getFETokenInfo()"); 374 375 case CXXConstructorName: 376 case CXXDestructorName: 377 case CXXConversionFunctionName: 378 return getAsCXXSpecialName()->FETokenInfo; 379 380 case CXXDeductionGuideName: 381 return getAsCXXDeductionGuideNameExtra()->FETokenInfo; 382 383 case CXXOperatorName: 384 return getAsCXXOperatorIdName()->FETokenInfo; 385 386 case CXXLiteralOperatorName: 387 return getAsCXXLiteralOperatorIdName()->FETokenInfo; 388 389 default: 390 llvm_unreachable("Declaration name has no FETokenInfo"); 391 } 392 } 393 394 void DeclarationName::setFETokenInfo(void *T) { 395 switch (getNameKind()) { 396 case Identifier: 397 getAsIdentifierInfo()->setFETokenInfo(T); 398 break; 399 400 case CXXConstructorName: 401 case CXXDestructorName: 402 case CXXConversionFunctionName: 403 getAsCXXSpecialName()->FETokenInfo = T; 404 break; 405 406 case CXXDeductionGuideName: 407 getAsCXXDeductionGuideNameExtra()->FETokenInfo = T; 408 break; 409 410 case CXXOperatorName: 411 getAsCXXOperatorIdName()->FETokenInfo = T; 412 break; 413 414 case CXXLiteralOperatorName: 415 getAsCXXLiteralOperatorIdName()->FETokenInfo = T; 416 break; 417 418 default: 419 llvm_unreachable("Declaration name has no FETokenInfo"); 420 } 421 } 422 423 DeclarationName DeclarationName::getUsingDirectiveName() { 424 // Single instance of DeclarationNameExtra for using-directive 425 static const DeclarationNameExtra UDirExtra = 426 { DeclarationNameExtra::CXXUsingDirective }; 427 428 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra); 429 Ptr |= StoredDeclarationNameExtra; 430 431 return DeclarationName(Ptr); 432 } 433 434 LLVM_DUMP_METHOD void DeclarationName::dump() const { 435 llvm::errs() << *this << '\n'; 436 } 437 438 DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) { 439 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>; 440 CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>; 441 CXXDeductionGuideNames = new llvm::FoldingSet<CXXDeductionGuideNameExtra>; 442 443 // Initialize the overloaded operator names. 444 CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS]; 445 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) { 446 CXXOperatorNames[Op].ExtraKindOrNumArgs 447 = Op + DeclarationNameExtra::CXXConversionFunction; 448 CXXOperatorNames[Op].FETokenInfo = nullptr; 449 } 450 } 451 452 DeclarationNameTable::~DeclarationNameTable() { 453 auto *SpecialNames = 454 static_cast<llvm::FoldingSet<CXXSpecialName> *>(CXXSpecialNamesImpl); 455 auto *LiteralNames = 456 static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName> *>( 457 CXXLiteralOperatorNames); 458 auto *DeductionGuideNames = 459 static_cast<llvm::FoldingSet<CXXDeductionGuideNameExtra> *>( 460 CXXDeductionGuideNames); 461 462 delete SpecialNames; 463 delete LiteralNames; 464 delete DeductionGuideNames; 465 } 466 467 DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) { 468 return getCXXSpecialName(DeclarationName::CXXConstructorName, 469 Ty.getUnqualifiedType()); 470 } 471 472 DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) { 473 return getCXXSpecialName(DeclarationName::CXXDestructorName, 474 Ty.getUnqualifiedType()); 475 } 476 477 DeclarationName 478 DeclarationNameTable::getCXXDeductionGuideName(TemplateDecl *Template) { 479 Template = cast<TemplateDecl>(Template->getCanonicalDecl()); 480 481 auto *DeductionGuideNames = 482 static_cast<llvm::FoldingSet<CXXDeductionGuideNameExtra> *>( 483 CXXDeductionGuideNames); 484 485 llvm::FoldingSetNodeID ID; 486 ID.AddPointer(Template); 487 488 void *InsertPos = nullptr; 489 if (auto *Name = DeductionGuideNames->FindNodeOrInsertPos(ID, InsertPos)) 490 return DeclarationName(Name); 491 492 auto *Name = new (Ctx) CXXDeductionGuideNameExtra; 493 Name->ExtraKindOrNumArgs = DeclarationNameExtra::CXXDeductionGuide; 494 Name->Template = Template; 495 Name->FETokenInfo = nullptr; 496 497 DeductionGuideNames->InsertNode(Name, InsertPos); 498 return DeclarationName(Name); 499 } 500 501 DeclarationName 502 DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) { 503 return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty); 504 } 505 506 DeclarationName 507 DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind, 508 CanQualType Ty) { 509 assert(Kind >= DeclarationName::CXXConstructorName && 510 Kind <= DeclarationName::CXXConversionFunctionName && 511 "Kind must be a C++ special name kind"); 512 llvm::FoldingSet<CXXSpecialName> *SpecialNames 513 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl); 514 515 DeclarationNameExtra::ExtraKind EKind; 516 switch (Kind) { 517 case DeclarationName::CXXConstructorName: 518 EKind = DeclarationNameExtra::CXXConstructor; 519 assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified"); 520 break; 521 case DeclarationName::CXXDestructorName: 522 EKind = DeclarationNameExtra::CXXDestructor; 523 assert(!Ty.hasQualifiers() && "Destructor type must be unqualified"); 524 break; 525 case DeclarationName::CXXConversionFunctionName: 526 EKind = DeclarationNameExtra::CXXConversionFunction; 527 break; 528 default: 529 return DeclarationName(); 530 } 531 532 // Unique selector, to guarantee there is one per name. 533 llvm::FoldingSetNodeID ID; 534 ID.AddInteger(EKind); 535 ID.AddPointer(Ty.getAsOpaquePtr()); 536 537 void *InsertPos = nullptr; 538 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos)) 539 return DeclarationName(Name); 540 541 CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName; 542 SpecialName->ExtraKindOrNumArgs = EKind; 543 SpecialName->Type = Ty; 544 SpecialName->FETokenInfo = nullptr; 545 546 SpecialNames->InsertNode(SpecialName, InsertPos); 547 return DeclarationName(SpecialName); 548 } 549 550 DeclarationName 551 DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) { 552 return DeclarationName(&CXXOperatorNames[(unsigned)Op]); 553 } 554 555 DeclarationName 556 DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) { 557 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames 558 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*> 559 (CXXLiteralOperatorNames); 560 561 llvm::FoldingSetNodeID ID; 562 ID.AddPointer(II); 563 564 void *InsertPos = nullptr; 565 if (CXXLiteralOperatorIdName *Name = 566 LiteralNames->FindNodeOrInsertPos(ID, InsertPos)) 567 return DeclarationName (Name); 568 569 CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName; 570 LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator; 571 LiteralName->ID = II; 572 LiteralName->FETokenInfo = nullptr; 573 574 LiteralNames->InsertNode(LiteralName, InsertPos); 575 return DeclarationName(LiteralName); 576 } 577 578 DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) { 579 switch (Name.getNameKind()) { 580 case DeclarationName::Identifier: 581 case DeclarationName::CXXDeductionGuideName: 582 break; 583 case DeclarationName::CXXConstructorName: 584 case DeclarationName::CXXDestructorName: 585 case DeclarationName::CXXConversionFunctionName: 586 NamedType.TInfo = nullptr; 587 break; 588 case DeclarationName::CXXOperatorName: 589 CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding(); 590 CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding(); 591 break; 592 case DeclarationName::CXXLiteralOperatorName: 593 CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding(); 594 break; 595 case DeclarationName::ObjCZeroArgSelector: 596 case DeclarationName::ObjCOneArgSelector: 597 case DeclarationName::ObjCMultiArgSelector: 598 // FIXME: ? 599 break; 600 case DeclarationName::CXXUsingDirective: 601 break; 602 } 603 } 604 605 bool DeclarationNameInfo::containsUnexpandedParameterPack() const { 606 switch (Name.getNameKind()) { 607 case DeclarationName::Identifier: 608 case DeclarationName::ObjCZeroArgSelector: 609 case DeclarationName::ObjCOneArgSelector: 610 case DeclarationName::ObjCMultiArgSelector: 611 case DeclarationName::CXXOperatorName: 612 case DeclarationName::CXXLiteralOperatorName: 613 case DeclarationName::CXXUsingDirective: 614 case DeclarationName::CXXDeductionGuideName: 615 return false; 616 617 case DeclarationName::CXXConstructorName: 618 case DeclarationName::CXXDestructorName: 619 case DeclarationName::CXXConversionFunctionName: 620 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) 621 return TInfo->getType()->containsUnexpandedParameterPack(); 622 623 return Name.getCXXNameType()->containsUnexpandedParameterPack(); 624 } 625 llvm_unreachable("All name kinds handled."); 626 } 627 628 bool DeclarationNameInfo::isInstantiationDependent() const { 629 switch (Name.getNameKind()) { 630 case DeclarationName::Identifier: 631 case DeclarationName::ObjCZeroArgSelector: 632 case DeclarationName::ObjCOneArgSelector: 633 case DeclarationName::ObjCMultiArgSelector: 634 case DeclarationName::CXXOperatorName: 635 case DeclarationName::CXXLiteralOperatorName: 636 case DeclarationName::CXXUsingDirective: 637 case DeclarationName::CXXDeductionGuideName: 638 return false; 639 640 case DeclarationName::CXXConstructorName: 641 case DeclarationName::CXXDestructorName: 642 case DeclarationName::CXXConversionFunctionName: 643 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) 644 return TInfo->getType()->isInstantiationDependentType(); 645 646 return Name.getCXXNameType()->isInstantiationDependentType(); 647 } 648 llvm_unreachable("All name kinds handled."); 649 } 650 651 std::string DeclarationNameInfo::getAsString() const { 652 std::string Result; 653 llvm::raw_string_ostream OS(Result); 654 printName(OS); 655 return OS.str(); 656 } 657 658 void DeclarationNameInfo::printName(raw_ostream &OS) const { 659 switch (Name.getNameKind()) { 660 case DeclarationName::Identifier: 661 case DeclarationName::ObjCZeroArgSelector: 662 case DeclarationName::ObjCOneArgSelector: 663 case DeclarationName::ObjCMultiArgSelector: 664 case DeclarationName::CXXOperatorName: 665 case DeclarationName::CXXLiteralOperatorName: 666 case DeclarationName::CXXUsingDirective: 667 case DeclarationName::CXXDeductionGuideName: 668 OS << Name; 669 return; 670 671 case DeclarationName::CXXConstructorName: 672 case DeclarationName::CXXDestructorName: 673 case DeclarationName::CXXConversionFunctionName: 674 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) { 675 if (Name.getNameKind() == DeclarationName::CXXDestructorName) 676 OS << '~'; 677 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName) 678 OS << "operator "; 679 LangOptions LO; 680 LO.CPlusPlus = true; 681 LO.Bool = true; 682 PrintingPolicy PP(LO); 683 PP.SuppressScope = true; 684 OS << TInfo->getType().getAsString(PP); 685 } else 686 OS << Name; 687 return; 688 } 689 llvm_unreachable("Unexpected declaration name kind"); 690 } 691 692 SourceLocation DeclarationNameInfo::getEndLoc() const { 693 switch (Name.getNameKind()) { 694 case DeclarationName::Identifier: 695 case DeclarationName::CXXDeductionGuideName: 696 return NameLoc; 697 698 case DeclarationName::CXXOperatorName: { 699 unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc; 700 return SourceLocation::getFromRawEncoding(raw); 701 } 702 703 case DeclarationName::CXXLiteralOperatorName: { 704 unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc; 705 return SourceLocation::getFromRawEncoding(raw); 706 } 707 708 case DeclarationName::CXXConstructorName: 709 case DeclarationName::CXXDestructorName: 710 case DeclarationName::CXXConversionFunctionName: 711 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) 712 return TInfo->getTypeLoc().getEndLoc(); 713 else 714 return NameLoc; 715 716 // DNInfo work in progress: FIXME. 717 case DeclarationName::ObjCZeroArgSelector: 718 case DeclarationName::ObjCOneArgSelector: 719 case DeclarationName::ObjCMultiArgSelector: 720 case DeclarationName::CXXUsingDirective: 721 return NameLoc; 722 } 723 llvm_unreachable("Unexpected declaration name kind"); 724 } 725