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