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