1 //===- ExtractAPI/DeclarationFragments.cpp ----------------------*- C++ -*-===// 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 /// \file 10 /// This file implements Declaration Fragments related classes. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/ExtractAPI/DeclarationFragments.h" 15 #include "clang/AST/ASTFwd.h" 16 #include "clang/AST/Decl.h" 17 #include "clang/AST/DeclCXX.h" 18 #include "clang/AST/TemplateBase.h" 19 #include "clang/AST/TemplateName.h" 20 #include "clang/AST/Type.h" 21 #include "clang/AST/TypeLoc.h" 22 #include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h" 23 #include "clang/Index/USRGeneration.h" 24 #include "llvm/ADT/StringSwitch.h" 25 #include "llvm/Support/ErrorHandling.h" 26 #include "llvm/Support/raw_ostream.h" 27 #include <optional> 28 29 using namespace clang::extractapi; 30 using namespace llvm; 31 32 namespace { 33 34 void findTypeLocForBlockDecl(const clang::TypeSourceInfo *TSInfo, 35 clang::FunctionTypeLoc &Block, 36 clang::FunctionProtoTypeLoc &BlockProto) { 37 if (!TSInfo) 38 return; 39 40 clang::TypeLoc TL = TSInfo->getTypeLoc().getUnqualifiedLoc(); 41 while (true) { 42 // Look through qualified types 43 if (auto QualifiedTL = TL.getAs<clang::QualifiedTypeLoc>()) { 44 TL = QualifiedTL.getUnqualifiedLoc(); 45 continue; 46 } 47 48 if (auto AttrTL = TL.getAs<clang::AttributedTypeLoc>()) { 49 TL = AttrTL.getModifiedLoc(); 50 continue; 51 } 52 53 // Try to get the function prototype behind the block pointer type, 54 // then we're done. 55 if (auto BlockPtr = TL.getAs<clang::BlockPointerTypeLoc>()) { 56 TL = BlockPtr.getPointeeLoc().IgnoreParens(); 57 Block = TL.getAs<clang::FunctionTypeLoc>(); 58 BlockProto = TL.getAs<clang::FunctionProtoTypeLoc>(); 59 } 60 break; 61 } 62 } 63 64 } // namespace 65 66 DeclarationFragments & 67 DeclarationFragments::appendUnduplicatedTextCharacter(char Character) { 68 if (!Fragments.empty()) { 69 Fragment &Last = Fragments.back(); 70 if (Last.Kind == FragmentKind::Text) { 71 // Merge the extra space into the last fragment if the last fragment is 72 // also text. 73 if (Last.Spelling.back() != Character) { // avoid duplicates at end 74 Last.Spelling.push_back(Character); 75 } 76 } else { 77 append("", FragmentKind::Text); 78 Fragments.back().Spelling.push_back(Character); 79 } 80 } 81 82 return *this; 83 } 84 85 DeclarationFragments &DeclarationFragments::appendSpace() { 86 return appendUnduplicatedTextCharacter(' '); 87 } 88 89 DeclarationFragments &DeclarationFragments::appendSemicolon() { 90 return appendUnduplicatedTextCharacter(';'); 91 } 92 93 DeclarationFragments &DeclarationFragments::removeTrailingSemicolon() { 94 if (Fragments.empty()) 95 return *this; 96 97 Fragment &Last = Fragments.back(); 98 if (Last.Kind == FragmentKind::Text && Last.Spelling.back() == ';') 99 Last.Spelling.pop_back(); 100 101 return *this; 102 } 103 104 StringRef DeclarationFragments::getFragmentKindString( 105 DeclarationFragments::FragmentKind Kind) { 106 switch (Kind) { 107 case DeclarationFragments::FragmentKind::None: 108 return "none"; 109 case DeclarationFragments::FragmentKind::Keyword: 110 return "keyword"; 111 case DeclarationFragments::FragmentKind::Attribute: 112 return "attribute"; 113 case DeclarationFragments::FragmentKind::NumberLiteral: 114 return "number"; 115 case DeclarationFragments::FragmentKind::StringLiteral: 116 return "string"; 117 case DeclarationFragments::FragmentKind::Identifier: 118 return "identifier"; 119 case DeclarationFragments::FragmentKind::TypeIdentifier: 120 return "typeIdentifier"; 121 case DeclarationFragments::FragmentKind::GenericParameter: 122 return "genericParameter"; 123 case DeclarationFragments::FragmentKind::ExternalParam: 124 return "externalParam"; 125 case DeclarationFragments::FragmentKind::InternalParam: 126 return "internalParam"; 127 case DeclarationFragments::FragmentKind::Text: 128 return "text"; 129 } 130 131 llvm_unreachable("Unhandled FragmentKind"); 132 } 133 134 DeclarationFragments::FragmentKind 135 DeclarationFragments::parseFragmentKindFromString(StringRef S) { 136 return llvm::StringSwitch<FragmentKind>(S) 137 .Case("keyword", DeclarationFragments::FragmentKind::Keyword) 138 .Case("attribute", DeclarationFragments::FragmentKind::Attribute) 139 .Case("number", DeclarationFragments::FragmentKind::NumberLiteral) 140 .Case("string", DeclarationFragments::FragmentKind::StringLiteral) 141 .Case("identifier", DeclarationFragments::FragmentKind::Identifier) 142 .Case("typeIdentifier", 143 DeclarationFragments::FragmentKind::TypeIdentifier) 144 .Case("genericParameter", 145 DeclarationFragments::FragmentKind::GenericParameter) 146 .Case("internalParam", DeclarationFragments::FragmentKind::InternalParam) 147 .Case("externalParam", DeclarationFragments::FragmentKind::ExternalParam) 148 .Case("text", DeclarationFragments::FragmentKind::Text) 149 .Default(DeclarationFragments::FragmentKind::None); 150 } 151 152 DeclarationFragments DeclarationFragments::getExceptionSpecificationString( 153 ExceptionSpecificationType ExceptionSpec) { 154 DeclarationFragments Fragments; 155 switch (ExceptionSpec) { 156 case ExceptionSpecificationType::EST_None: 157 return Fragments; 158 case ExceptionSpecificationType::EST_DynamicNone: 159 return Fragments.append(" ", DeclarationFragments::FragmentKind::Text) 160 .append("throw", DeclarationFragments::FragmentKind::Keyword) 161 .append("(", DeclarationFragments::FragmentKind::Text) 162 .append(")", DeclarationFragments::FragmentKind::Text); 163 case ExceptionSpecificationType::EST_Dynamic: 164 // FIXME: throw(int), get types of inner expression 165 return Fragments; 166 case ExceptionSpecificationType::EST_BasicNoexcept: 167 return Fragments.append(" ", DeclarationFragments::FragmentKind::Text) 168 .append("noexcept", DeclarationFragments::FragmentKind::Keyword); 169 case ExceptionSpecificationType::EST_DependentNoexcept: 170 // FIXME: throw(conditional-expression), get expression 171 break; 172 case ExceptionSpecificationType::EST_NoexceptFalse: 173 return Fragments.append(" ", DeclarationFragments::FragmentKind::Text) 174 .append("noexcept", DeclarationFragments::FragmentKind::Keyword) 175 .append("(", DeclarationFragments::FragmentKind::Text) 176 .append("false", DeclarationFragments::FragmentKind::Keyword) 177 .append(")", DeclarationFragments::FragmentKind::Text); 178 case ExceptionSpecificationType::EST_NoexceptTrue: 179 return Fragments.append(" ", DeclarationFragments::FragmentKind::Text) 180 .append("noexcept", DeclarationFragments::FragmentKind::Keyword) 181 .append("(", DeclarationFragments::FragmentKind::Text) 182 .append("true", DeclarationFragments::FragmentKind::Keyword) 183 .append(")", DeclarationFragments::FragmentKind::Text); 184 default: 185 return Fragments; 186 } 187 188 llvm_unreachable("Unhandled exception specification"); 189 } 190 191 DeclarationFragments 192 DeclarationFragments::getStructureTypeFragment(const RecordDecl *Record) { 193 DeclarationFragments Fragments; 194 if (Record->isStruct()) 195 Fragments.append("struct", DeclarationFragments::FragmentKind::Keyword); 196 else if (Record->isUnion()) 197 Fragments.append("union", DeclarationFragments::FragmentKind::Keyword); 198 else 199 Fragments.append("class", DeclarationFragments::FragmentKind::Keyword); 200 201 return Fragments; 202 } 203 204 // NNS stores C++ nested name specifiers, which are prefixes to qualified names. 205 // Build declaration fragments for NNS recursively so that we have the USR for 206 // every part in a qualified name, and also leaves the actual underlying type 207 // cleaner for its own fragment. 208 DeclarationFragments 209 DeclarationFragmentsBuilder::getFragmentsForNNS(const NestedNameSpecifier *NNS, 210 ASTContext &Context, 211 DeclarationFragments &After) { 212 DeclarationFragments Fragments; 213 if (NNS->getPrefix()) 214 Fragments.append(getFragmentsForNNS(NNS->getPrefix(), Context, After)); 215 216 switch (NNS->getKind()) { 217 case NestedNameSpecifier::Identifier: 218 Fragments.append(NNS->getAsIdentifier()->getName(), 219 DeclarationFragments::FragmentKind::Identifier); 220 break; 221 222 case NestedNameSpecifier::Namespace: { 223 const NamespaceDecl *NS = NNS->getAsNamespace(); 224 if (NS->isAnonymousNamespace()) 225 return Fragments; 226 SmallString<128> USR; 227 index::generateUSRForDecl(NS, USR); 228 Fragments.append(NS->getName(), 229 DeclarationFragments::FragmentKind::Identifier, USR, NS); 230 break; 231 } 232 233 case NestedNameSpecifier::NamespaceAlias: { 234 const NamespaceAliasDecl *Alias = NNS->getAsNamespaceAlias(); 235 SmallString<128> USR; 236 index::generateUSRForDecl(Alias, USR); 237 Fragments.append(Alias->getName(), 238 DeclarationFragments::FragmentKind::Identifier, USR, 239 Alias); 240 break; 241 } 242 243 case NestedNameSpecifier::Global: 244 // The global specifier `::` at the beginning. No stored value. 245 break; 246 247 case NestedNameSpecifier::Super: 248 // Microsoft's `__super` specifier. 249 Fragments.append("__super", DeclarationFragments::FragmentKind::Keyword); 250 break; 251 252 case NestedNameSpecifier::TypeSpec: { 253 const Type *T = NNS->getAsType(); 254 // FIXME: Handle C++ template specialization type 255 Fragments.append(getFragmentsForType(T, Context, After)); 256 break; 257 } 258 } 259 260 // Add the separator text `::` for this segment. 261 return Fragments.append("::", DeclarationFragments::FragmentKind::Text); 262 } 263 264 // Recursively build the declaration fragments for an underlying `Type` with 265 // qualifiers removed. 266 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType( 267 const Type *T, ASTContext &Context, DeclarationFragments &After) { 268 assert(T && "invalid type"); 269 270 DeclarationFragments Fragments; 271 272 if (const MacroQualifiedType *MQT = dyn_cast<MacroQualifiedType>(T)) { 273 Fragments.append( 274 getFragmentsForType(MQT->getUnderlyingType(), Context, After)); 275 return Fragments; 276 } 277 278 if (const AttributedType *AT = dyn_cast<AttributedType>(T)) { 279 // FIXME: Serialize Attributes correctly 280 Fragments.append( 281 getFragmentsForType(AT->getModifiedType(), Context, After)); 282 return Fragments; 283 } 284 285 // An ElaboratedType is a sugar for types that are referred to using an 286 // elaborated keyword, e.g., `struct S`, `enum E`, or (in C++) via a 287 // qualified name, e.g., `N::M::type`, or both. 288 if (const ElaboratedType *ET = dyn_cast<ElaboratedType>(T)) { 289 ElaboratedTypeKeyword Keyword = ET->getKeyword(); 290 if (Keyword != ElaboratedTypeKeyword::None) { 291 Fragments 292 .append(ElaboratedType::getKeywordName(Keyword), 293 DeclarationFragments::FragmentKind::Keyword) 294 .appendSpace(); 295 } 296 297 if (const NestedNameSpecifier *NNS = ET->getQualifier()) 298 Fragments.append(getFragmentsForNNS(NNS, Context, After)); 299 300 // After handling the elaborated keyword or qualified name, build 301 // declaration fragments for the desugared underlying type. 302 return Fragments.append(getFragmentsForType(ET->desugar(), Context, After)); 303 } 304 305 // If the type is a typedefed type, get the underlying TypedefNameDecl for a 306 // direct reference to the typedef instead of the wrapped type. 307 308 // 'id' type is a typedef for an ObjCObjectPointerType 309 // we treat it as a typedef 310 if (const TypedefType *TypedefTy = dyn_cast<TypedefType>(T)) { 311 const TypedefNameDecl *Decl = TypedefTy->getDecl(); 312 TypedefUnderlyingTypeResolver TypedefResolver(Context); 313 std::string USR = TypedefResolver.getUSRForType(QualType(T, 0)); 314 315 if (T->isObjCIdType()) { 316 return Fragments.append(Decl->getName(), 317 DeclarationFragments::FragmentKind::Keyword); 318 } 319 320 return Fragments.append( 321 Decl->getName(), DeclarationFragments::FragmentKind::TypeIdentifier, 322 USR, TypedefResolver.getUnderlyingTypeDecl(QualType(T, 0))); 323 } 324 325 // Declaration fragments of a pointer type is the declaration fragments of 326 // the pointee type followed by a `*`, 327 if (T->isPointerType() && !T->isFunctionPointerType()) { 328 QualType PointeeT = T->getPointeeType(); 329 Fragments.append(getFragmentsForType(PointeeT, Context, After)); 330 // If the pointee is itself a pointer, we do not want to insert a space 331 // before the `*` as the preceding character in the type name is a `*`. 332 if (!PointeeT->isAnyPointerType()) 333 Fragments.appendSpace(); 334 return Fragments.append("*", DeclarationFragments::FragmentKind::Text); 335 } 336 337 // For Objective-C `id` and `Class` pointers 338 // we do not spell out the `*`. 339 if (T->isObjCObjectPointerType() && 340 !T->getAs<ObjCObjectPointerType>()->isObjCIdOrClassType()) { 341 342 Fragments.append(getFragmentsForType(T->getPointeeType(), Context, After)); 343 344 // id<protocol> is an qualified id type 345 // id<protocol>* is not an qualified id type 346 if (!T->getAs<ObjCObjectPointerType>()->isObjCQualifiedIdType()) { 347 Fragments.append(" *", DeclarationFragments::FragmentKind::Text); 348 } 349 350 return Fragments; 351 } 352 353 // Declaration fragments of a lvalue reference type is the declaration 354 // fragments of the underlying type followed by a `&`. 355 if (const LValueReferenceType *LRT = dyn_cast<LValueReferenceType>(T)) 356 return Fragments 357 .append( 358 getFragmentsForType(LRT->getPointeeTypeAsWritten(), Context, After)) 359 .append(" &", DeclarationFragments::FragmentKind::Text); 360 361 // Declaration fragments of a rvalue reference type is the declaration 362 // fragments of the underlying type followed by a `&&`. 363 if (const RValueReferenceType *RRT = dyn_cast<RValueReferenceType>(T)) 364 return Fragments 365 .append( 366 getFragmentsForType(RRT->getPointeeTypeAsWritten(), Context, After)) 367 .append(" &&", DeclarationFragments::FragmentKind::Text); 368 369 // Declaration fragments of an array-typed variable have two parts: 370 // 1. the element type of the array that appears before the variable name; 371 // 2. array brackets `[(0-9)?]` that appear after the variable name. 372 if (const ArrayType *AT = T->getAsArrayTypeUnsafe()) { 373 // Build the "after" part first because the inner element type might also 374 // be an array-type. For example `int matrix[3][4]` which has a type of 375 // "(array 3 of (array 4 of ints))." 376 // Push the array size part first to make sure they are in the right order. 377 After.append("[", DeclarationFragments::FragmentKind::Text); 378 379 switch (AT->getSizeModifier()) { 380 case ArraySizeModifier::Normal: 381 break; 382 case ArraySizeModifier::Static: 383 Fragments.append("static", DeclarationFragments::FragmentKind::Keyword); 384 break; 385 case ArraySizeModifier::Star: 386 Fragments.append("*", DeclarationFragments::FragmentKind::Text); 387 break; 388 } 389 390 if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) { 391 // FIXME: right now this would evaluate any expressions/macros written in 392 // the original source to concrete values. For example 393 // `int nums[MAX]` -> `int nums[100]` 394 // `char *str[5 + 1]` -> `char *str[6]` 395 SmallString<128> Size; 396 CAT->getSize().toStringUnsigned(Size); 397 After.append(Size, DeclarationFragments::FragmentKind::NumberLiteral); 398 } 399 400 After.append("]", DeclarationFragments::FragmentKind::Text); 401 402 return Fragments.append( 403 getFragmentsForType(AT->getElementType(), Context, After)); 404 } 405 406 if (const TemplateSpecializationType *TemplSpecTy = 407 dyn_cast<TemplateSpecializationType>(T)) { 408 const auto TemplName = TemplSpecTy->getTemplateName(); 409 std::string Str; 410 raw_string_ostream Stream(Str); 411 TemplName.print(Stream, Context.getPrintingPolicy(), 412 TemplateName::Qualified::AsWritten); 413 SmallString<64> USR(""); 414 if (const auto *TemplDecl = TemplName.getAsTemplateDecl()) 415 index::generateUSRForDecl(TemplDecl, USR); 416 417 return Fragments 418 .append(Str, DeclarationFragments::FragmentKind::TypeIdentifier, USR) 419 .append("<", DeclarationFragments::FragmentKind::Text) 420 .append(getFragmentsForTemplateArguments( 421 TemplSpecTy->template_arguments(), Context, std::nullopt)) 422 .append(">", DeclarationFragments::FragmentKind::Text); 423 } 424 425 // Everything we care about has been handled now, reduce to the canonical 426 // unqualified base type. 427 QualType Base = T->getCanonicalTypeUnqualified(); 428 429 // If the base type is a TagType (struct/interface/union/class/enum), let's 430 // get the underlying Decl for better names and USRs. 431 if (const TagType *TagTy = dyn_cast<TagType>(Base)) { 432 const TagDecl *Decl = TagTy->getDecl(); 433 // Anonymous decl, skip this fragment. 434 if (Decl->getName().empty()) 435 return Fragments.append("{ ... }", 436 DeclarationFragments::FragmentKind::Text); 437 SmallString<128> TagUSR; 438 clang::index::generateUSRForDecl(Decl, TagUSR); 439 return Fragments.append(Decl->getName(), 440 DeclarationFragments::FragmentKind::TypeIdentifier, 441 TagUSR, Decl); 442 } 443 444 // If the base type is an ObjCInterfaceType, use the underlying 445 // ObjCInterfaceDecl for the true USR. 446 if (const auto *ObjCIT = dyn_cast<ObjCInterfaceType>(Base)) { 447 const auto *Decl = ObjCIT->getDecl(); 448 SmallString<128> USR; 449 index::generateUSRForDecl(Decl, USR); 450 return Fragments.append(Decl->getName(), 451 DeclarationFragments::FragmentKind::TypeIdentifier, 452 USR, Decl); 453 } 454 455 // Default fragment builder for other kinds of types (BuiltinType etc.) 456 SmallString<128> USR; 457 clang::index::generateUSRForType(Base, Context, USR); 458 Fragments.append(Base.getAsString(), 459 DeclarationFragments::FragmentKind::TypeIdentifier, USR); 460 461 return Fragments; 462 } 463 464 DeclarationFragments 465 DeclarationFragmentsBuilder::getFragmentsForQualifiers(const Qualifiers Quals) { 466 DeclarationFragments Fragments; 467 if (Quals.hasConst()) 468 Fragments.append("const", DeclarationFragments::FragmentKind::Keyword); 469 if (Quals.hasVolatile()) 470 Fragments.append("volatile", DeclarationFragments::FragmentKind::Keyword); 471 if (Quals.hasRestrict()) 472 Fragments.append("restrict", DeclarationFragments::FragmentKind::Keyword); 473 474 return Fragments; 475 } 476 477 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType( 478 const QualType QT, ASTContext &Context, DeclarationFragments &After) { 479 assert(!QT.isNull() && "invalid type"); 480 481 if (const ParenType *PT = dyn_cast<ParenType>(QT)) { 482 After.append(")", DeclarationFragments::FragmentKind::Text); 483 return getFragmentsForType(PT->getInnerType(), Context, After) 484 .append("(", DeclarationFragments::FragmentKind::Text); 485 } 486 487 const SplitQualType SQT = QT.split(); 488 DeclarationFragments QualsFragments = getFragmentsForQualifiers(SQT.Quals), 489 TypeFragments = 490 getFragmentsForType(SQT.Ty, Context, After); 491 if (QT.getAsString() == "_Bool") 492 TypeFragments.replace("bool", 0); 493 494 if (QualsFragments.getFragments().empty()) 495 return TypeFragments; 496 497 // Use east qualifier for pointer types 498 // For example: 499 // ``` 500 // int * const 501 // ^---- ^---- 502 // type qualifier 503 // ^----------------- 504 // const pointer to int 505 // ``` 506 // should not be reconstructed as 507 // ``` 508 // const int * 509 // ^---- ^-- 510 // qualifier type 511 // ^---------------- ^ 512 // pointer to const int 513 // ``` 514 if (SQT.Ty->isAnyPointerType()) 515 return TypeFragments.appendSpace().append(std::move(QualsFragments)); 516 517 return QualsFragments.appendSpace().append(std::move(TypeFragments)); 518 } 519 520 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForNamespace( 521 const NamespaceDecl *Decl) { 522 DeclarationFragments Fragments; 523 Fragments.append("namespace", DeclarationFragments::FragmentKind::Keyword); 524 if (!Decl->isAnonymousNamespace()) 525 Fragments.appendSpace().append( 526 Decl->getName(), DeclarationFragments::FragmentKind::Identifier); 527 return Fragments.appendSemicolon(); 528 } 529 530 DeclarationFragments 531 DeclarationFragmentsBuilder::getFragmentsForVar(const VarDecl *Var) { 532 DeclarationFragments Fragments; 533 if (Var->isConstexpr()) 534 Fragments.append("constexpr", DeclarationFragments::FragmentKind::Keyword) 535 .appendSpace(); 536 537 StorageClass SC = Var->getStorageClass(); 538 if (SC != SC_None) 539 Fragments 540 .append(VarDecl::getStorageClassSpecifierString(SC), 541 DeclarationFragments::FragmentKind::Keyword) 542 .appendSpace(); 543 544 // Capture potential fragments that needs to be placed after the variable name 545 // ``` 546 // int nums[5]; 547 // char (*ptr_to_array)[6]; 548 // ``` 549 DeclarationFragments After; 550 FunctionTypeLoc BlockLoc; 551 FunctionProtoTypeLoc BlockProtoLoc; 552 findTypeLocForBlockDecl(Var->getTypeSourceInfo(), BlockLoc, BlockProtoLoc); 553 554 if (!BlockLoc) { 555 QualType T = Var->getTypeSourceInfo() 556 ? Var->getTypeSourceInfo()->getType() 557 : Var->getASTContext().getUnqualifiedObjCPointerType( 558 Var->getType()); 559 560 Fragments.append(getFragmentsForType(T, Var->getASTContext(), After)) 561 .appendSpace(); 562 } else { 563 Fragments.append(getFragmentsForBlock(Var, BlockLoc, BlockProtoLoc, After)); 564 } 565 566 return Fragments 567 .append(Var->getName(), DeclarationFragments::FragmentKind::Identifier) 568 .append(std::move(After)) 569 .appendSemicolon(); 570 } 571 572 DeclarationFragments 573 DeclarationFragmentsBuilder::getFragmentsForVarTemplate(const VarDecl *Var) { 574 DeclarationFragments Fragments; 575 if (Var->isConstexpr()) 576 Fragments.append("constexpr", DeclarationFragments::FragmentKind::Keyword) 577 .appendSpace(); 578 QualType T = 579 Var->getTypeSourceInfo() 580 ? Var->getTypeSourceInfo()->getType() 581 : Var->getASTContext().getUnqualifiedObjCPointerType(Var->getType()); 582 583 // Might be a member, so might be static. 584 if (Var->isStaticDataMember()) 585 Fragments.append("static", DeclarationFragments::FragmentKind::Keyword) 586 .appendSpace(); 587 588 DeclarationFragments After; 589 DeclarationFragments ArgumentFragment = 590 getFragmentsForType(T, Var->getASTContext(), After); 591 if (StringRef(ArgumentFragment.begin()->Spelling) 592 .starts_with("type-parameter")) { 593 std::string ProperArgName = T.getAsString(); 594 ArgumentFragment.begin()->Spelling.swap(ProperArgName); 595 } 596 Fragments.append(std::move(ArgumentFragment)) 597 .appendSpace() 598 .append(Var->getName(), DeclarationFragments::FragmentKind::Identifier) 599 .appendSemicolon(); 600 return Fragments; 601 } 602 603 DeclarationFragments 604 DeclarationFragmentsBuilder::getFragmentsForParam(const ParmVarDecl *Param) { 605 DeclarationFragments Fragments, After; 606 607 auto *TSInfo = Param->getTypeSourceInfo(); 608 609 QualType T = TSInfo ? TSInfo->getType() 610 : Param->getASTContext().getUnqualifiedObjCPointerType( 611 Param->getType()); 612 613 FunctionTypeLoc BlockLoc; 614 FunctionProtoTypeLoc BlockProtoLoc; 615 findTypeLocForBlockDecl(TSInfo, BlockLoc, BlockProtoLoc); 616 617 DeclarationFragments TypeFragments; 618 if (BlockLoc) 619 TypeFragments.append( 620 getFragmentsForBlock(Param, BlockLoc, BlockProtoLoc, After)); 621 else 622 TypeFragments.append(getFragmentsForType(T, Param->getASTContext(), After)); 623 624 if (StringRef(TypeFragments.begin()->Spelling) 625 .starts_with("type-parameter")) { 626 std::string ProperArgName = Param->getOriginalType().getAsString(); 627 TypeFragments.begin()->Spelling.swap(ProperArgName); 628 } 629 630 if (Param->isObjCMethodParameter()) { 631 Fragments.append("(", DeclarationFragments::FragmentKind::Text) 632 .append(std::move(TypeFragments)) 633 .append(std::move(After)) 634 .append(") ", DeclarationFragments::FragmentKind::Text) 635 .append(Param->getName(), 636 DeclarationFragments::FragmentKind::InternalParam); 637 } else { 638 Fragments.append(std::move(TypeFragments)); 639 // If the type is a type alias, append the space 640 // even if the underlying type is a pointer type. 641 if (T->isTypedefNameType() || 642 (!T->isAnyPointerType() && !T->isBlockPointerType())) 643 Fragments.appendSpace(); 644 Fragments 645 .append(Param->getName(), 646 DeclarationFragments::FragmentKind::InternalParam) 647 .append(std::move(After)); 648 } 649 return Fragments; 650 } 651 652 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForBlock( 653 const NamedDecl *BlockDecl, FunctionTypeLoc &Block, 654 FunctionProtoTypeLoc &BlockProto, DeclarationFragments &After) { 655 DeclarationFragments Fragments; 656 657 DeclarationFragments RetTyAfter; 658 auto ReturnValueFragment = getFragmentsForType( 659 Block.getTypePtr()->getReturnType(), BlockDecl->getASTContext(), After); 660 661 Fragments.append(std::move(ReturnValueFragment)) 662 .append(std::move(RetTyAfter)) 663 .appendSpace() 664 .append("(^", DeclarationFragments::FragmentKind::Text); 665 666 After.append(")", DeclarationFragments::FragmentKind::Text); 667 unsigned NumParams = Block.getNumParams(); 668 669 if (!BlockProto || NumParams == 0) { 670 if (BlockProto && BlockProto.getTypePtr()->isVariadic()) 671 After.append("(...)", DeclarationFragments::FragmentKind::Text); 672 else 673 After.append("()", DeclarationFragments::FragmentKind::Text); 674 } else { 675 After.append("(", DeclarationFragments::FragmentKind::Text); 676 for (unsigned I = 0; I != NumParams; ++I) { 677 if (I) 678 After.append(", ", DeclarationFragments::FragmentKind::Text); 679 After.append(getFragmentsForParam(Block.getParam(I))); 680 if (I == NumParams - 1 && BlockProto.getTypePtr()->isVariadic()) 681 After.append(", ...", DeclarationFragments::FragmentKind::Text); 682 } 683 After.append(")", DeclarationFragments::FragmentKind::Text); 684 } 685 686 return Fragments; 687 } 688 689 DeclarationFragments 690 DeclarationFragmentsBuilder::getFragmentsForFunction(const FunctionDecl *Func) { 691 DeclarationFragments Fragments; 692 switch (Func->getStorageClass()) { 693 case SC_None: 694 case SC_PrivateExtern: 695 break; 696 case SC_Extern: 697 Fragments.append("extern", DeclarationFragments::FragmentKind::Keyword) 698 .appendSpace(); 699 break; 700 case SC_Static: 701 Fragments.append("static", DeclarationFragments::FragmentKind::Keyword) 702 .appendSpace(); 703 break; 704 case SC_Auto: 705 case SC_Register: 706 llvm_unreachable("invalid for functions"); 707 } 708 if (Func->isConsteval()) // if consteval, it is also constexpr 709 Fragments.append("consteval", DeclarationFragments::FragmentKind::Keyword) 710 .appendSpace(); 711 else if (Func->isConstexpr()) 712 Fragments.append("constexpr", DeclarationFragments::FragmentKind::Keyword) 713 .appendSpace(); 714 715 // FIXME: Is `after` actually needed here? 716 DeclarationFragments After; 717 QualType ReturnType = Func->getReturnType(); 718 auto ReturnValueFragment = 719 getFragmentsForType(ReturnType, Func->getASTContext(), After); 720 if (StringRef(ReturnValueFragment.begin()->Spelling) 721 .starts_with("type-parameter")) { 722 std::string ProperArgName = ReturnType.getAsString(); 723 ReturnValueFragment.begin()->Spelling.swap(ProperArgName); 724 } 725 726 Fragments.append(std::move(ReturnValueFragment)); 727 if (!ReturnType->isAnyPointerType()) 728 Fragments.appendSpace(); 729 Fragments.append(Func->getNameAsString(), 730 DeclarationFragments::FragmentKind::Identifier); 731 732 if (Func->getTemplateSpecializationInfo()) { 733 Fragments.append("<", DeclarationFragments::FragmentKind::Text); 734 735 for (unsigned i = 0, end = Func->getNumParams(); i != end; ++i) { 736 if (i) 737 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 738 Fragments.append( 739 getFragmentsForType(Func->getParamDecl(i)->getType(), 740 Func->getParamDecl(i)->getASTContext(), After)); 741 } 742 Fragments.append(">", DeclarationFragments::FragmentKind::Text); 743 } 744 Fragments.append(std::move(After)); 745 746 Fragments.append("(", DeclarationFragments::FragmentKind::Text); 747 unsigned NumParams = Func->getNumParams(); 748 for (unsigned i = 0; i != NumParams; ++i) { 749 if (i) 750 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 751 Fragments.append(getFragmentsForParam(Func->getParamDecl(i))); 752 } 753 754 if (Func->isVariadic()) { 755 if (NumParams > 0) 756 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 757 Fragments.append("...", DeclarationFragments::FragmentKind::Text); 758 } 759 Fragments.append(")", DeclarationFragments::FragmentKind::Text); 760 761 Fragments.append(DeclarationFragments::getExceptionSpecificationString( 762 Func->getExceptionSpecType())); 763 764 return Fragments.appendSemicolon(); 765 } 766 767 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForEnumConstant( 768 const EnumConstantDecl *EnumConstDecl) { 769 DeclarationFragments Fragments; 770 return Fragments.append(EnumConstDecl->getName(), 771 DeclarationFragments::FragmentKind::Identifier); 772 } 773 774 DeclarationFragments 775 DeclarationFragmentsBuilder::getFragmentsForEnum(const EnumDecl *EnumDecl) { 776 if (const auto *TypedefNameDecl = EnumDecl->getTypedefNameForAnonDecl()) 777 return getFragmentsForTypedef(TypedefNameDecl); 778 779 DeclarationFragments Fragments, After; 780 Fragments.append("enum", DeclarationFragments::FragmentKind::Keyword); 781 782 if (!EnumDecl->getName().empty()) 783 Fragments.appendSpace().append( 784 EnumDecl->getName(), DeclarationFragments::FragmentKind::Identifier); 785 786 QualType IntegerType = EnumDecl->getIntegerType(); 787 if (!IntegerType.isNull()) 788 Fragments.appendSpace() 789 .append(": ", DeclarationFragments::FragmentKind::Text) 790 .append( 791 getFragmentsForType(IntegerType, EnumDecl->getASTContext(), After)) 792 .append(std::move(After)); 793 794 if (EnumDecl->getName().empty()) 795 Fragments.appendSpace().append("{ ... }", 796 DeclarationFragments::FragmentKind::Text); 797 798 return Fragments.appendSemicolon(); 799 } 800 801 DeclarationFragments 802 DeclarationFragmentsBuilder::getFragmentsForField(const FieldDecl *Field) { 803 DeclarationFragments After; 804 DeclarationFragments Fragments; 805 if (Field->isMutable()) 806 Fragments.append("mutable", DeclarationFragments::FragmentKind::Keyword) 807 .appendSpace(); 808 return Fragments 809 .append( 810 getFragmentsForType(Field->getType(), Field->getASTContext(), After)) 811 .appendSpace() 812 .append(Field->getName(), DeclarationFragments::FragmentKind::Identifier) 813 .append(std::move(After)) 814 .appendSemicolon(); 815 } 816 817 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForRecordDecl( 818 const RecordDecl *Record) { 819 if (const auto *TypedefNameDecl = Record->getTypedefNameForAnonDecl()) 820 return getFragmentsForTypedef(TypedefNameDecl); 821 822 DeclarationFragments Fragments; 823 if (Record->isUnion()) 824 Fragments.append("union", DeclarationFragments::FragmentKind::Keyword); 825 else 826 Fragments.append("struct", DeclarationFragments::FragmentKind::Keyword); 827 828 Fragments.appendSpace(); 829 if (!Record->getName().empty()) 830 Fragments.append(Record->getName(), 831 DeclarationFragments::FragmentKind::Identifier); 832 else 833 Fragments.append("{ ... }", DeclarationFragments::FragmentKind::Text); 834 835 return Fragments.appendSemicolon(); 836 } 837 838 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForCXXClass( 839 const CXXRecordDecl *Record) { 840 if (const auto *TypedefNameDecl = Record->getTypedefNameForAnonDecl()) 841 return getFragmentsForTypedef(TypedefNameDecl); 842 843 DeclarationFragments Fragments; 844 Fragments.append(DeclarationFragments::getStructureTypeFragment(Record)); 845 846 if (!Record->getName().empty()) 847 Fragments.appendSpace().append( 848 Record->getName(), DeclarationFragments::FragmentKind::Identifier); 849 850 return Fragments.appendSemicolon(); 851 } 852 853 DeclarationFragments 854 DeclarationFragmentsBuilder::getFragmentsForSpecialCXXMethod( 855 const CXXMethodDecl *Method) { 856 DeclarationFragments Fragments; 857 std::string Name; 858 if (const auto *Constructor = dyn_cast<CXXConstructorDecl>(Method)) { 859 Name = Method->getNameAsString(); 860 if (Constructor->isExplicit()) 861 Fragments.append("explicit", DeclarationFragments::FragmentKind::Keyword) 862 .appendSpace(); 863 } else if (isa<CXXDestructorDecl>(Method)) 864 Name = Method->getNameAsString(); 865 866 DeclarationFragments After; 867 Fragments.append(Name, DeclarationFragments::FragmentKind::Identifier) 868 .append(std::move(After)); 869 Fragments.append("(", DeclarationFragments::FragmentKind::Text); 870 for (unsigned i = 0, end = Method->getNumParams(); i != end; ++i) { 871 if (i) 872 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 873 Fragments.append(getFragmentsForParam(Method->getParamDecl(i))); 874 } 875 Fragments.append(")", DeclarationFragments::FragmentKind::Text); 876 877 Fragments.append(DeclarationFragments::getExceptionSpecificationString( 878 Method->getExceptionSpecType())); 879 880 return Fragments.appendSemicolon(); 881 } 882 883 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForCXXMethod( 884 const CXXMethodDecl *Method) { 885 DeclarationFragments Fragments; 886 StringRef Name = Method->getName(); 887 if (Method->isStatic()) 888 Fragments.append("static", DeclarationFragments::FragmentKind::Keyword) 889 .appendSpace(); 890 if (Method->isConstexpr()) 891 Fragments.append("constexpr", DeclarationFragments::FragmentKind::Keyword) 892 .appendSpace(); 893 if (Method->isVolatile()) 894 Fragments.append("volatile", DeclarationFragments::FragmentKind::Keyword) 895 .appendSpace(); 896 if (Method->isVirtual()) 897 Fragments.append("virtual", DeclarationFragments::FragmentKind::Keyword) 898 .appendSpace(); 899 900 // Build return type 901 DeclarationFragments After; 902 Fragments 903 .append(getFragmentsForType(Method->getReturnType(), 904 Method->getASTContext(), After)) 905 .appendSpace() 906 .append(Name, DeclarationFragments::FragmentKind::Identifier) 907 .append(std::move(After)); 908 Fragments.append("(", DeclarationFragments::FragmentKind::Text); 909 for (unsigned i = 0, end = Method->getNumParams(); i != end; ++i) { 910 if (i) 911 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 912 Fragments.append(getFragmentsForParam(Method->getParamDecl(i))); 913 } 914 Fragments.append(")", DeclarationFragments::FragmentKind::Text); 915 916 if (Method->isConst()) 917 Fragments.appendSpace().append("const", 918 DeclarationFragments::FragmentKind::Keyword); 919 920 Fragments.append(DeclarationFragments::getExceptionSpecificationString( 921 Method->getExceptionSpecType())); 922 923 return Fragments.appendSemicolon(); 924 } 925 926 DeclarationFragments 927 DeclarationFragmentsBuilder::getFragmentsForConversionFunction( 928 const CXXConversionDecl *ConversionFunction) { 929 DeclarationFragments Fragments; 930 931 if (ConversionFunction->isExplicit()) 932 Fragments.append("explicit", DeclarationFragments::FragmentKind::Keyword) 933 .appendSpace(); 934 935 Fragments.append("operator", DeclarationFragments::FragmentKind::Keyword) 936 .appendSpace(); 937 938 Fragments 939 .append(ConversionFunction->getConversionType().getAsString(), 940 DeclarationFragments::FragmentKind::TypeIdentifier) 941 .append("(", DeclarationFragments::FragmentKind::Text); 942 for (unsigned i = 0, end = ConversionFunction->getNumParams(); i != end; 943 ++i) { 944 if (i) 945 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 946 Fragments.append(getFragmentsForParam(ConversionFunction->getParamDecl(i))); 947 } 948 Fragments.append(")", DeclarationFragments::FragmentKind::Text); 949 950 if (ConversionFunction->isConst()) 951 Fragments.appendSpace().append("const", 952 DeclarationFragments::FragmentKind::Keyword); 953 954 return Fragments.appendSemicolon(); 955 } 956 957 DeclarationFragments 958 DeclarationFragmentsBuilder::getFragmentsForOverloadedOperator( 959 const CXXMethodDecl *Method) { 960 DeclarationFragments Fragments; 961 962 // Build return type 963 DeclarationFragments After; 964 Fragments 965 .append(getFragmentsForType(Method->getReturnType(), 966 Method->getASTContext(), After)) 967 .appendSpace() 968 .append(Method->getNameAsString(), 969 DeclarationFragments::FragmentKind::Identifier) 970 .append(std::move(After)); 971 Fragments.append("(", DeclarationFragments::FragmentKind::Text); 972 for (unsigned i = 0, end = Method->getNumParams(); i != end; ++i) { 973 if (i) 974 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 975 Fragments.append(getFragmentsForParam(Method->getParamDecl(i))); 976 } 977 Fragments.append(")", DeclarationFragments::FragmentKind::Text); 978 979 if (Method->isConst()) 980 Fragments.appendSpace().append("const", 981 DeclarationFragments::FragmentKind::Keyword); 982 983 Fragments.append(DeclarationFragments::getExceptionSpecificationString( 984 Method->getExceptionSpecType())); 985 986 return Fragments.appendSemicolon(); 987 } 988 989 // Get fragments for template parameters, e.g. T in tempalte<typename T> ... 990 DeclarationFragments 991 DeclarationFragmentsBuilder::getFragmentsForTemplateParameters( 992 ArrayRef<NamedDecl *> ParameterArray) { 993 DeclarationFragments Fragments; 994 for (unsigned i = 0, end = ParameterArray.size(); i != end; ++i) { 995 if (i) 996 Fragments.append(",", DeclarationFragments::FragmentKind::Text) 997 .appendSpace(); 998 999 if (const auto *TemplateParam = 1000 dyn_cast<TemplateTypeParmDecl>(ParameterArray[i])) { 1001 if (TemplateParam->hasTypeConstraint()) 1002 Fragments.append(TemplateParam->getTypeConstraint() 1003 ->getNamedConcept() 1004 ->getName() 1005 .str(), 1006 DeclarationFragments::FragmentKind::TypeIdentifier); 1007 else if (TemplateParam->wasDeclaredWithTypename()) 1008 Fragments.append("typename", 1009 DeclarationFragments::FragmentKind::Keyword); 1010 else 1011 Fragments.append("class", DeclarationFragments::FragmentKind::Keyword); 1012 1013 if (TemplateParam->isParameterPack()) 1014 Fragments.append("...", DeclarationFragments::FragmentKind::Text); 1015 1016 if (!TemplateParam->getName().empty()) 1017 Fragments.appendSpace().append( 1018 TemplateParam->getName(), 1019 DeclarationFragments::FragmentKind::GenericParameter); 1020 1021 if (TemplateParam->hasDefaultArgument()) { 1022 const auto Default = TemplateParam->getDefaultArgument(); 1023 Fragments.append(" = ", DeclarationFragments::FragmentKind::Text) 1024 .append(getFragmentsForTemplateArguments( 1025 {Default.getArgument()}, TemplateParam->getASTContext(), 1026 {Default})); 1027 } 1028 } else if (const auto *NTP = 1029 dyn_cast<NonTypeTemplateParmDecl>(ParameterArray[i])) { 1030 DeclarationFragments After; 1031 const auto TyFragments = 1032 getFragmentsForType(NTP->getType(), NTP->getASTContext(), After); 1033 Fragments.append(std::move(TyFragments)).append(std::move(After)); 1034 1035 if (NTP->isParameterPack()) 1036 Fragments.append("...", DeclarationFragments::FragmentKind::Text); 1037 1038 if (!NTP->getName().empty()) 1039 Fragments.appendSpace().append( 1040 NTP->getName(), 1041 DeclarationFragments::FragmentKind::GenericParameter); 1042 1043 if (NTP->hasDefaultArgument()) { 1044 SmallString<8> ExprStr; 1045 raw_svector_ostream Output(ExprStr); 1046 NTP->getDefaultArgument().getArgument().print( 1047 NTP->getASTContext().getPrintingPolicy(), Output, 1048 /*IncludeType=*/false); 1049 Fragments.append(" = ", DeclarationFragments::FragmentKind::Text) 1050 .append(ExprStr, DeclarationFragments::FragmentKind::Text); 1051 } 1052 } else if (const auto *TTP = 1053 dyn_cast<TemplateTemplateParmDecl>(ParameterArray[i])) { 1054 Fragments.append("template", DeclarationFragments::FragmentKind::Keyword) 1055 .appendSpace() 1056 .append("<", DeclarationFragments::FragmentKind::Text) 1057 .append(getFragmentsForTemplateParameters( 1058 TTP->getTemplateParameters()->asArray())) 1059 .append(">", DeclarationFragments::FragmentKind::Text) 1060 .appendSpace() 1061 .append(TTP->wasDeclaredWithTypename() ? "typename" : "class", 1062 DeclarationFragments::FragmentKind::Keyword); 1063 1064 if (TTP->isParameterPack()) 1065 Fragments.append("...", DeclarationFragments::FragmentKind::Text); 1066 1067 if (!TTP->getName().empty()) 1068 Fragments.appendSpace().append( 1069 TTP->getName(), 1070 DeclarationFragments::FragmentKind::GenericParameter); 1071 if (TTP->hasDefaultArgument()) { 1072 const auto Default = TTP->getDefaultArgument(); 1073 Fragments.append(" = ", DeclarationFragments::FragmentKind::Text) 1074 .append(getFragmentsForTemplateArguments( 1075 {Default.getArgument()}, TTP->getASTContext(), {Default})); 1076 } 1077 } 1078 } 1079 return Fragments; 1080 } 1081 1082 // Get fragments for template arguments, e.g. int in template<typename T> 1083 // Foo<int>; 1084 // 1085 // Note: TemplateParameters is only necessary if the Decl is a 1086 // PartialSpecialization, where we need the parameters to deduce the name of the 1087 // generic arguments. 1088 DeclarationFragments 1089 DeclarationFragmentsBuilder::getFragmentsForTemplateArguments( 1090 const ArrayRef<TemplateArgument> TemplateArguments, ASTContext &Context, 1091 const std::optional<ArrayRef<TemplateArgumentLoc>> TemplateArgumentLocs) { 1092 DeclarationFragments Fragments; 1093 for (unsigned i = 0, end = TemplateArguments.size(); i != end; ++i) { 1094 if (i) 1095 Fragments.append(",", DeclarationFragments::FragmentKind::Text) 1096 .appendSpace(); 1097 1098 const auto &CTA = TemplateArguments[i]; 1099 switch (CTA.getKind()) { 1100 case TemplateArgument::Type: { 1101 DeclarationFragments After; 1102 DeclarationFragments ArgumentFragment = 1103 getFragmentsForType(CTA.getAsType(), Context, After); 1104 1105 if (StringRef(ArgumentFragment.begin()->Spelling) 1106 .starts_with("type-parameter")) { 1107 if (TemplateArgumentLocs.has_value() && 1108 TemplateArgumentLocs->size() > i) { 1109 std::string ProperArgName = TemplateArgumentLocs.value()[i] 1110 .getTypeSourceInfo() 1111 ->getType() 1112 .getAsString(); 1113 ArgumentFragment.begin()->Spelling.swap(ProperArgName); 1114 } else { 1115 auto &Spelling = ArgumentFragment.begin()->Spelling; 1116 Spelling.clear(); 1117 raw_string_ostream OutStream(Spelling); 1118 CTA.print(Context.getPrintingPolicy(), OutStream, false); 1119 } 1120 } 1121 1122 Fragments.append(std::move(ArgumentFragment)); 1123 break; 1124 } 1125 case TemplateArgument::Declaration: { 1126 const auto *VD = CTA.getAsDecl(); 1127 SmallString<128> USR; 1128 index::generateUSRForDecl(VD, USR); 1129 Fragments.append(VD->getNameAsString(), 1130 DeclarationFragments::FragmentKind::Identifier, USR); 1131 break; 1132 } 1133 case TemplateArgument::NullPtr: 1134 Fragments.append("nullptr", DeclarationFragments::FragmentKind::Keyword); 1135 break; 1136 1137 case TemplateArgument::Integral: { 1138 SmallString<4> Str; 1139 CTA.getAsIntegral().toString(Str); 1140 Fragments.append(Str, DeclarationFragments::FragmentKind::Text); 1141 break; 1142 } 1143 1144 case TemplateArgument::StructuralValue: { 1145 const auto SVTy = CTA.getStructuralValueType(); 1146 Fragments.append(CTA.getAsStructuralValue().getAsString(Context, SVTy), 1147 DeclarationFragments::FragmentKind::Text); 1148 break; 1149 } 1150 1151 case TemplateArgument::TemplateExpansion: 1152 case TemplateArgument::Template: { 1153 std::string Str; 1154 raw_string_ostream Stream(Str); 1155 CTA.getAsTemplate().print(Stream, Context.getPrintingPolicy()); 1156 SmallString<64> USR(""); 1157 if (const auto *TemplDecl = 1158 CTA.getAsTemplateOrTemplatePattern().getAsTemplateDecl()) 1159 index::generateUSRForDecl(TemplDecl, USR); 1160 Fragments.append(Str, DeclarationFragments::FragmentKind::TypeIdentifier, 1161 USR); 1162 if (CTA.getKind() == TemplateArgument::TemplateExpansion) 1163 Fragments.append("...", DeclarationFragments::FragmentKind::Text); 1164 break; 1165 } 1166 1167 case TemplateArgument::Pack: 1168 Fragments.append("<", DeclarationFragments::FragmentKind::Text) 1169 .append(getFragmentsForTemplateArguments(CTA.pack_elements(), Context, 1170 {})) 1171 .append(">", DeclarationFragments::FragmentKind::Text); 1172 break; 1173 1174 case TemplateArgument::Expression: { 1175 SmallString<8> ExprStr; 1176 raw_svector_ostream Output(ExprStr); 1177 CTA.getAsExpr()->printPretty(Output, nullptr, 1178 Context.getPrintingPolicy()); 1179 Fragments.append(ExprStr, DeclarationFragments::FragmentKind::Text); 1180 break; 1181 } 1182 1183 case TemplateArgument::Null: 1184 break; 1185 } 1186 } 1187 return Fragments; 1188 } 1189 1190 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForConcept( 1191 const ConceptDecl *Concept) { 1192 DeclarationFragments Fragments; 1193 return Fragments 1194 .append("template", DeclarationFragments::FragmentKind::Keyword) 1195 .appendSpace() 1196 .append("<", DeclarationFragments::FragmentKind::Text) 1197 .append(getFragmentsForTemplateParameters( 1198 Concept->getTemplateParameters()->asArray())) 1199 .append("> ", DeclarationFragments::FragmentKind::Text) 1200 .appendSpace() 1201 .append("concept", DeclarationFragments::FragmentKind::Keyword) 1202 .appendSpace() 1203 .append(Concept->getName().str(), 1204 DeclarationFragments::FragmentKind::Identifier) 1205 .appendSemicolon(); 1206 } 1207 1208 DeclarationFragments 1209 DeclarationFragmentsBuilder::getFragmentsForRedeclarableTemplate( 1210 const RedeclarableTemplateDecl *RedeclarableTemplate) { 1211 DeclarationFragments Fragments; 1212 Fragments.append("template", DeclarationFragments::FragmentKind::Keyword) 1213 .appendSpace() 1214 .append("<", DeclarationFragments::FragmentKind::Text) 1215 .append(getFragmentsForTemplateParameters( 1216 RedeclarableTemplate->getTemplateParameters()->asArray())) 1217 .append(">", DeclarationFragments::FragmentKind::Text) 1218 .appendSpace(); 1219 1220 if (isa<TypeAliasTemplateDecl>(RedeclarableTemplate)) 1221 Fragments.appendSpace() 1222 .append("using", DeclarationFragments::FragmentKind::Keyword) 1223 .appendSpace() 1224 .append(RedeclarableTemplate->getName(), 1225 DeclarationFragments::FragmentKind::Identifier); 1226 // the templated records will be resposbible for injecting their templates 1227 return Fragments.appendSpace(); 1228 } 1229 1230 DeclarationFragments 1231 DeclarationFragmentsBuilder::getFragmentsForClassTemplateSpecialization( 1232 const ClassTemplateSpecializationDecl *Decl) { 1233 DeclarationFragments Fragments; 1234 std::optional<ArrayRef<TemplateArgumentLoc>> TemplateArgumentLocs = {}; 1235 if (auto *TemplateArgs = Decl->getTemplateArgsAsWritten()) { 1236 TemplateArgumentLocs = TemplateArgs->arguments(); 1237 } 1238 return Fragments 1239 .append("template", DeclarationFragments::FragmentKind::Keyword) 1240 .appendSpace() 1241 .append("<", DeclarationFragments::FragmentKind::Text) 1242 .append(">", DeclarationFragments::FragmentKind::Text) 1243 .appendSpace() 1244 .append(DeclarationFragmentsBuilder::getFragmentsForCXXClass( 1245 cast<CXXRecordDecl>(Decl))) 1246 .pop_back() // there is an extra semicolon now 1247 .append("<", DeclarationFragments::FragmentKind::Text) 1248 .append(getFragmentsForTemplateArguments( 1249 Decl->getTemplateArgs().asArray(), Decl->getASTContext(), 1250 TemplateArgumentLocs)) 1251 .append(">", DeclarationFragments::FragmentKind::Text) 1252 .appendSemicolon(); 1253 } 1254 1255 DeclarationFragments 1256 DeclarationFragmentsBuilder::getFragmentsForClassTemplatePartialSpecialization( 1257 const ClassTemplatePartialSpecializationDecl *Decl) { 1258 DeclarationFragments Fragments; 1259 return Fragments 1260 .append("template", DeclarationFragments::FragmentKind::Keyword) 1261 .appendSpace() 1262 .append("<", DeclarationFragments::FragmentKind::Text) 1263 .append(getFragmentsForTemplateParameters( 1264 Decl->getTemplateParameters()->asArray())) 1265 .append(">", DeclarationFragments::FragmentKind::Text) 1266 .appendSpace() 1267 .append(DeclarationFragmentsBuilder::getFragmentsForCXXClass( 1268 cast<CXXRecordDecl>(Decl))) 1269 .pop_back() // there is an extra semicolon now 1270 .append("<", DeclarationFragments::FragmentKind::Text) 1271 .append(getFragmentsForTemplateArguments( 1272 Decl->getTemplateArgs().asArray(), Decl->getASTContext(), 1273 Decl->getTemplateArgsAsWritten()->arguments())) 1274 .append(">", DeclarationFragments::FragmentKind::Text) 1275 .appendSemicolon(); 1276 } 1277 1278 DeclarationFragments 1279 DeclarationFragmentsBuilder::getFragmentsForVarTemplateSpecialization( 1280 const VarTemplateSpecializationDecl *Decl) { 1281 DeclarationFragments Fragments; 1282 return Fragments 1283 .append("template", DeclarationFragments::FragmentKind::Keyword) 1284 .appendSpace() 1285 .append("<", DeclarationFragments::FragmentKind::Text) 1286 .append(">", DeclarationFragments::FragmentKind::Text) 1287 .appendSpace() 1288 .append(DeclarationFragmentsBuilder::getFragmentsForVarTemplate(Decl)) 1289 .pop_back() // there is an extra semicolon now 1290 .append("<", DeclarationFragments::FragmentKind::Text) 1291 .append(getFragmentsForTemplateArguments( 1292 Decl->getTemplateArgs().asArray(), Decl->getASTContext(), 1293 Decl->getTemplateArgsAsWritten()->arguments())) 1294 .append(">", DeclarationFragments::FragmentKind::Text) 1295 .appendSemicolon(); 1296 } 1297 1298 DeclarationFragments 1299 DeclarationFragmentsBuilder::getFragmentsForVarTemplatePartialSpecialization( 1300 const VarTemplatePartialSpecializationDecl *Decl) { 1301 DeclarationFragments Fragments; 1302 return Fragments 1303 .append("template", DeclarationFragments::FragmentKind::Keyword) 1304 .appendSpace() 1305 .append("<", DeclarationFragments::FragmentKind::Text) 1306 // Partial specs may have new params. 1307 .append(getFragmentsForTemplateParameters( 1308 Decl->getTemplateParameters()->asArray())) 1309 .append(">", DeclarationFragments::FragmentKind::Text) 1310 .appendSpace() 1311 .append(DeclarationFragmentsBuilder::getFragmentsForVarTemplate(Decl)) 1312 .pop_back() // there is an extra semicolon now 1313 .append("<", DeclarationFragments::FragmentKind::Text) 1314 .append(getFragmentsForTemplateArguments( 1315 Decl->getTemplateArgs().asArray(), Decl->getASTContext(), 1316 Decl->getTemplateArgsAsWritten()->arguments())) 1317 .append(">", DeclarationFragments::FragmentKind::Text) 1318 .appendSemicolon(); 1319 } 1320 1321 DeclarationFragments 1322 DeclarationFragmentsBuilder::getFragmentsForFunctionTemplate( 1323 const FunctionTemplateDecl *Decl) { 1324 DeclarationFragments Fragments; 1325 return Fragments 1326 .append("template", DeclarationFragments::FragmentKind::Keyword) 1327 .appendSpace() 1328 .append("<", DeclarationFragments::FragmentKind::Text) 1329 // Partial specs may have new params. 1330 .append(getFragmentsForTemplateParameters( 1331 Decl->getTemplateParameters()->asArray())) 1332 .append(">", DeclarationFragments::FragmentKind::Text) 1333 .appendSpace() 1334 .append(DeclarationFragmentsBuilder::getFragmentsForFunction( 1335 Decl->getAsFunction())); 1336 } 1337 1338 DeclarationFragments 1339 DeclarationFragmentsBuilder::getFragmentsForFunctionTemplateSpecialization( 1340 const FunctionDecl *Decl) { 1341 DeclarationFragments Fragments; 1342 return Fragments 1343 .append("template", DeclarationFragments::FragmentKind::Keyword) 1344 .appendSpace() 1345 .append("<>", DeclarationFragments::FragmentKind::Text) 1346 .appendSpace() 1347 .append(DeclarationFragmentsBuilder::getFragmentsForFunction(Decl)); 1348 } 1349 1350 DeclarationFragments 1351 DeclarationFragmentsBuilder::getFragmentsForMacro(StringRef Name, 1352 const MacroInfo *MI) { 1353 DeclarationFragments Fragments; 1354 Fragments.append("#define", DeclarationFragments::FragmentKind::Keyword) 1355 .appendSpace(); 1356 Fragments.append(Name, DeclarationFragments::FragmentKind::Identifier); 1357 1358 if (MI->isFunctionLike()) { 1359 Fragments.append("(", DeclarationFragments::FragmentKind::Text); 1360 unsigned numParameters = MI->getNumParams(); 1361 if (MI->isC99Varargs()) 1362 --numParameters; 1363 for (unsigned i = 0; i < numParameters; ++i) { 1364 if (i) 1365 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 1366 Fragments.append(MI->params()[i]->getName(), 1367 DeclarationFragments::FragmentKind::InternalParam); 1368 } 1369 if (MI->isVariadic()) { 1370 if (numParameters && MI->isC99Varargs()) 1371 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 1372 Fragments.append("...", DeclarationFragments::FragmentKind::Text); 1373 } 1374 Fragments.append(")", DeclarationFragments::FragmentKind::Text); 1375 } 1376 return Fragments; 1377 } 1378 1379 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCCategory( 1380 const ObjCCategoryDecl *Category) { 1381 DeclarationFragments Fragments; 1382 1383 auto *Interface = Category->getClassInterface(); 1384 SmallString<128> InterfaceUSR; 1385 index::generateUSRForDecl(Interface, InterfaceUSR); 1386 1387 Fragments.append("@interface", DeclarationFragments::FragmentKind::Keyword) 1388 .appendSpace() 1389 .append(Interface->getName(), 1390 DeclarationFragments::FragmentKind::TypeIdentifier, InterfaceUSR, 1391 Interface) 1392 .append(" (", DeclarationFragments::FragmentKind::Text) 1393 .append(Category->getName(), 1394 DeclarationFragments::FragmentKind::Identifier) 1395 .append(")", DeclarationFragments::FragmentKind::Text); 1396 1397 return Fragments; 1398 } 1399 1400 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCInterface( 1401 const ObjCInterfaceDecl *Interface) { 1402 DeclarationFragments Fragments; 1403 // Build the base of the Objective-C interface declaration. 1404 Fragments.append("@interface", DeclarationFragments::FragmentKind::Keyword) 1405 .appendSpace() 1406 .append(Interface->getName(), 1407 DeclarationFragments::FragmentKind::Identifier); 1408 1409 // Build the inheritance part of the declaration. 1410 if (const ObjCInterfaceDecl *SuperClass = Interface->getSuperClass()) { 1411 SmallString<128> SuperUSR; 1412 index::generateUSRForDecl(SuperClass, SuperUSR); 1413 Fragments.append(" : ", DeclarationFragments::FragmentKind::Text) 1414 .append(SuperClass->getName(), 1415 DeclarationFragments::FragmentKind::TypeIdentifier, SuperUSR, 1416 SuperClass); 1417 } 1418 1419 return Fragments; 1420 } 1421 1422 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCMethod( 1423 const ObjCMethodDecl *Method) { 1424 DeclarationFragments Fragments, After; 1425 // Build the instance/class method indicator. 1426 if (Method->isClassMethod()) 1427 Fragments.append("+ ", DeclarationFragments::FragmentKind::Text); 1428 else if (Method->isInstanceMethod()) 1429 Fragments.append("- ", DeclarationFragments::FragmentKind::Text); 1430 1431 // Build the return type. 1432 Fragments.append("(", DeclarationFragments::FragmentKind::Text) 1433 .append(getFragmentsForType(Method->getReturnType(), 1434 Method->getASTContext(), After)) 1435 .append(std::move(After)) 1436 .append(")", DeclarationFragments::FragmentKind::Text); 1437 1438 // Build the selector part. 1439 Selector Selector = Method->getSelector(); 1440 if (Selector.getNumArgs() == 0) 1441 // For Objective-C methods that don't take arguments, the first (and only) 1442 // slot of the selector is the method name. 1443 Fragments.appendSpace().append( 1444 Selector.getNameForSlot(0), 1445 DeclarationFragments::FragmentKind::Identifier); 1446 1447 // For Objective-C methods that take arguments, build the selector slots. 1448 for (unsigned i = 0, end = Method->param_size(); i != end; ++i) { 1449 // Objective-C method selector parts are considered as identifiers instead 1450 // of "external parameters" as in Swift. This is because Objective-C method 1451 // symbols are referenced with the entire selector, instead of just the 1452 // method name in Swift. 1453 SmallString<32> ParamID(Selector.getNameForSlot(i)); 1454 ParamID.append(":"); 1455 Fragments.appendSpace().append( 1456 ParamID, DeclarationFragments::FragmentKind::Identifier); 1457 1458 // Build the internal parameter. 1459 const ParmVarDecl *Param = Method->getParamDecl(i); 1460 Fragments.append(getFragmentsForParam(Param)); 1461 } 1462 1463 return Fragments.appendSemicolon(); 1464 } 1465 1466 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProperty( 1467 const ObjCPropertyDecl *Property) { 1468 DeclarationFragments Fragments, After; 1469 1470 // Build the Objective-C property keyword. 1471 Fragments.append("@property", DeclarationFragments::FragmentKind::Keyword); 1472 1473 const auto Attributes = Property->getPropertyAttributesAsWritten(); 1474 // Build the attributes if there is any associated with the property. 1475 if (Attributes != ObjCPropertyAttribute::kind_noattr) { 1476 // No leading comma for the first attribute. 1477 bool First = true; 1478 Fragments.append(" (", DeclarationFragments::FragmentKind::Text); 1479 // Helper function to render the attribute. 1480 auto RenderAttribute = 1481 [&](ObjCPropertyAttribute::Kind Kind, StringRef Spelling, 1482 StringRef Arg = "", 1483 DeclarationFragments::FragmentKind ArgKind = 1484 DeclarationFragments::FragmentKind::Identifier) { 1485 // Check if the `Kind` attribute is set for this property. 1486 if ((Attributes & Kind) && !Spelling.empty()) { 1487 // Add a leading comma if this is not the first attribute rendered. 1488 if (!First) 1489 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 1490 // Render the spelling of this attribute `Kind` as a keyword. 1491 Fragments.append(Spelling, 1492 DeclarationFragments::FragmentKind::Keyword); 1493 // If this attribute takes in arguments (e.g. `getter=getterName`), 1494 // render the arguments. 1495 if (!Arg.empty()) 1496 Fragments.append("=", DeclarationFragments::FragmentKind::Text) 1497 .append(Arg, ArgKind); 1498 First = false; 1499 } 1500 }; 1501 1502 // Go through all possible Objective-C property attributes and render set 1503 // ones. 1504 RenderAttribute(ObjCPropertyAttribute::kind_class, "class"); 1505 RenderAttribute(ObjCPropertyAttribute::kind_direct, "direct"); 1506 RenderAttribute(ObjCPropertyAttribute::kind_nonatomic, "nonatomic"); 1507 RenderAttribute(ObjCPropertyAttribute::kind_atomic, "atomic"); 1508 RenderAttribute(ObjCPropertyAttribute::kind_assign, "assign"); 1509 RenderAttribute(ObjCPropertyAttribute::kind_retain, "retain"); 1510 RenderAttribute(ObjCPropertyAttribute::kind_strong, "strong"); 1511 RenderAttribute(ObjCPropertyAttribute::kind_copy, "copy"); 1512 RenderAttribute(ObjCPropertyAttribute::kind_weak, "weak"); 1513 RenderAttribute(ObjCPropertyAttribute::kind_unsafe_unretained, 1514 "unsafe_unretained"); 1515 RenderAttribute(ObjCPropertyAttribute::kind_readwrite, "readwrite"); 1516 RenderAttribute(ObjCPropertyAttribute::kind_readonly, "readonly"); 1517 RenderAttribute(ObjCPropertyAttribute::kind_getter, "getter", 1518 Property->getGetterName().getAsString()); 1519 RenderAttribute(ObjCPropertyAttribute::kind_setter, "setter", 1520 Property->getSetterName().getAsString()); 1521 1522 // Render nullability attributes. 1523 if (Attributes & ObjCPropertyAttribute::kind_nullability) { 1524 QualType Type = Property->getType(); 1525 if (const auto Nullability = 1526 AttributedType::stripOuterNullability(Type)) { 1527 if (!First) 1528 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 1529 if (*Nullability == NullabilityKind::Unspecified && 1530 (Attributes & ObjCPropertyAttribute::kind_null_resettable)) 1531 Fragments.append("null_resettable", 1532 DeclarationFragments::FragmentKind::Keyword); 1533 else 1534 Fragments.append( 1535 getNullabilitySpelling(*Nullability, /*isContextSensitive=*/true), 1536 DeclarationFragments::FragmentKind::Keyword); 1537 First = false; 1538 } 1539 } 1540 1541 Fragments.append(")", DeclarationFragments::FragmentKind::Text); 1542 } 1543 1544 Fragments.appendSpace(); 1545 1546 FunctionTypeLoc BlockLoc; 1547 FunctionProtoTypeLoc BlockProtoLoc; 1548 findTypeLocForBlockDecl(Property->getTypeSourceInfo(), BlockLoc, 1549 BlockProtoLoc); 1550 1551 auto PropType = Property->getType(); 1552 if (!BlockLoc) 1553 Fragments 1554 .append(getFragmentsForType(PropType, Property->getASTContext(), After)) 1555 .appendSpace(); 1556 else 1557 Fragments.append( 1558 getFragmentsForBlock(Property, BlockLoc, BlockProtoLoc, After)); 1559 1560 return Fragments 1561 .append(Property->getName(), 1562 DeclarationFragments::FragmentKind::Identifier) 1563 .append(std::move(After)) 1564 .appendSemicolon(); 1565 } 1566 1567 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProtocol( 1568 const ObjCProtocolDecl *Protocol) { 1569 DeclarationFragments Fragments; 1570 // Build basic protocol declaration. 1571 Fragments.append("@protocol", DeclarationFragments::FragmentKind::Keyword) 1572 .appendSpace() 1573 .append(Protocol->getName(), 1574 DeclarationFragments::FragmentKind::Identifier); 1575 1576 // If this protocol conforms to other protocols, build the conformance list. 1577 if (!Protocol->protocols().empty()) { 1578 Fragments.append(" <", DeclarationFragments::FragmentKind::Text); 1579 for (ObjCProtocolDecl::protocol_iterator It = Protocol->protocol_begin(); 1580 It != Protocol->protocol_end(); It++) { 1581 // Add a leading comma if this is not the first protocol rendered. 1582 if (It != Protocol->protocol_begin()) 1583 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 1584 1585 SmallString<128> USR; 1586 index::generateUSRForDecl(*It, USR); 1587 Fragments.append((*It)->getName(), 1588 DeclarationFragments::FragmentKind::TypeIdentifier, USR, 1589 *It); 1590 } 1591 Fragments.append(">", DeclarationFragments::FragmentKind::Text); 1592 } 1593 1594 return Fragments; 1595 } 1596 1597 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForTypedef( 1598 const TypedefNameDecl *Decl) { 1599 DeclarationFragments Fragments, After; 1600 Fragments.append("typedef", DeclarationFragments::FragmentKind::Keyword) 1601 .appendSpace() 1602 .append(getFragmentsForType(Decl->getUnderlyingType(), 1603 Decl->getASTContext(), After)) 1604 .append(std::move(After)) 1605 .appendSpace() 1606 .append(Decl->getName(), DeclarationFragments::FragmentKind::Identifier); 1607 1608 return Fragments.appendSemicolon(); 1609 } 1610 1611 // Instantiate template for FunctionDecl. 1612 template FunctionSignature 1613 DeclarationFragmentsBuilder::getFunctionSignature(const FunctionDecl *); 1614 1615 // Instantiate template for ObjCMethodDecl. 1616 template FunctionSignature 1617 DeclarationFragmentsBuilder::getFunctionSignature(const ObjCMethodDecl *); 1618 1619 // Subheading of a symbol defaults to its name. 1620 DeclarationFragments 1621 DeclarationFragmentsBuilder::getSubHeading(const NamedDecl *Decl) { 1622 DeclarationFragments Fragments; 1623 if (isa<CXXConstructorDecl>(Decl)) { 1624 Fragments.append(cast<CXXRecordDecl>(Decl->getDeclContext())->getName(), 1625 DeclarationFragments::FragmentKind::Identifier); 1626 } else if (isa<CXXDestructorDecl>(Decl)) { 1627 Fragments.append(cast<CXXDestructorDecl>(Decl)->getNameAsString(), 1628 DeclarationFragments::FragmentKind::Identifier); 1629 } else if (isa<CXXConversionDecl>(Decl)) { 1630 Fragments.append( 1631 cast<CXXConversionDecl>(Decl)->getConversionType().getAsString(), 1632 DeclarationFragments::FragmentKind::Identifier); 1633 } else if (isa<CXXMethodDecl>(Decl) && 1634 cast<CXXMethodDecl>(Decl)->isOverloadedOperator()) { 1635 Fragments.append(Decl->getNameAsString(), 1636 DeclarationFragments::FragmentKind::Identifier); 1637 } else if (isa<TagDecl>(Decl) && 1638 cast<TagDecl>(Decl)->getTypedefNameForAnonDecl()) { 1639 return getSubHeading(cast<TagDecl>(Decl)->getTypedefNameForAnonDecl()); 1640 } else if (Decl->getIdentifier()) { 1641 Fragments.append(Decl->getName(), 1642 DeclarationFragments::FragmentKind::Identifier); 1643 } else { 1644 Fragments.append(Decl->getDeclName().getAsString(), 1645 DeclarationFragments::FragmentKind::Identifier); 1646 } 1647 1648 return Fragments; 1649 } 1650 1651 // Subheading of an Objective-C method is a `+` or `-` sign indicating whether 1652 // it's a class method or an instance method, followed by the selector name. 1653 DeclarationFragments 1654 DeclarationFragmentsBuilder::getSubHeading(const ObjCMethodDecl *Method) { 1655 DeclarationFragments Fragments; 1656 if (Method->isClassMethod()) 1657 Fragments.append("+ ", DeclarationFragments::FragmentKind::Text); 1658 else if (Method->isInstanceMethod()) 1659 Fragments.append("- ", DeclarationFragments::FragmentKind::Text); 1660 1661 return Fragments.append(Method->getNameAsString(), 1662 DeclarationFragments::FragmentKind::Identifier); 1663 } 1664 1665 // Subheading of a symbol defaults to its name. 1666 DeclarationFragments 1667 DeclarationFragmentsBuilder::getSubHeadingForMacro(StringRef Name) { 1668 DeclarationFragments Fragments; 1669 Fragments.append(Name, DeclarationFragments::FragmentKind::Identifier); 1670 return Fragments; 1671 } 1672