1 //===- DeclarationName.cpp - Declaration names implementation -------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements the DeclarationName and DeclarationNameTable 10 // classes. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/AST/DeclarationName.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/Decl.h" 17 #include "clang/AST/DeclBase.h" 18 #include "clang/AST/DeclCXX.h" 19 #include "clang/AST/DeclTemplate.h" 20 #include "clang/AST/OpenMPClause.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, 139 const PrintingPolicy &Policy) const { 140 switch (getNameKind()) { 141 case DeclarationName::Identifier: 142 if (const IdentifierInfo *II = getAsIdentifierInfo()) { 143 StringRef Name = II->getName(); 144 // If this is a mangled OpenMP variant name we strip off the mangling for 145 // printing. It should not be visible to the user at all. 146 if (II->isMangledOpenMPVariantName()) { 147 std::pair<StringRef, StringRef> NameContextPair = 148 Name.split(getOpenMPVariantManglingSeparatorStr()); 149 OS << NameContextPair.first << "[" 150 << OMPTraitInfo(NameContextPair.second) << "]"; 151 } else { 152 OS << Name; 153 } 154 } 155 return; 156 157 case DeclarationName::ObjCZeroArgSelector: 158 case DeclarationName::ObjCOneArgSelector: 159 case DeclarationName::ObjCMultiArgSelector: 160 getObjCSelector().print(OS); 161 return; 162 163 case DeclarationName::CXXConstructorName: 164 return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy); 165 166 case DeclarationName::CXXDestructorName: 167 OS << '~'; 168 return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy); 169 170 case DeclarationName::CXXDeductionGuideName: 171 OS << "<deduction guide for "; 172 getCXXDeductionGuideTemplate()->getDeclName().print(OS, Policy); 173 OS << '>'; 174 return; 175 176 case DeclarationName::CXXOperatorName: { 177 const char *OpName = getOperatorSpelling(getCXXOverloadedOperator()); 178 assert(OpName && "not an overloaded operator"); 179 180 OS << "operator"; 181 if (OpName[0] >= 'a' && OpName[0] <= 'z') 182 OS << ' '; 183 OS << OpName; 184 return; 185 } 186 187 case DeclarationName::CXXLiteralOperatorName: 188 OS << "operator\"\"" << getCXXLiteralIdentifier()->getName(); 189 return; 190 191 case DeclarationName::CXXConversionFunctionName: { 192 OS << "operator "; 193 QualType Type = getCXXNameType(); 194 if (const RecordType *Rec = Type->getAs<RecordType>()) { 195 OS << *Rec->getDecl(); 196 return; 197 } 198 // We know we're printing C++ here, ensure we print 'bool' properly. 199 PrintingPolicy CXXPolicy = Policy; 200 CXXPolicy.adjustForCPlusPlus(); 201 Type.print(OS, CXXPolicy); 202 return; 203 } 204 case DeclarationName::CXXUsingDirective: 205 OS << "<using-directive>"; 206 return; 207 } 208 209 llvm_unreachable("Unexpected declaration name kind"); 210 } 211 212 namespace clang { 213 214 raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) { 215 LangOptions LO; 216 N.print(OS, PrintingPolicy(LO)); 217 return OS; 218 } 219 220 } // namespace clang 221 222 bool DeclarationName::isDependentName() const { 223 QualType T = getCXXNameType(); 224 if (!T.isNull() && T->isDependentType()) 225 return true; 226 227 // A class-scope deduction guide in a dependent context has a dependent name. 228 auto *TD = getCXXDeductionGuideTemplate(); 229 if (TD && TD->getDeclContext()->isDependentContext()) 230 return true; 231 232 return false; 233 } 234 235 std::string DeclarationName::getAsString() const { 236 std::string Result; 237 llvm::raw_string_ostream OS(Result); 238 OS << *this; 239 return OS.str(); 240 } 241 242 void *DeclarationName::getFETokenInfoSlow() const { 243 switch (getNameKind()) { 244 case Identifier: 245 llvm_unreachable("case Identifier already handled by getFETokenInfo!"); 246 case CXXConstructorName: 247 case CXXDestructorName: 248 case CXXConversionFunctionName: 249 return castAsCXXSpecialNameExtra()->FETokenInfo; 250 case CXXOperatorName: 251 return castAsCXXOperatorIdName()->FETokenInfo; 252 case CXXDeductionGuideName: 253 return castAsCXXDeductionGuideNameExtra()->FETokenInfo; 254 case CXXLiteralOperatorName: 255 return castAsCXXLiteralOperatorIdName()->FETokenInfo; 256 default: 257 llvm_unreachable("DeclarationName has no FETokenInfo!"); 258 } 259 } 260 261 void DeclarationName::setFETokenInfoSlow(void *T) { 262 switch (getNameKind()) { 263 case Identifier: 264 llvm_unreachable("case Identifier already handled by setFETokenInfo!"); 265 case CXXConstructorName: 266 case CXXDestructorName: 267 case CXXConversionFunctionName: 268 castAsCXXSpecialNameExtra()->FETokenInfo = T; 269 break; 270 case CXXOperatorName: 271 castAsCXXOperatorIdName()->FETokenInfo = T; 272 break; 273 case CXXDeductionGuideName: 274 castAsCXXDeductionGuideNameExtra()->FETokenInfo = T; 275 break; 276 case CXXLiteralOperatorName: 277 castAsCXXLiteralOperatorIdName()->FETokenInfo = T; 278 break; 279 default: 280 llvm_unreachable("DeclarationName has no FETokenInfo!"); 281 } 282 } 283 284 LLVM_DUMP_METHOD void DeclarationName::dump() const { 285 llvm::errs() << *this << '\n'; 286 } 287 288 DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) { 289 // Initialize the overloaded operator names. 290 for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) 291 CXXOperatorNames[Op].Kind = static_cast<OverloadedOperatorKind>(Op); 292 } 293 294 DeclarationName 295 DeclarationNameTable::getCXXDeductionGuideName(TemplateDecl *Template) { 296 Template = cast<TemplateDecl>(Template->getCanonicalDecl()); 297 298 llvm::FoldingSetNodeID ID; 299 ID.AddPointer(Template); 300 301 void *InsertPos = nullptr; 302 if (auto *Name = CXXDeductionGuideNames.FindNodeOrInsertPos(ID, InsertPos)) 303 return DeclarationName(Name); 304 305 auto *Name = new (Ctx) detail::CXXDeductionGuideNameExtra(Template); 306 CXXDeductionGuideNames.InsertNode(Name, InsertPos); 307 return DeclarationName(Name); 308 } 309 310 DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) { 311 // The type of constructors is unqualified. 312 Ty = Ty.getUnqualifiedType(); 313 // Do we already have this C++ constructor name ? 314 llvm::FoldingSetNodeID ID; 315 ID.AddPointer(Ty.getAsOpaquePtr()); 316 void *InsertPos = nullptr; 317 if (auto *Name = CXXConstructorNames.FindNodeOrInsertPos(ID, InsertPos)) 318 return {Name, DeclarationName::StoredCXXConstructorName}; 319 320 // We have to create it. 321 auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty); 322 CXXConstructorNames.InsertNode(SpecialName, InsertPos); 323 return {SpecialName, DeclarationName::StoredCXXConstructorName}; 324 } 325 326 DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) { 327 // The type of destructors is unqualified. 328 Ty = Ty.getUnqualifiedType(); 329 // Do we already have this C++ destructor name ? 330 llvm::FoldingSetNodeID ID; 331 ID.AddPointer(Ty.getAsOpaquePtr()); 332 void *InsertPos = nullptr; 333 if (auto *Name = CXXDestructorNames.FindNodeOrInsertPos(ID, InsertPos)) 334 return {Name, DeclarationName::StoredCXXDestructorName}; 335 336 // We have to create it. 337 auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty); 338 CXXDestructorNames.InsertNode(SpecialName, InsertPos); 339 return {SpecialName, DeclarationName::StoredCXXDestructorName}; 340 } 341 342 DeclarationName 343 DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) { 344 // Do we already have this C++ conversion function name ? 345 llvm::FoldingSetNodeID ID; 346 ID.AddPointer(Ty.getAsOpaquePtr()); 347 void *InsertPos = nullptr; 348 if (auto *Name = 349 CXXConversionFunctionNames.FindNodeOrInsertPos(ID, InsertPos)) 350 return {Name, DeclarationName::StoredCXXConversionFunctionName}; 351 352 // We have to create it. 353 auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty); 354 CXXConversionFunctionNames.InsertNode(SpecialName, InsertPos); 355 return {SpecialName, DeclarationName::StoredCXXConversionFunctionName}; 356 } 357 358 DeclarationName 359 DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind, 360 CanQualType Ty) { 361 switch (Kind) { 362 case DeclarationName::CXXConstructorName: 363 return getCXXConstructorName(Ty); 364 case DeclarationName::CXXDestructorName: 365 return getCXXDestructorName(Ty); 366 case DeclarationName::CXXConversionFunctionName: 367 return getCXXConversionFunctionName(Ty); 368 default: 369 llvm_unreachable("Invalid kind in getCXXSpecialName!"); 370 } 371 } 372 373 DeclarationName 374 DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) { 375 llvm::FoldingSetNodeID ID; 376 ID.AddPointer(II); 377 378 void *InsertPos = nullptr; 379 if (auto *Name = CXXLiteralOperatorNames.FindNodeOrInsertPos(ID, InsertPos)) 380 return DeclarationName(Name); 381 382 auto *LiteralName = new (Ctx) detail::CXXLiteralOperatorIdName(II); 383 CXXLiteralOperatorNames.InsertNode(LiteralName, InsertPos); 384 return DeclarationName(LiteralName); 385 } 386 387 DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) { 388 switch (Name.getNameKind()) { 389 case DeclarationName::Identifier: 390 case DeclarationName::CXXDeductionGuideName: 391 break; 392 case DeclarationName::CXXConstructorName: 393 case DeclarationName::CXXDestructorName: 394 case DeclarationName::CXXConversionFunctionName: 395 NamedType.TInfo = nullptr; 396 break; 397 case DeclarationName::CXXOperatorName: 398 CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding(); 399 CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding(); 400 break; 401 case DeclarationName::CXXLiteralOperatorName: 402 CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding(); 403 break; 404 case DeclarationName::ObjCZeroArgSelector: 405 case DeclarationName::ObjCOneArgSelector: 406 case DeclarationName::ObjCMultiArgSelector: 407 // FIXME: ? 408 break; 409 case DeclarationName::CXXUsingDirective: 410 break; 411 } 412 } 413 414 bool DeclarationNameInfo::containsUnexpandedParameterPack() const { 415 switch (Name.getNameKind()) { 416 case DeclarationName::Identifier: 417 case DeclarationName::ObjCZeroArgSelector: 418 case DeclarationName::ObjCOneArgSelector: 419 case DeclarationName::ObjCMultiArgSelector: 420 case DeclarationName::CXXOperatorName: 421 case DeclarationName::CXXLiteralOperatorName: 422 case DeclarationName::CXXUsingDirective: 423 case DeclarationName::CXXDeductionGuideName: 424 return false; 425 426 case DeclarationName::CXXConstructorName: 427 case DeclarationName::CXXDestructorName: 428 case DeclarationName::CXXConversionFunctionName: 429 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) 430 return TInfo->getType()->containsUnexpandedParameterPack(); 431 432 return Name.getCXXNameType()->containsUnexpandedParameterPack(); 433 } 434 llvm_unreachable("All name kinds handled."); 435 } 436 437 bool DeclarationNameInfo::isInstantiationDependent() const { 438 switch (Name.getNameKind()) { 439 case DeclarationName::Identifier: 440 case DeclarationName::ObjCZeroArgSelector: 441 case DeclarationName::ObjCOneArgSelector: 442 case DeclarationName::ObjCMultiArgSelector: 443 case DeclarationName::CXXOperatorName: 444 case DeclarationName::CXXLiteralOperatorName: 445 case DeclarationName::CXXUsingDirective: 446 case DeclarationName::CXXDeductionGuideName: 447 return false; 448 449 case DeclarationName::CXXConstructorName: 450 case DeclarationName::CXXDestructorName: 451 case DeclarationName::CXXConversionFunctionName: 452 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) 453 return TInfo->getType()->isInstantiationDependentType(); 454 455 return Name.getCXXNameType()->isInstantiationDependentType(); 456 } 457 llvm_unreachable("All name kinds handled."); 458 } 459 460 std::string DeclarationNameInfo::getAsString() const { 461 std::string Result; 462 llvm::raw_string_ostream OS(Result); 463 OS << *this; 464 return OS.str(); 465 } 466 467 raw_ostream &clang::operator<<(raw_ostream &OS, DeclarationNameInfo DNInfo) { 468 LangOptions LO; 469 DNInfo.printName(OS, PrintingPolicy(LangOptions())); 470 return OS; 471 } 472 473 void DeclarationNameInfo::printName(raw_ostream &OS, PrintingPolicy Policy) const { 474 switch (Name.getNameKind()) { 475 case DeclarationName::Identifier: 476 case DeclarationName::ObjCZeroArgSelector: 477 case DeclarationName::ObjCOneArgSelector: 478 case DeclarationName::ObjCMultiArgSelector: 479 case DeclarationName::CXXOperatorName: 480 case DeclarationName::CXXLiteralOperatorName: 481 case DeclarationName::CXXUsingDirective: 482 case DeclarationName::CXXDeductionGuideName: 483 Name.print(OS, Policy); 484 return; 485 486 case DeclarationName::CXXConstructorName: 487 case DeclarationName::CXXDestructorName: 488 case DeclarationName::CXXConversionFunctionName: 489 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) { 490 if (Name.getNameKind() == DeclarationName::CXXDestructorName) 491 OS << '~'; 492 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName) 493 OS << "operator "; 494 LangOptions LO; 495 Policy.adjustForCPlusPlus(); 496 Policy.SuppressScope = true; 497 OS << TInfo->getType().getAsString(Policy); 498 } else 499 Name.print(OS, Policy); 500 return; 501 } 502 llvm_unreachable("Unexpected declaration name kind"); 503 } 504 505 SourceLocation DeclarationNameInfo::getEndLocPrivate() const { 506 switch (Name.getNameKind()) { 507 case DeclarationName::Identifier: 508 case DeclarationName::CXXDeductionGuideName: 509 return NameLoc; 510 511 case DeclarationName::CXXOperatorName: { 512 unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc; 513 return SourceLocation::getFromRawEncoding(raw); 514 } 515 516 case DeclarationName::CXXLiteralOperatorName: { 517 unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc; 518 return SourceLocation::getFromRawEncoding(raw); 519 } 520 521 case DeclarationName::CXXConstructorName: 522 case DeclarationName::CXXDestructorName: 523 case DeclarationName::CXXConversionFunctionName: 524 if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) 525 return TInfo->getTypeLoc().getEndLoc(); 526 else 527 return NameLoc; 528 529 // DNInfo work in progress: FIXME. 530 case DeclarationName::ObjCZeroArgSelector: 531 case DeclarationName::ObjCOneArgSelector: 532 case DeclarationName::ObjCMultiArgSelector: 533 case DeclarationName::CXXUsingDirective: 534 return NameLoc; 535 } 536 llvm_unreachable("Unexpected declaration name kind"); 537 } 538