1 //===- DeclarationName.cpp - Declaration names implementation -------------===// 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 15 #include "clang/AST/DeclarationName.h" 16 #include "clang/AST/ASTContext.h" 17 #include "clang/AST/Decl.h" 18 #include "clang/AST/DeclBase.h" 19 #include "clang/AST/DeclCXX.h" 20 #include "clang/AST/DeclTemplate.h" 21 #include "clang/AST/PrettyPrinter.h" 22 #include "clang/AST/Type.h" 23 #include "clang/AST/TypeLoc.h" 24 #include "clang/AST/TypeOrdering.h" 25 #include "clang/Basic/IdentifierTable.h" 26 #include "clang/Basic/LLVM.h" 27 #include "clang/Basic/LangOptions.h" 28 #include "clang/Basic/OperatorKinds.h" 29 #include "clang/Basic/SourceLocation.h" 30 #include "llvm/ADT/FoldingSet.h" 31 #include "llvm/Support/Casting.h" 32 #include "llvm/Support/Compiler.h" 33 #include "llvm/Support/ErrorHandling.h" 34 #include "llvm/Support/raw_ostream.h" 35 #include <algorithm> 36 #include <cassert> 37 #include <cstdint> 38 #include <string> 39 40 using namespace clang; 41 42 static int compareInt(unsigned A, unsigned B) { 43 return (A < B ? -1 : (A > B ? 1 : 0)); 44 } 45 46 int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) { 47 if (LHS.getNameKind() != RHS.getNameKind()) 48 return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1); 49 50 switch (LHS.getNameKind()) { 51 case DeclarationName::Identifier: { 52 IdentifierInfo *LII = LHS.castAsIdentifierInfo(); 53 IdentifierInfo *RII = RHS.castAsIdentifierInfo(); 54 if (!LII) 55 return RII ? -1 : 0; 56 if (!RII) 57 return 1; 58 59 return LII->getName().compare(RII->getName()); 60 } 61 62 case DeclarationName::ObjCZeroArgSelector: 63 case DeclarationName::ObjCOneArgSelector: 64 case DeclarationName::ObjCMultiArgSelector: { 65 Selector LHSSelector = LHS.getObjCSelector(); 66 Selector RHSSelector = RHS.getObjCSelector(); 67 // getNumArgs for ZeroArgSelector returns 0, but we still need to compare. 68 if (LHS.getNameKind() == DeclarationName::ObjCZeroArgSelector && 69 RHS.getNameKind() == DeclarationName::ObjCZeroArgSelector) { 70 return LHSSelector.getAsIdentifierInfo()->getName().compare( 71 RHSSelector.getAsIdentifierInfo()->getName()); 72 } 73 unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs(); 74 for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) { 75 switch (LHSSelector.getNameForSlot(I).compare( 76 RHSSelector.getNameForSlot(I))) { 77 case -1: 78 return -1; 79 case 1: 80 return 1; 81 default: 82 break; 83 } 84 } 85 86 return compareInt(LN, RN); 87 } 88 89 case DeclarationName::CXXConstructorName: 90 case DeclarationName::CXXDestructorName: 91 case DeclarationName::CXXConversionFunctionName: 92 if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType())) 93 return -1; 94 if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType())) 95 return 1; 96 return 0; 97 98 case DeclarationName::CXXDeductionGuideName: 99 // We never want to compare deduction guide names for templates from 100 // different scopes, so just compare the template-name. 101 return compare(LHS.getCXXDeductionGuideTemplate()->getDeclName(), 102 RHS.getCXXDeductionGuideTemplate()->getDeclName()); 103 104 case DeclarationName::CXXOperatorName: 105 return compareInt(LHS.getCXXOverloadedOperator(), 106 RHS.getCXXOverloadedOperator()); 107 108 case DeclarationName::CXXLiteralOperatorName: 109 return LHS.getCXXLiteralIdentifier()->getName().compare( 110 RHS.getCXXLiteralIdentifier()->getName()); 111 112 case DeclarationName::CXXUsingDirective: 113 return 0; 114 } 115 116 llvm_unreachable("Invalid DeclarationName Kind!"); 117 } 118 119 static void printCXXConstructorDestructorName(QualType ClassType, 120 raw_ostream &OS, 121 PrintingPolicy Policy) { 122 // We know we're printing C++ here. Ensure we print types properly. 123 Policy.adjustForCPlusPlus(); 124 125 if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) { 126 OS << *ClassRec->getDecl(); 127 return; 128 } 129 if (Policy.SuppressTemplateArgsInCXXConstructors) { 130 if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) { 131 OS << *InjTy->getDecl(); 132 return; 133 } 134 } 135 ClassType.print(OS, Policy); 136 } 137 138 void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) { 139 switch (getNameKind()) { 140 case DeclarationName::Identifier: 141 if (const IdentifierInfo *II = getAsIdentifierInfo()) 142 OS << II->getName(); 143 return; 144 145 case DeclarationName::ObjCZeroArgSelector: 146 case DeclarationName::ObjCOneArgSelector: 147 case DeclarationName::ObjCMultiArgSelector: 148 getObjCSelector().print(OS); 149 return; 150 151 case DeclarationName::CXXConstructorName: 152 return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy); 153 154 case DeclarationName::CXXDestructorName: 155 OS << '~'; 156 return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy); 157 158 case DeclarationName::CXXDeductionGuideName: 159 OS << "<deduction guide for "; 160 getCXXDeductionGuideTemplate()->getDeclName().print(OS, Policy); 161 OS << '>'; 162 return; 163 164 case DeclarationName::CXXOperatorName: { 165 static const char *const OperatorNames[NUM_OVERLOADED_OPERATORS] = { 166 nullptr, 167 #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \ 168 Spelling, 169 #include "clang/Basic/OperatorKinds.def" 170 }; 171 const char *OpName = OperatorNames[getCXXOverloadedOperator()]; 172 assert(OpName && "not an overloaded operator"); 173 174 OS << "operator"; 175 if (OpName[0] >= 'a' && OpName[0] <= 'z') 176 OS << ' '; 177 OS << OpName; 178 return; 179 } 180 181 case DeclarationName::CXXLiteralOperatorName: 182 OS << "operator\"\"" << getCXXLiteralIdentifier()->getName(); 183 return; 184 185 case DeclarationName::CXXConversionFunctionName: { 186 OS << "operator "; 187 QualType Type = getCXXNameType(); 188 if (const RecordType *Rec = Type->getAs<RecordType>()) { 189 OS << *Rec->getDecl(); 190 return; 191 } 192 // We know we're printing C++ here, ensure we print 'bool' properly. 193 PrintingPolicy CXXPolicy = Policy; 194 CXXPolicy.adjustForCPlusPlus(); 195 Type.print(OS, CXXPolicy); 196 return; 197 } 198 case DeclarationName::CXXUsingDirective: 199 OS << "<using-directive>"; 200 return; 201 } 202 203 llvm_unreachable("Unexpected declaration name kind"); 204 } 205 206 namespace clang { 207 208 raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) { 209 LangOptions LO; 210 N.print(OS, PrintingPolicy(LO)); 211 return OS; 212 } 213 214 } // namespace clang 215 216 bool DeclarationName::isDependentName() const { 217 QualType T = getCXXNameType(); 218 if (!T.isNull() && T->isDependentType()) 219 return true; 220 221 // A class-scope deduction guide in a dependent context has a dependent name. 222 auto *TD = getCXXDeductionGuideTemplate(); 223 if (TD && TD->getDeclContext()->isDependentContext()) 224 return true; 225 226 return false; 227 } 228 229 std::string DeclarationName::getAsString() const { 230 std::string Result; 231 llvm::raw_string_ostream OS(Result); 232 OS << *this; 233 return OS.str(); 234 } 235 236 void *DeclarationName::getFETokenInfoSlow() const { 237 switch (getNameKind()) { 238 case Identifier: 239 llvm_unreachable("case Identifier already handled by getFETokenInfo!"); 240 case CXXConstructorName: 241 case CXXDestructorName: 242 case CXXConversionFunctionName: 243 return castAsCXXSpecialNameExtra()->FETokenInfo; 244 case CXXOperatorName: 245 return castAsCXXOperatorIdName()->FETokenInfo; 246 case CXXDeductionGuideName: 247 return castAsCXXDeductionGuideNameExtra()->FETokenInfo; 248 case CXXLiteralOperatorName: 249 return castAsCXXLiteralOperatorIdName()->FETokenInfo; 250 default: 251 llvm_unreachable("DeclarationName has no FETokenInfo!"); 252 } 253 } 254 255 void DeclarationName::setFETokenInfoSlow(void *T) { 256 switch (getNameKind()) { 257 case Identifier: 258 llvm_unreachable("case Identifier already handled by setFETokenInfo!"); 259 case CXXConstructorName: 260 case CXXDestructorName: 261 case CXXConversionFunctionName: 262 castAsCXXSpecialNameExtra()->FETokenInfo = T; 263 break; 264 case CXXOperatorName: 265 castAsCXXOperatorIdName()->FETokenInfo = T; 266 break; 267 case CXXDeductionGuideName: 268 castAsCXXDeductionGuideNameExtra()->FETokenInfo = T; 269 break; 270 case CXXLiteralOperatorName: 271 castAsCXXLiteralOperatorIdName()->FETokenInfo = T; 272 break; 273 default: 274 llvm_unreachable("DeclarationName has no FETokenInfo!"); 275 } 276 } 277 278 LLVM_DUMP_METHOD void DeclarationName::dump() const { 279 llvm::errs() << *this << '\n'; 280 } 281 282 DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) { 283 // Initialize the overloaded operator names. 284 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) 285 CXXOperatorNames[Op].Kind = static_cast<OverloadedOperatorKind>(Op); 286 } 287 288 DeclarationName 289 DeclarationNameTable::getCXXDeductionGuideName(TemplateDecl *Template) { 290 Template = cast<TemplateDecl>(Template->getCanonicalDecl()); 291 292 llvm::FoldingSetNodeID ID; 293 ID.AddPointer(Template); 294 295 void *InsertPos = nullptr; 296 if (auto *Name = CXXDeductionGuideNames.FindNodeOrInsertPos(ID, InsertPos)) 297 return DeclarationName(Name); 298 299 auto *Name = new (Ctx) detail::CXXDeductionGuideNameExtra(Template); 300 CXXDeductionGuideNames.InsertNode(Name, InsertPos); 301 return DeclarationName(Name); 302 } 303 304 DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) { 305 // The type of constructors is unqualified. 306 Ty = Ty.getUnqualifiedType(); 307 // Do we already have this C++ constructor name ? 308 llvm::FoldingSetNodeID ID; 309 ID.AddPointer(Ty.getAsOpaquePtr()); 310 void *InsertPos = nullptr; 311 if (auto *Name = CXXConstructorNames.FindNodeOrInsertPos(ID, InsertPos)) 312 return {Name, DeclarationName::StoredCXXConstructorName}; 313 314 // We have to create it. 315 auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty); 316 CXXConstructorNames.InsertNode(SpecialName, InsertPos); 317 return {SpecialName, DeclarationName::StoredCXXConstructorName}; 318 } 319 320 DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) { 321 // The type of destructors is unqualified. 322 Ty = Ty.getUnqualifiedType(); 323 // Do we already have this C++ destructor name ? 324 llvm::FoldingSetNodeID ID; 325 ID.AddPointer(Ty.getAsOpaquePtr()); 326 void *InsertPos = nullptr; 327 if (auto *Name = CXXDestructorNames.FindNodeOrInsertPos(ID, InsertPos)) 328 return {Name, DeclarationName::StoredCXXDestructorName}; 329 330 // We have to create it. 331 auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty); 332 CXXDestructorNames.InsertNode(SpecialName, InsertPos); 333 return {SpecialName, DeclarationName::StoredCXXDestructorName}; 334 } 335 336 DeclarationName 337 DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) { 338 // Do we already have this C++ conversion function name ? 339 llvm::FoldingSetNodeID ID; 340 ID.AddPointer(Ty.getAsOpaquePtr()); 341 void *InsertPos = nullptr; 342 if (auto *Name = 343 CXXConversionFunctionNames.FindNodeOrInsertPos(ID, InsertPos)) 344 return {Name, DeclarationName::StoredCXXConversionFunctionName}; 345 346 // We have to create it. 347 auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty); 348 CXXConversionFunctionNames.InsertNode(SpecialName, InsertPos); 349 return {SpecialName, DeclarationName::StoredCXXConversionFunctionName}; 350 } 351 352 DeclarationName 353 DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind, 354 CanQualType Ty) { 355 switch (Kind) { 356 case DeclarationName::CXXConstructorName: 357 return getCXXConstructorName(Ty); 358 case DeclarationName::CXXDestructorName: 359 return getCXXDestructorName(Ty); 360 case DeclarationName::CXXConversionFunctionName: 361 return getCXXConversionFunctionName(Ty); 362 default: 363 llvm_unreachable("Invalid kind in getCXXSpecialName!"); 364 } 365 } 366 367 DeclarationName 368 DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) { 369 llvm::FoldingSetNodeID ID; 370 ID.AddPointer(II); 371 372 void *InsertPos = nullptr; 373 if (auto *Name = CXXLiteralOperatorNames.FindNodeOrInsertPos(ID, InsertPos)) 374 return DeclarationName(Name); 375 376 auto *LiteralName = new (Ctx) detail::CXXLiteralOperatorIdName(II); 377 CXXLiteralOperatorNames.InsertNode(LiteralName, InsertPos); 378 return DeclarationName(LiteralName); 379 } 380 381 DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) { 382 switch (Name.getNameKind()) { 383 case DeclarationName::Identifier: 384 case DeclarationName::CXXDeductionGuideName: 385 break; 386 case DeclarationName::CXXConstructorName: 387 case DeclarationName::CXXDestructorName: 388 case DeclarationName::CXXConversionFunctionName: 389 NamedType.TInfo = nullptr; 390 break; 391 case DeclarationName::CXXOperatorName: 392 CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding(); 393 CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding(); 394 break; 395 case DeclarationName::CXXLiteralOperatorName: 396 CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding(); 397 break; 398 case DeclarationName::ObjCZeroArgSelector: 399 case DeclarationName::ObjCOneArgSelector: 400 case DeclarationName::ObjCMultiArgSelector: 401 // FIXME: ? 402 break; 403 case DeclarationName::CXXUsingDirective: 404 break; 405 } 406 } 407 408 bool DeclarationNameInfo::containsUnexpandedParameterPack() const { 409 switch (Name.getNameKind()) { 410 case DeclarationName::Identifier: 411 case DeclarationName::ObjCZeroArgSelector: 412 case DeclarationName::ObjCOneArgSelector: 413 case DeclarationName::ObjCMultiArgSelector: 414 case DeclarationName::CXXOperatorName: 415 case DeclarationName::CXXLiteralOperatorName: 416 case DeclarationName::CXXUsingDirective: 417 case DeclarationName::CXXDeductionGuideName: 418 return false; 419 420 case DeclarationName::CXXConstructorName: 421 case DeclarationName::CXXDestructorName: 422 case DeclarationName::CXXConversionFunctionName: 423 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) 424 return TInfo->getType()->containsUnexpandedParameterPack(); 425 426 return Name.getCXXNameType()->containsUnexpandedParameterPack(); 427 } 428 llvm_unreachable("All name kinds handled."); 429 } 430 431 bool DeclarationNameInfo::isInstantiationDependent() const { 432 switch (Name.getNameKind()) { 433 case DeclarationName::Identifier: 434 case DeclarationName::ObjCZeroArgSelector: 435 case DeclarationName::ObjCOneArgSelector: 436 case DeclarationName::ObjCMultiArgSelector: 437 case DeclarationName::CXXOperatorName: 438 case DeclarationName::CXXLiteralOperatorName: 439 case DeclarationName::CXXUsingDirective: 440 case DeclarationName::CXXDeductionGuideName: 441 return false; 442 443 case DeclarationName::CXXConstructorName: 444 case DeclarationName::CXXDestructorName: 445 case DeclarationName::CXXConversionFunctionName: 446 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) 447 return TInfo->getType()->isInstantiationDependentType(); 448 449 return Name.getCXXNameType()->isInstantiationDependentType(); 450 } 451 llvm_unreachable("All name kinds handled."); 452 } 453 454 std::string DeclarationNameInfo::getAsString() const { 455 std::string Result; 456 llvm::raw_string_ostream OS(Result); 457 printName(OS); 458 return OS.str(); 459 } 460 461 void DeclarationNameInfo::printName(raw_ostream &OS) const { 462 switch (Name.getNameKind()) { 463 case DeclarationName::Identifier: 464 case DeclarationName::ObjCZeroArgSelector: 465 case DeclarationName::ObjCOneArgSelector: 466 case DeclarationName::ObjCMultiArgSelector: 467 case DeclarationName::CXXOperatorName: 468 case DeclarationName::CXXLiteralOperatorName: 469 case DeclarationName::CXXUsingDirective: 470 case DeclarationName::CXXDeductionGuideName: 471 OS << Name; 472 return; 473 474 case DeclarationName::CXXConstructorName: 475 case DeclarationName::CXXDestructorName: 476 case DeclarationName::CXXConversionFunctionName: 477 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) { 478 if (Name.getNameKind() == DeclarationName::CXXDestructorName) 479 OS << '~'; 480 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName) 481 OS << "operator "; 482 LangOptions LO; 483 LO.CPlusPlus = true; 484 LO.Bool = true; 485 PrintingPolicy PP(LO); 486 PP.SuppressScope = true; 487 OS << TInfo->getType().getAsString(PP); 488 } else 489 OS << Name; 490 return; 491 } 492 llvm_unreachable("Unexpected declaration name kind"); 493 } 494 495 SourceLocation DeclarationNameInfo::getEndLocPrivate() const { 496 switch (Name.getNameKind()) { 497 case DeclarationName::Identifier: 498 case DeclarationName::CXXDeductionGuideName: 499 return NameLoc; 500 501 case DeclarationName::CXXOperatorName: { 502 unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc; 503 return SourceLocation::getFromRawEncoding(raw); 504 } 505 506 case DeclarationName::CXXLiteralOperatorName: { 507 unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc; 508 return SourceLocation::getFromRawEncoding(raw); 509 } 510 511 case DeclarationName::CXXConstructorName: 512 case DeclarationName::CXXDestructorName: 513 case DeclarationName::CXXConversionFunctionName: 514 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) 515 return TInfo->getTypeLoc().getEndLoc(); 516 else 517 return NameLoc; 518 519 // DNInfo work in progress: FIXME. 520 case DeclarationName::ObjCZeroArgSelector: 521 case DeclarationName::ObjCOneArgSelector: 522 case DeclarationName::ObjCMultiArgSelector: 523 case DeclarationName::CXXUsingDirective: 524 return NameLoc; 525 } 526 llvm_unreachable("Unexpected declaration name kind"); 527 } 528