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