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 llvm_unreachable("Invalid DeclarationName Kind!"); 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 } 193 194 // Can't actually get here. 195 llvm_unreachable("This should be unreachable!"); 196 } 197 198 bool DeclarationName::isDependentName() const { 199 QualType T = getCXXNameType(); 200 return !T.isNull() && T->isDependentType(); 201 } 202 203 std::string DeclarationName::getAsString() const { 204 std::string Result; 205 llvm::raw_string_ostream OS(Result); 206 printName(OS); 207 return OS.str(); 208 } 209 210 void DeclarationName::printName(raw_ostream &OS) const { 211 switch (getNameKind()) { 212 case Identifier: 213 if (const IdentifierInfo *II = getAsIdentifierInfo()) 214 OS << II->getName(); 215 return; 216 217 case ObjCZeroArgSelector: 218 case ObjCOneArgSelector: 219 case ObjCMultiArgSelector: 220 OS << getObjCSelector().getAsString(); 221 return; 222 223 case CXXConstructorName: { 224 QualType ClassType = getCXXNameType(); 225 if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) 226 OS << *ClassRec->getDecl(); 227 else 228 OS << ClassType.getAsString(); 229 return; 230 } 231 232 case CXXDestructorName: { 233 OS << '~'; 234 QualType Type = getCXXNameType(); 235 if (const RecordType *Rec = Type->getAs<RecordType>()) 236 OS << *Rec->getDecl(); 237 else 238 OS << Type.getAsString(); 239 return; 240 } 241 242 case CXXOperatorName: { 243 static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = { 244 0, 245 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 246 Spelling, 247 #include "clang/Basic/OperatorKinds.def" 248 }; 249 const char *OpName = OperatorNames[getCXXOverloadedOperator()]; 250 assert(OpName && "not an overloaded operator"); 251 252 OS << "operator"; 253 if (OpName[0] >= 'a' && OpName[0] <= 'z') 254 OS << ' '; 255 OS << OpName; 256 return; 257 } 258 259 case CXXLiteralOperatorName: 260 OS << "operator \"\" " << getCXXLiteralIdentifier()->getName(); 261 return; 262 263 case CXXConversionFunctionName: { 264 OS << "operator "; 265 QualType Type = getCXXNameType(); 266 if (const RecordType *Rec = Type->getAs<RecordType>()) 267 OS << *Rec->getDecl(); 268 else 269 OS << Type.getAsString(); 270 return; 271 } 272 case CXXUsingDirective: 273 OS << "<using-directive>"; 274 return; 275 } 276 277 llvm_unreachable("Unexpected declaration name kind"); 278 } 279 280 QualType DeclarationName::getCXXNameType() const { 281 if (CXXSpecialName *CXXName = getAsCXXSpecialName()) 282 return CXXName->Type; 283 else 284 return QualType(); 285 } 286 287 OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const { 288 if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) { 289 unsigned value 290 = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction; 291 return static_cast<OverloadedOperatorKind>(value); 292 } else { 293 return OO_None; 294 } 295 } 296 297 IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const { 298 if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName()) 299 return CXXLit->ID; 300 else 301 return 0; 302 } 303 304 Selector DeclarationName::getObjCSelector() const { 305 switch (getNameKind()) { 306 case ObjCZeroArgSelector: 307 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 0); 308 309 case ObjCOneArgSelector: 310 return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 1); 311 312 case ObjCMultiArgSelector: 313 return Selector(reinterpret_cast<MultiKeywordSelector *>(Ptr & ~PtrMask)); 314 315 default: 316 break; 317 } 318 319 return Selector(); 320 } 321 322 void *DeclarationName::getFETokenInfoAsVoid() const { 323 switch (getNameKind()) { 324 case Identifier: 325 return getAsIdentifierInfo()->getFETokenInfo<void>(); 326 327 case CXXConstructorName: 328 case CXXDestructorName: 329 case CXXConversionFunctionName: 330 return getAsCXXSpecialName()->FETokenInfo; 331 332 case CXXOperatorName: 333 return getAsCXXOperatorIdName()->FETokenInfo; 334 335 case CXXLiteralOperatorName: 336 return getCXXLiteralIdentifier()->getFETokenInfo<void>(); 337 338 default: 339 llvm_unreachable("Declaration name has no FETokenInfo"); 340 } 341 } 342 343 void DeclarationName::setFETokenInfo(void *T) { 344 switch (getNameKind()) { 345 case Identifier: 346 getAsIdentifierInfo()->setFETokenInfo(T); 347 break; 348 349 case CXXConstructorName: 350 case CXXDestructorName: 351 case CXXConversionFunctionName: 352 getAsCXXSpecialName()->FETokenInfo = T; 353 break; 354 355 case CXXOperatorName: 356 getAsCXXOperatorIdName()->FETokenInfo = T; 357 break; 358 359 case CXXLiteralOperatorName: 360 getCXXLiteralIdentifier()->setFETokenInfo(T); 361 break; 362 363 default: 364 llvm_unreachable("Declaration name has no FETokenInfo"); 365 } 366 } 367 368 DeclarationName DeclarationName::getUsingDirectiveName() { 369 // Single instance of DeclarationNameExtra for using-directive 370 static const DeclarationNameExtra UDirExtra = 371 { DeclarationNameExtra::CXXUsingDirective }; 372 373 uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra); 374 Ptr |= StoredDeclarationNameExtra; 375 376 return DeclarationName(Ptr); 377 } 378 379 void DeclarationName::dump() const { 380 printName(llvm::errs()); 381 llvm::errs() << '\n'; 382 } 383 384 DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) { 385 CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>; 386 CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>; 387 388 // Initialize the overloaded operator names. 389 CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS]; 390 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) { 391 CXXOperatorNames[Op].ExtraKindOrNumArgs 392 = Op + DeclarationNameExtra::CXXConversionFunction; 393 CXXOperatorNames[Op].FETokenInfo = 0; 394 } 395 } 396 397 DeclarationNameTable::~DeclarationNameTable() { 398 llvm::FoldingSet<CXXSpecialName> *SpecialNames = 399 static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl); 400 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames 401 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*> 402 (CXXLiteralOperatorNames); 403 404 delete SpecialNames; 405 delete LiteralNames; 406 } 407 408 DeclarationName 409 DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind, 410 CanQualType Ty) { 411 assert(Kind >= DeclarationName::CXXConstructorName && 412 Kind <= DeclarationName::CXXConversionFunctionName && 413 "Kind must be a C++ special name kind"); 414 llvm::FoldingSet<CXXSpecialName> *SpecialNames 415 = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl); 416 417 DeclarationNameExtra::ExtraKind EKind; 418 switch (Kind) { 419 case DeclarationName::CXXConstructorName: 420 EKind = DeclarationNameExtra::CXXConstructor; 421 assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified"); 422 break; 423 case DeclarationName::CXXDestructorName: 424 EKind = DeclarationNameExtra::CXXDestructor; 425 assert(!Ty.hasQualifiers() && "Destructor type must be unqualified"); 426 break; 427 case DeclarationName::CXXConversionFunctionName: 428 EKind = DeclarationNameExtra::CXXConversionFunction; 429 break; 430 default: 431 return DeclarationName(); 432 } 433 434 // Unique selector, to guarantee there is one per name. 435 llvm::FoldingSetNodeID ID; 436 ID.AddInteger(EKind); 437 ID.AddPointer(Ty.getAsOpaquePtr()); 438 439 void *InsertPos = 0; 440 if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos)) 441 return DeclarationName(Name); 442 443 CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName; 444 SpecialName->ExtraKindOrNumArgs = EKind; 445 SpecialName->Type = Ty; 446 SpecialName->FETokenInfo = 0; 447 448 SpecialNames->InsertNode(SpecialName, InsertPos); 449 return DeclarationName(SpecialName); 450 } 451 452 DeclarationName 453 DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) { 454 return DeclarationName(&CXXOperatorNames[(unsigned)Op]); 455 } 456 457 DeclarationName 458 DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) { 459 llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames 460 = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*> 461 (CXXLiteralOperatorNames); 462 463 llvm::FoldingSetNodeID ID; 464 ID.AddPointer(II); 465 466 void *InsertPos = 0; 467 if (CXXLiteralOperatorIdName *Name = 468 LiteralNames->FindNodeOrInsertPos(ID, InsertPos)) 469 return DeclarationName (Name); 470 471 CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName; 472 LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator; 473 LiteralName->ID = II; 474 475 LiteralNames->InsertNode(LiteralName, InsertPos); 476 return DeclarationName(LiteralName); 477 } 478 479 unsigned 480 llvm::DenseMapInfo<clang::DeclarationName>:: 481 getHashValue(clang::DeclarationName N) { 482 return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr()); 483 } 484 485 DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) { 486 switch (Name.getNameKind()) { 487 case DeclarationName::Identifier: 488 break; 489 case DeclarationName::CXXConstructorName: 490 case DeclarationName::CXXDestructorName: 491 case DeclarationName::CXXConversionFunctionName: 492 NamedType.TInfo = 0; 493 break; 494 case DeclarationName::CXXOperatorName: 495 CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding(); 496 CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding(); 497 break; 498 case DeclarationName::CXXLiteralOperatorName: 499 CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding(); 500 break; 501 case DeclarationName::ObjCZeroArgSelector: 502 case DeclarationName::ObjCOneArgSelector: 503 case DeclarationName::ObjCMultiArgSelector: 504 // FIXME: ? 505 break; 506 case DeclarationName::CXXUsingDirective: 507 break; 508 } 509 } 510 511 bool DeclarationNameInfo::containsUnexpandedParameterPack() const { 512 switch (Name.getNameKind()) { 513 case DeclarationName::Identifier: 514 case DeclarationName::ObjCZeroArgSelector: 515 case DeclarationName::ObjCOneArgSelector: 516 case DeclarationName::ObjCMultiArgSelector: 517 case DeclarationName::CXXOperatorName: 518 case DeclarationName::CXXLiteralOperatorName: 519 case DeclarationName::CXXUsingDirective: 520 return false; 521 522 case DeclarationName::CXXConstructorName: 523 case DeclarationName::CXXDestructorName: 524 case DeclarationName::CXXConversionFunctionName: 525 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) 526 return TInfo->getType()->containsUnexpandedParameterPack(); 527 528 return Name.getCXXNameType()->containsUnexpandedParameterPack(); 529 } 530 llvm_unreachable("All name kinds handled."); 531 } 532 533 bool DeclarationNameInfo::isInstantiationDependent() const { 534 switch (Name.getNameKind()) { 535 case DeclarationName::Identifier: 536 case DeclarationName::ObjCZeroArgSelector: 537 case DeclarationName::ObjCOneArgSelector: 538 case DeclarationName::ObjCMultiArgSelector: 539 case DeclarationName::CXXOperatorName: 540 case DeclarationName::CXXLiteralOperatorName: 541 case DeclarationName::CXXUsingDirective: 542 return false; 543 544 case DeclarationName::CXXConstructorName: 545 case DeclarationName::CXXDestructorName: 546 case DeclarationName::CXXConversionFunctionName: 547 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) 548 return TInfo->getType()->isInstantiationDependentType(); 549 550 return Name.getCXXNameType()->isInstantiationDependentType(); 551 } 552 llvm_unreachable("All name kinds handled."); 553 } 554 555 std::string DeclarationNameInfo::getAsString() const { 556 std::string Result; 557 llvm::raw_string_ostream OS(Result); 558 printName(OS); 559 return OS.str(); 560 } 561 562 void DeclarationNameInfo::printName(raw_ostream &OS) const { 563 switch (Name.getNameKind()) { 564 case DeclarationName::Identifier: 565 case DeclarationName::ObjCZeroArgSelector: 566 case DeclarationName::ObjCOneArgSelector: 567 case DeclarationName::ObjCMultiArgSelector: 568 case DeclarationName::CXXOperatorName: 569 case DeclarationName::CXXLiteralOperatorName: 570 case DeclarationName::CXXUsingDirective: 571 Name.printName(OS); 572 return; 573 574 case DeclarationName::CXXConstructorName: 575 case DeclarationName::CXXDestructorName: 576 case DeclarationName::CXXConversionFunctionName: 577 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) { 578 if (Name.getNameKind() == DeclarationName::CXXDestructorName) 579 OS << '~'; 580 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName) 581 OS << "operator "; 582 OS << TInfo->getType().getAsString(); 583 } 584 else 585 Name.printName(OS); 586 return; 587 } 588 llvm_unreachable("Unexpected declaration name kind"); 589 } 590 591 SourceLocation DeclarationNameInfo::getEndLoc() const { 592 switch (Name.getNameKind()) { 593 case DeclarationName::Identifier: 594 return NameLoc; 595 596 case DeclarationName::CXXOperatorName: { 597 unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc; 598 return SourceLocation::getFromRawEncoding(raw); 599 } 600 601 case DeclarationName::CXXLiteralOperatorName: { 602 unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc; 603 return SourceLocation::getFromRawEncoding(raw); 604 } 605 606 case DeclarationName::CXXConstructorName: 607 case DeclarationName::CXXDestructorName: 608 case DeclarationName::CXXConversionFunctionName: 609 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) 610 return TInfo->getTypeLoc().getEndLoc(); 611 else 612 return NameLoc; 613 614 // DNInfo work in progress: FIXME. 615 case DeclarationName::ObjCZeroArgSelector: 616 case DeclarationName::ObjCOneArgSelector: 617 case DeclarationName::ObjCMultiArgSelector: 618 case DeclarationName::CXXUsingDirective: 619 return NameLoc; 620 } 621 llvm_unreachable("Unexpected declaration name kind"); 622 } 623