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