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