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 Result; 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 setNamedTypeLoc(nullptr); 396 break; 397 case DeclarationName::CXXOperatorName: 398 setCXXOperatorNameRange(SourceRange()); 399 break; 400 case DeclarationName::CXXLiteralOperatorName: 401 setCXXLiteralOperatorNameLoc(SourceLocation()); 402 break; 403 case DeclarationName::ObjCZeroArgSelector: 404 case DeclarationName::ObjCOneArgSelector: 405 case DeclarationName::ObjCMultiArgSelector: 406 // FIXME: ? 407 break; 408 case DeclarationName::CXXUsingDirective: 409 break; 410 } 411 } 412 413 bool DeclarationNameInfo::containsUnexpandedParameterPack() const { 414 switch (Name.getNameKind()) { 415 case DeclarationName::Identifier: 416 case DeclarationName::ObjCZeroArgSelector: 417 case DeclarationName::ObjCOneArgSelector: 418 case DeclarationName::ObjCMultiArgSelector: 419 case DeclarationName::CXXOperatorName: 420 case DeclarationName::CXXLiteralOperatorName: 421 case DeclarationName::CXXUsingDirective: 422 case DeclarationName::CXXDeductionGuideName: 423 return false; 424 425 case DeclarationName::CXXConstructorName: 426 case DeclarationName::CXXDestructorName: 427 case DeclarationName::CXXConversionFunctionName: 428 if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo()) 429 return TInfo->getType()->containsUnexpandedParameterPack(); 430 431 return Name.getCXXNameType()->containsUnexpandedParameterPack(); 432 } 433 llvm_unreachable("All name kinds handled."); 434 } 435 436 bool DeclarationNameInfo::isInstantiationDependent() const { 437 switch (Name.getNameKind()) { 438 case DeclarationName::Identifier: 439 case DeclarationName::ObjCZeroArgSelector: 440 case DeclarationName::ObjCOneArgSelector: 441 case DeclarationName::ObjCMultiArgSelector: 442 case DeclarationName::CXXOperatorName: 443 case DeclarationName::CXXLiteralOperatorName: 444 case DeclarationName::CXXUsingDirective: 445 case DeclarationName::CXXDeductionGuideName: 446 return false; 447 448 case DeclarationName::CXXConstructorName: 449 case DeclarationName::CXXDestructorName: 450 case DeclarationName::CXXConversionFunctionName: 451 if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo()) 452 return TInfo->getType()->isInstantiationDependentType(); 453 454 return Name.getCXXNameType()->isInstantiationDependentType(); 455 } 456 llvm_unreachable("All name kinds handled."); 457 } 458 459 std::string DeclarationNameInfo::getAsString() const { 460 std::string Result; 461 llvm::raw_string_ostream OS(Result); 462 OS << *this; 463 return Result; 464 } 465 466 raw_ostream &clang::operator<<(raw_ostream &OS, DeclarationNameInfo DNInfo) { 467 LangOptions LO; 468 DNInfo.printName(OS, PrintingPolicy(LangOptions())); 469 return OS; 470 } 471 472 void DeclarationNameInfo::printName(raw_ostream &OS, PrintingPolicy Policy) const { 473 switch (Name.getNameKind()) { 474 case DeclarationName::Identifier: 475 case DeclarationName::ObjCZeroArgSelector: 476 case DeclarationName::ObjCOneArgSelector: 477 case DeclarationName::ObjCMultiArgSelector: 478 case DeclarationName::CXXOperatorName: 479 case DeclarationName::CXXLiteralOperatorName: 480 case DeclarationName::CXXUsingDirective: 481 case DeclarationName::CXXDeductionGuideName: 482 Name.print(OS, Policy); 483 return; 484 485 case DeclarationName::CXXConstructorName: 486 case DeclarationName::CXXDestructorName: 487 case DeclarationName::CXXConversionFunctionName: 488 if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo()) { 489 if (Name.getNameKind() == DeclarationName::CXXDestructorName) 490 OS << '~'; 491 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName) 492 OS << "operator "; 493 LangOptions LO; 494 Policy.adjustForCPlusPlus(); 495 Policy.SuppressScope = true; 496 OS << TInfo->getType().getAsString(Policy); 497 } else 498 Name.print(OS, Policy); 499 return; 500 } 501 llvm_unreachable("Unexpected declaration name kind"); 502 } 503 504 SourceLocation DeclarationNameInfo::getEndLocPrivate() const { 505 switch (Name.getNameKind()) { 506 case DeclarationName::Identifier: 507 case DeclarationName::CXXDeductionGuideName: 508 return NameLoc; 509 510 case DeclarationName::CXXOperatorName: 511 return LocInfo.getCXXOperatorNameEndLoc(); 512 513 case DeclarationName::CXXLiteralOperatorName: 514 return LocInfo.getCXXLiteralOperatorNameLoc(); 515 516 case DeclarationName::CXXConstructorName: 517 case DeclarationName::CXXDestructorName: 518 case DeclarationName::CXXConversionFunctionName: 519 if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo()) 520 return TInfo->getTypeLoc().getEndLoc(); 521 else 522 return NameLoc; 523 524 // DNInfo work in progress: FIXME. 525 case DeclarationName::ObjCZeroArgSelector: 526 case DeclarationName::ObjCOneArgSelector: 527 case DeclarationName::ObjCMultiArgSelector: 528 case DeclarationName::CXXUsingDirective: 529 return NameLoc; 530 } 531 llvm_unreachable("Unexpected declaration name kind"); 532 } 533