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