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