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 if (int Compare = LHSSelector.getNameForSlot(I).compare( 76 RHSSelector.getNameForSlot(I))) 77 return Compare; 78 } 79 80 return compareInt(LN, RN); 81 } 82 83 case DeclarationName::CXXConstructorName: 84 case DeclarationName::CXXDestructorName: 85 case DeclarationName::CXXConversionFunctionName: 86 if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType())) 87 return -1; 88 if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType())) 89 return 1; 90 return 0; 91 92 case DeclarationName::CXXDeductionGuideName: 93 // We never want to compare deduction guide names for templates from 94 // different scopes, so just compare the template-name. 95 return compare(LHS.getCXXDeductionGuideTemplate()->getDeclName(), 96 RHS.getCXXDeductionGuideTemplate()->getDeclName()); 97 98 case DeclarationName::CXXOperatorName: 99 return compareInt(LHS.getCXXOverloadedOperator(), 100 RHS.getCXXOverloadedOperator()); 101 102 case DeclarationName::CXXLiteralOperatorName: 103 return LHS.getCXXLiteralIdentifier()->getName().compare( 104 RHS.getCXXLiteralIdentifier()->getName()); 105 106 case DeclarationName::CXXUsingDirective: 107 return 0; 108 } 109 110 llvm_unreachable("Invalid DeclarationName Kind!"); 111 } 112 113 static void printCXXConstructorDestructorName(QualType ClassType, 114 raw_ostream &OS, 115 PrintingPolicy Policy) { 116 // We know we're printing C++ here. Ensure we print types properly. 117 Policy.adjustForCPlusPlus(); 118 119 if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) { 120 ClassRec->getDecl()->printName(OS, Policy); 121 return; 122 } 123 if (Policy.SuppressTemplateArgsInCXXConstructors) { 124 if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) { 125 InjTy->getDecl()->printName(OS, Policy); 126 return; 127 } 128 } 129 ClassType.print(OS, Policy); 130 } 131 132 void DeclarationName::print(raw_ostream &OS, 133 const PrintingPolicy &Policy) const { 134 switch (getNameKind()) { 135 case DeclarationName::Identifier: 136 if (const IdentifierInfo *II = getAsIdentifierInfo()) { 137 StringRef Name = II->getName(); 138 // If this is a mangled OpenMP variant name we strip off the mangling for 139 // printing. It should not be visible to the user at all. 140 if (II->isMangledOpenMPVariantName()) { 141 std::pair<StringRef, StringRef> NameContextPair = 142 Name.split(getOpenMPVariantManglingSeparatorStr()); 143 OS << NameContextPair.first << "[" 144 << OMPTraitInfo(NameContextPair.second) << "]"; 145 } else { 146 OS << Name; 147 } 148 } 149 return; 150 151 case DeclarationName::ObjCZeroArgSelector: 152 case DeclarationName::ObjCOneArgSelector: 153 case DeclarationName::ObjCMultiArgSelector: 154 getObjCSelector().print(OS); 155 return; 156 157 case DeclarationName::CXXConstructorName: 158 return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy); 159 160 case DeclarationName::CXXDestructorName: 161 OS << '~'; 162 return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy); 163 164 case DeclarationName::CXXDeductionGuideName: 165 OS << "<deduction guide for "; 166 getCXXDeductionGuideTemplate()->getDeclName().print(OS, Policy); 167 OS << '>'; 168 return; 169 170 case DeclarationName::CXXOperatorName: { 171 const char *OpName = getOperatorSpelling(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 Result; 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(const 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 setNamedTypeLoc(nullptr); 390 break; 391 case DeclarationName::CXXOperatorName: 392 setCXXOperatorNameRange(SourceRange()); 393 break; 394 case DeclarationName::CXXLiteralOperatorName: 395 setCXXLiteralOperatorNameLoc(SourceLocation()); 396 break; 397 case DeclarationName::ObjCZeroArgSelector: 398 case DeclarationName::ObjCOneArgSelector: 399 case DeclarationName::ObjCMultiArgSelector: 400 // FIXME: ? 401 break; 402 case DeclarationName::CXXUsingDirective: 403 break; 404 } 405 } 406 407 bool DeclarationNameInfo::containsUnexpandedParameterPack() const { 408 switch (Name.getNameKind()) { 409 case DeclarationName::Identifier: 410 case DeclarationName::ObjCZeroArgSelector: 411 case DeclarationName::ObjCOneArgSelector: 412 case DeclarationName::ObjCMultiArgSelector: 413 case DeclarationName::CXXOperatorName: 414 case DeclarationName::CXXLiteralOperatorName: 415 case DeclarationName::CXXUsingDirective: 416 case DeclarationName::CXXDeductionGuideName: 417 return false; 418 419 case DeclarationName::CXXConstructorName: 420 case DeclarationName::CXXDestructorName: 421 case DeclarationName::CXXConversionFunctionName: 422 if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo()) 423 return TInfo->getType()->containsUnexpandedParameterPack(); 424 425 return Name.getCXXNameType()->containsUnexpandedParameterPack(); 426 } 427 llvm_unreachable("All name kinds handled."); 428 } 429 430 bool DeclarationNameInfo::isInstantiationDependent() const { 431 switch (Name.getNameKind()) { 432 case DeclarationName::Identifier: 433 case DeclarationName::ObjCZeroArgSelector: 434 case DeclarationName::ObjCOneArgSelector: 435 case DeclarationName::ObjCMultiArgSelector: 436 case DeclarationName::CXXOperatorName: 437 case DeclarationName::CXXLiteralOperatorName: 438 case DeclarationName::CXXUsingDirective: 439 case DeclarationName::CXXDeductionGuideName: 440 return false; 441 442 case DeclarationName::CXXConstructorName: 443 case DeclarationName::CXXDestructorName: 444 case DeclarationName::CXXConversionFunctionName: 445 if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo()) 446 return TInfo->getType()->isInstantiationDependentType(); 447 448 return Name.getCXXNameType()->isInstantiationDependentType(); 449 } 450 llvm_unreachable("All name kinds handled."); 451 } 452 453 std::string DeclarationNameInfo::getAsString() const { 454 std::string Result; 455 llvm::raw_string_ostream OS(Result); 456 OS << *this; 457 return Result; 458 } 459 460 raw_ostream &clang::operator<<(raw_ostream &OS, DeclarationNameInfo DNInfo) { 461 LangOptions LO; 462 DNInfo.printName(OS, PrintingPolicy(LangOptions())); 463 return OS; 464 } 465 466 void DeclarationNameInfo::printName(raw_ostream &OS, PrintingPolicy Policy) const { 467 switch (Name.getNameKind()) { 468 case DeclarationName::Identifier: 469 case DeclarationName::ObjCZeroArgSelector: 470 case DeclarationName::ObjCOneArgSelector: 471 case DeclarationName::ObjCMultiArgSelector: 472 case DeclarationName::CXXOperatorName: 473 case DeclarationName::CXXLiteralOperatorName: 474 case DeclarationName::CXXUsingDirective: 475 case DeclarationName::CXXDeductionGuideName: 476 Name.print(OS, Policy); 477 return; 478 479 case DeclarationName::CXXConstructorName: 480 case DeclarationName::CXXDestructorName: 481 case DeclarationName::CXXConversionFunctionName: 482 if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo()) { 483 if (Name.getNameKind() == DeclarationName::CXXDestructorName) 484 OS << '~'; 485 else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName) 486 OS << "operator "; 487 LangOptions LO; 488 Policy.adjustForCPlusPlus(); 489 Policy.SuppressScope = true; 490 OS << TInfo->getType().getAsString(Policy); 491 } else 492 Name.print(OS, Policy); 493 return; 494 } 495 llvm_unreachable("Unexpected declaration name kind"); 496 } 497 498 SourceLocation DeclarationNameInfo::getEndLocPrivate() const { 499 switch (Name.getNameKind()) { 500 case DeclarationName::Identifier: 501 case DeclarationName::CXXDeductionGuideName: 502 return NameLoc; 503 504 case DeclarationName::CXXOperatorName: 505 return LocInfo.getCXXOperatorNameEndLoc(); 506 507 case DeclarationName::CXXLiteralOperatorName: 508 return LocInfo.getCXXLiteralOperatorNameLoc(); 509 510 case DeclarationName::CXXConstructorName: 511 case DeclarationName::CXXDestructorName: 512 case DeclarationName::CXXConversionFunctionName: 513 if (TypeSourceInfo *TInfo = LocInfo.getNamedTypeInfo()) 514 return TInfo->getTypeLoc().getEndLoc(); 515 else 516 return NameLoc; 517 518 // DNInfo work in progress: FIXME. 519 case DeclarationName::ObjCZeroArgSelector: 520 case DeclarationName::ObjCOneArgSelector: 521 case DeclarationName::ObjCMultiArgSelector: 522 case DeclarationName::CXXUsingDirective: 523 return NameLoc; 524 } 525 llvm_unreachable("Unexpected declaration name kind"); 526 } 527