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/ASTContext.h" 15 #include "clang/AST/Decl.h" 16 #include "clang/AST/DeclarationName.h" 17 #include "clang/AST/Type.h" 18 #include "clang/AST/TypeLoc.h" 19 #include "clang/AST/TypeOrdering.h" 20 #include "clang/Basic/IdentifierTable.h" 21 #include "llvm/ADT/DenseMap.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 /// CXXOperatorIdName - Contains extra information for the name of an 48 /// overloaded operator in C++, such as "operator+. 49 class CXXOperatorIdName : public DeclarationNameExtra { 50 public: 51 /// FETokenInfo - Extra information associated with this operator 52 /// name that can be used by the front end. 53 void *FETokenInfo; 54 }; 55 56 /// CXXLiberalOperatorName - Contains the actual identifier that makes up the 57 /// name. 58 /// 59 /// This identifier is stored here rather than directly in DeclarationName so as 60 /// to allow Objective-C selectors, which are about a million times more common, 61 /// to consume minimal memory. 62 class CXXLiteralOperatorIdName 63 : public DeclarationNameExtra, public llvm::FoldingSetNode { 64 public: 65 IdentifierInfo *ID; 66 67 void Profile(llvm::FoldingSetNodeID &FSID) { 68 FSID.AddPointer(ID); 69 } 70 }; 71 72 static int compareInt(unsigned A, unsigned B) { 73 return (A < B ? -1 : (A > B ? 1 : 0)); 74 } 75 76 int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) { 77 if (LHS.getNameKind() != RHS.getNameKind()) 78 return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1); 79 80 switch (LHS.getNameKind()) { 81 case DeclarationName::Identifier: { 82 IdentifierInfo *LII = LHS.getAsIdentifierInfo(); 83 IdentifierInfo *RII = RHS.getAsIdentifierInfo(); 84 if (!LII) return RII ? -1 : 0; 85 if (!RII) return 1; 86 87 return LII->getName().compare(RII->getName()); 88 } 89 90 case DeclarationName::ObjCZeroArgSelector: 91 case DeclarationName::ObjCOneArgSelector: 92 case DeclarationName::ObjCMultiArgSelector: { 93 Selector LHSSelector = LHS.getObjCSelector(); 94 Selector RHSSelector = RHS.getObjCSelector(); 95 unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs(); 96 for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) { 97 switch (LHSSelector.getNameForSlot(I).compare( 98 RHSSelector.getNameForSlot(I))) { 99 case -1: return true; 100 case 1: return false; 101 default: break; 102 } 103 } 104 105 return compareInt(LN, RN); 106 } 107 108 case DeclarationName::CXXConstructorName: 109 case DeclarationName::CXXDestructorName: 110 case DeclarationName::CXXConversionFunctionName: 111 if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType())) 112 return -1; 113 if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType())) 114 return 1; 115 return 0; 116 117 case DeclarationName::CXXOperatorName: 118 return compareInt(LHS.getCXXOverloadedOperator(), 119 RHS.getCXXOverloadedOperator()); 120 121 case DeclarationName::CXXLiteralOperatorName: 122 return LHS.getCXXLiteralIdentifier()->getName().compare( 123 RHS.getCXXLiteralIdentifier()->getName()); 124 125 case DeclarationName::CXXUsingDirective: 126 return 0; 127 } 128 129 return 0; 130 } 131 132 } // end namespace clang 133 134 DeclarationName::DeclarationName(Selector Sel) { 135 if (!Sel.getAsOpaquePtr()) { 136 Ptr = 0; 137 return; 138 } 139 140 switch (Sel.getNumArgs()) { 141 case 0: 142 Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo()); 143 assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo"); 144 Ptr |= StoredObjCZeroArgSelector; 145 break; 146 147 case 1: 148 Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo()); 149 assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo"); 150 Ptr |= StoredObjCOneArgSelector; 151 break; 152 153 default: 154 Ptr = Sel.InfoPtr & ~Selector::ArgFlags; 155 assert((Ptr & PtrMask) == 0 && "Improperly aligned MultiKeywordSelector"); 156 Ptr |= StoredDeclarationNameExtra; 157 break; 158 } 159 } 160 161 DeclarationName::NameKind DeclarationName::getNameKind() const { 162 switch (getStoredNameKind()) { 163 case StoredIdentifier: return Identifier; 164 case StoredObjCZeroArgSelector: return ObjCZeroArgSelector; 165 case StoredObjCOneArgSelector: return ObjCOneArgSelector; 166 167 case StoredDeclarationNameExtra: 168 switch (getExtra()->ExtraKindOrNumArgs) { 169 case DeclarationNameExtra::CXXConstructor: 170 return CXXConstructorName; 171 172 case DeclarationNameExtra::CXXDestructor: 173 return CXXDestructorName; 174 175 case DeclarationNameExtra::CXXConversionFunction: 176 return CXXConversionFunctionName; 177 178 case DeclarationNameExtra::CXXLiteralOperator: 179 return CXXLiteralOperatorName; 180 181 case DeclarationNameExtra::CXXUsingDirective: 182 return CXXUsingDirective; 183 184 default: 185 // Check if we have one of the CXXOperator* enumeration values. 186 if (getExtra()->ExtraKindOrNumArgs < 187 DeclarationNameExtra::CXXUsingDirective) 188 return CXXOperatorName; 189 190 return ObjCMultiArgSelector; 191 } 192 break; 193 } 194 195 // Can't actually get here. 196 llvm_unreachable("This should be unreachable!"); 197 } 198 199 bool DeclarationName::isDependentName() const { 200 QualType T = getCXXNameType(); 201 return !T.isNull() && T->isDependentType(); 202 } 203 204 std::string DeclarationName::getAsString() const { 205 std::string Result; 206 llvm::raw_string_ostream OS(Result); 207 printName(OS); 208 return OS.str(); 209 } 210 211 void DeclarationName::printName(raw_ostream &OS) const { 212 switch (getNameKind()) { 213 case Identifier: 214 if (const IdentifierInfo *II = getAsIdentifierInfo()) 215 OS << II->getName(); 216 return; 217 218 case ObjCZeroArgSelector: 219 case ObjCOneArgSelector: 220 case ObjCMultiArgSelector: 221 OS << getObjCSelector().getAsString(); 222 return; 223 224 case CXXConstructorName: { 225 QualType ClassType = getCXXNameType(); 226 if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) 227 OS << *ClassRec->getDecl(); 228 else 229 OS << ClassType.getAsString(); 230 return; 231 } 232 233 case CXXDestructorName: { 234 OS << '~'; 235 QualType Type = getCXXNameType(); 236 if (const RecordType *Rec = Type->getAs<RecordType>()) 237 OS << *Rec->getDecl(); 238 else 239 OS << Type.getAsString(); 240 return; 241 } 242 243 case CXXOperatorName: { 244 static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = { 245 0, 246 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 247 Spelling, 248 #include "clang/Basic/OperatorKinds.def" 249 }; 250 const char *OpName = OperatorNames[getCXXOverloadedOperator()]; 251 assert(OpName && "not an overloaded operator"); 252 253 OS << "operator"; 254 if (OpName[0] >= 'a' && OpName[0] <= 'z') 255 OS << ' '; 256 OS << OpName; 257 return; 258 } 259 260 case CXXLiteralOperatorName: 261 OS << "operator \"\" " << getCXXLiteralIdentifier()->getName(); 262 return; 263 264 case CXXConversionFunctionName: { 265 OS << "operator "; 266 QualType Type = getCXXNameType(); 267 if (const RecordType *Rec = Type->getAs<RecordType>()) 268 OS << *Rec->getDecl(); 269 else 270 OS << Type.getAsString(); 271 return; 272 } 273 case CXXUsingDirective: 274 OS << "<using-directive>"; 275 return; 276 } 277 278 llvm_unreachable("Unexpected declaration name kind"); 279 } 280 281 QualType DeclarationName::getCXXNameType() const { 282 if (CXXSpecialName *CXXName = getAsCXXSpecialName()) 283 return CXXName->Type; 284 else 285 return QualType(); 286 } 287 288 OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const { 289 if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) { 290 unsigned value 291 = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction; 292 return static_cast<OverloadedOperatorKind>(value); 293 } else { 294 return OO_None; 295 } 296 } 297 298 IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const { 299 if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName()) 300 return CXXLit->ID; 301 else 302 return 0; 303 } 304 305 Selector DeclarationName::getObjCSelector() const { 306 switch (getNameKind()) { 307 case ObjCZeroArgSelector: 308 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 0); 309 310 case ObjCOneArgSelector: 311 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 1); 312 313 case ObjCMultiArgSelector: 314 return Selector(reinterpret_cast<MultiKeywordSelector *>(Ptr & ~PtrMask)); 315 316 default: 317 break; 318 } 319 320 return Selector(); 321 } 322 323 void *DeclarationName::getFETokenInfoAsVoid() const { 324 switch (getNameKind()) { 325 case Identifier: 326 return getAsIdentifierInfo()->getFETokenInfo<void>(); 327 328 case CXXConstructorName: 329 case CXXDestructorName: 330 case CXXConversionFunctionName: 331 return getAsCXXSpecialName()->FETokenInfo; 332 333 case CXXOperatorName: 334 return getAsCXXOperatorIdName()->FETokenInfo; 335 336 case CXXLiteralOperatorName: 337 return getCXXLiteralIdentifier()->getFETokenInfo<void>(); 338 339 default: 340 llvm_unreachable("Declaration name has no FETokenInfo"); 341 } 342 } 343 344 void DeclarationName::setFETokenInfo(void *T) { 345 switch (getNameKind()) { 346 case Identifier: 347 getAsIdentifierInfo()->setFETokenInfo(T); 348 break; 349 350 case CXXConstructorName: 351 case CXXDestructorName: 352 case CXXConversionFunctionName: 353 getAsCXXSpecialName()->FETokenInfo = T; 354 break; 355 356 case CXXOperatorName: 357 getAsCXXOperatorIdName()->FETokenInfo = T; 358 break; 359 360 case CXXLiteralOperatorName: 361 getCXXLiteralIdentifier()->setFETokenInfo(T); 362 break; 363 364 default: 365 llvm_unreachable("Declaration name has no FETokenInfo"); 366 } 367 } 368 369 DeclarationName DeclarationName::getUsingDirectiveName() { 370 // Single instance of DeclarationNameExtra for using-directive 371 static const DeclarationNameExtra UDirExtra = 372 { DeclarationNameExtra::CXXUsingDirective }; 373 374 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra); 375 Ptr |= StoredDeclarationNameExtra; 376 377 return DeclarationName(Ptr); 378 } 379 380 void DeclarationName::dump() const { 381 printName(llvm::errs()); 382 llvm::errs() << '\n'; 383 } 384 385 DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) { 386 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>; 387 CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>; 388 389 // Initialize the overloaded operator names. 390 CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS]; 391 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) { 392 CXXOperatorNames[Op].ExtraKindOrNumArgs 393 = Op + DeclarationNameExtra::CXXConversionFunction; 394 CXXOperatorNames[Op].FETokenInfo = 0; 395 } 396 } 397 398 DeclarationNameTable::~DeclarationNameTable() { 399 llvm::FoldingSet<CXXSpecialName> *SpecialNames = 400 static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl); 401 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames 402 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*> 403 (CXXLiteralOperatorNames); 404 405 delete SpecialNames; 406 delete LiteralNames; 407 } 408 409 DeclarationName 410 DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind, 411 CanQualType Ty) { 412 assert(Kind >= DeclarationName::CXXConstructorName && 413 Kind <= DeclarationName::CXXConversionFunctionName && 414 "Kind must be a C++ special name kind"); 415 llvm::FoldingSet<CXXSpecialName> *SpecialNames 416 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl); 417 418 DeclarationNameExtra::ExtraKind EKind; 419 switch (Kind) { 420 case DeclarationName::CXXConstructorName: 421 EKind = DeclarationNameExtra::CXXConstructor; 422 assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified"); 423 break; 424 case DeclarationName::CXXDestructorName: 425 EKind = DeclarationNameExtra::CXXDestructor; 426 assert(!Ty.hasQualifiers() && "Destructor type must be unqualified"); 427 break; 428 case DeclarationName::CXXConversionFunctionName: 429 EKind = DeclarationNameExtra::CXXConversionFunction; 430 break; 431 default: 432 return DeclarationName(); 433 } 434 435 // Unique selector, to guarantee there is one per name. 436 llvm::FoldingSetNodeID ID; 437 ID.AddInteger(EKind); 438 ID.AddPointer(Ty.getAsOpaquePtr()); 439 440 void *InsertPos = 0; 441 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos)) 442 return DeclarationName(Name); 443 444 CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName; 445 SpecialName->ExtraKindOrNumArgs = EKind; 446 SpecialName->Type = Ty; 447 SpecialName->FETokenInfo = 0; 448 449 SpecialNames->InsertNode(SpecialName, InsertPos); 450 return DeclarationName(SpecialName); 451 } 452 453 DeclarationName 454 DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) { 455 return DeclarationName(&CXXOperatorNames[(unsigned)Op]); 456 } 457 458 DeclarationName 459 DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) { 460 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames 461 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*> 462 (CXXLiteralOperatorNames); 463 464 llvm::FoldingSetNodeID ID; 465 ID.AddPointer(II); 466 467 void *InsertPos = 0; 468 if (CXXLiteralOperatorIdName *Name = 469 LiteralNames->FindNodeOrInsertPos(ID, InsertPos)) 470 return DeclarationName (Name); 471 472 CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName; 473 LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator; 474 LiteralName->ID = II; 475 476 LiteralNames->InsertNode(LiteralName, InsertPos); 477 return DeclarationName(LiteralName); 478 } 479 480 unsigned 481 llvm::DenseMapInfo<clang::DeclarationName>:: 482 getHashValue(clang::DeclarationName N) { 483 return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr()); 484 } 485 486 DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) { 487 switch (Name.getNameKind()) { 488 case DeclarationName::Identifier: 489 break; 490 case DeclarationName::CXXConstructorName: 491 case DeclarationName::CXXDestructorName: 492 case DeclarationName::CXXConversionFunctionName: 493 NamedType.TInfo = 0; 494 break; 495 case DeclarationName::CXXOperatorName: 496 CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding(); 497 CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding(); 498 break; 499 case DeclarationName::CXXLiteralOperatorName: 500 CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding(); 501 break; 502 case DeclarationName::ObjCZeroArgSelector: 503 case DeclarationName::ObjCOneArgSelector: 504 case DeclarationName::ObjCMultiArgSelector: 505 // FIXME: ? 506 break; 507 case DeclarationName::CXXUsingDirective: 508 break; 509 } 510 } 511 512 bool DeclarationNameInfo::containsUnexpandedParameterPack() const { 513 switch (Name.getNameKind()) { 514 case DeclarationName::Identifier: 515 case DeclarationName::ObjCZeroArgSelector: 516 case DeclarationName::ObjCOneArgSelector: 517 case DeclarationName::ObjCMultiArgSelector: 518 case DeclarationName::CXXOperatorName: 519 case DeclarationName::CXXLiteralOperatorName: 520 case DeclarationName::CXXUsingDirective: 521 return false; 522 523 case DeclarationName::CXXConstructorName: 524 case DeclarationName::CXXDestructorName: 525 case DeclarationName::CXXConversionFunctionName: 526 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) 527 return TInfo->getType()->containsUnexpandedParameterPack(); 528 529 return Name.getCXXNameType()->containsUnexpandedParameterPack(); 530 } 531 llvm_unreachable("All name kinds handled."); 532 } 533 534 bool DeclarationNameInfo::isInstantiationDependent() const { 535 switch (Name.getNameKind()) { 536 case DeclarationName::Identifier: 537 case DeclarationName::ObjCZeroArgSelector: 538 case DeclarationName::ObjCOneArgSelector: 539 case DeclarationName::ObjCMultiArgSelector: 540 case DeclarationName::CXXOperatorName: 541 case DeclarationName::CXXLiteralOperatorName: 542 case DeclarationName::CXXUsingDirective: 543 return false; 544 545 case DeclarationName::CXXConstructorName: 546 case DeclarationName::CXXDestructorName: 547 case DeclarationName::CXXConversionFunctionName: 548 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) 549 return TInfo->getType()->isInstantiationDependentType(); 550 551 return Name.getCXXNameType()->isInstantiationDependentType(); 552 } 553 llvm_unreachable("All name kinds handled."); 554 } 555 556 std::string DeclarationNameInfo::getAsString() const { 557 std::string Result; 558 llvm::raw_string_ostream OS(Result); 559 printName(OS); 560 return OS.str(); 561 } 562 563 void DeclarationNameInfo::printName(raw_ostream &OS) const { 564 switch (Name.getNameKind()) { 565 case DeclarationName::Identifier: 566 case DeclarationName::ObjCZeroArgSelector: 567 case DeclarationName::ObjCOneArgSelector: 568 case DeclarationName::ObjCMultiArgSelector: 569 case DeclarationName::CXXOperatorName: 570 case DeclarationName::CXXLiteralOperatorName: 571 case DeclarationName::CXXUsingDirective: 572 Name.printName(OS); 573 return; 574 575 case DeclarationName::CXXConstructorName: 576 case DeclarationName::CXXDestructorName: 577 case DeclarationName::CXXConversionFunctionName: 578 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) { 579 if (Name.getNameKind() == DeclarationName::CXXDestructorName) 580 OS << '~'; 581 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName) 582 OS << "operator "; 583 OS << TInfo->getType().getAsString(); 584 } 585 else 586 Name.printName(OS); 587 return; 588 } 589 llvm_unreachable("Unexpected declaration name kind"); 590 } 591 592 SourceLocation DeclarationNameInfo::getEndLoc() const { 593 switch (Name.getNameKind()) { 594 case DeclarationName::Identifier: 595 return NameLoc; 596 597 case DeclarationName::CXXOperatorName: { 598 unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc; 599 return SourceLocation::getFromRawEncoding(raw); 600 } 601 602 case DeclarationName::CXXLiteralOperatorName: { 603 unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc; 604 return SourceLocation::getFromRawEncoding(raw); 605 } 606 607 case DeclarationName::CXXConstructorName: 608 case DeclarationName::CXXDestructorName: 609 case DeclarationName::CXXConversionFunctionName: 610 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) 611 return TInfo->getTypeLoc().getEndLoc(); 612 else 613 return NameLoc; 614 615 // DNInfo work in progress: FIXME. 616 case DeclarationName::ObjCZeroArgSelector: 617 case DeclarationName::ObjCOneArgSelector: 618 case DeclarationName::ObjCMultiArgSelector: 619 case DeclarationName::CXXUsingDirective: 620 return NameLoc; 621 } 622 llvm_unreachable("Unexpected declaration name kind"); 623 } 624