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