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