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 "TypedefUnderlyingTypeResolver.h" 16 #include "clang/Index/USRGeneration.h" 17 #include "llvm/ADT/StringSwitch.h" 18 19 using namespace clang::extractapi; 20 using namespace llvm; 21 22 DeclarationFragments &DeclarationFragments::appendSpace() { 23 if (!Fragments.empty()) { 24 Fragment &Last = Fragments.back(); 25 if (Last.Kind == FragmentKind::Text) { 26 // Merge the extra space into the last fragment if the last fragment is 27 // also text. 28 if (Last.Spelling.back() != ' ') { // avoid extra trailing spaces. 29 Last.Spelling.push_back(' '); 30 } 31 } else { 32 append(" ", FragmentKind::Text); 33 } 34 } 35 36 return *this; 37 } 38 39 StringRef DeclarationFragments::getFragmentKindString( 40 DeclarationFragments::FragmentKind Kind) { 41 switch (Kind) { 42 case DeclarationFragments::FragmentKind::None: 43 return "none"; 44 case DeclarationFragments::FragmentKind::Keyword: 45 return "keyword"; 46 case DeclarationFragments::FragmentKind::Attribute: 47 return "attribute"; 48 case DeclarationFragments::FragmentKind::NumberLiteral: 49 return "number"; 50 case DeclarationFragments::FragmentKind::StringLiteral: 51 return "string"; 52 case DeclarationFragments::FragmentKind::Identifier: 53 return "identifier"; 54 case DeclarationFragments::FragmentKind::TypeIdentifier: 55 return "typeIdentifier"; 56 case DeclarationFragments::FragmentKind::GenericParameter: 57 return "genericParameter"; 58 case DeclarationFragments::FragmentKind::ExternalParam: 59 return "externalParam"; 60 case DeclarationFragments::FragmentKind::InternalParam: 61 return "internalParam"; 62 case DeclarationFragments::FragmentKind::Text: 63 return "text"; 64 } 65 66 llvm_unreachable("Unhandled FragmentKind"); 67 } 68 69 DeclarationFragments::FragmentKind 70 DeclarationFragments::parseFragmentKindFromString(StringRef S) { 71 return llvm::StringSwitch<FragmentKind>(S) 72 .Case("keyword", DeclarationFragments::FragmentKind::Keyword) 73 .Case("attribute", DeclarationFragments::FragmentKind::Attribute) 74 .Case("number", DeclarationFragments::FragmentKind::NumberLiteral) 75 .Case("string", DeclarationFragments::FragmentKind::StringLiteral) 76 .Case("identifier", DeclarationFragments::FragmentKind::Identifier) 77 .Case("typeIdentifier", 78 DeclarationFragments::FragmentKind::TypeIdentifier) 79 .Case("genericParameter", 80 DeclarationFragments::FragmentKind::GenericParameter) 81 .Case("internalParam", DeclarationFragments::FragmentKind::InternalParam) 82 .Case("externalParam", DeclarationFragments::FragmentKind::ExternalParam) 83 .Case("text", DeclarationFragments::FragmentKind::Text) 84 .Default(DeclarationFragments::FragmentKind::None); 85 } 86 87 // NNS stores C++ nested name specifiers, which are prefixes to qualified names. 88 // Build declaration fragments for NNS recursively so that we have the USR for 89 // every part in a qualified name, and also leaves the actual underlying type 90 // cleaner for its own fragment. 91 DeclarationFragments 92 DeclarationFragmentsBuilder::getFragmentsForNNS(const NestedNameSpecifier *NNS, 93 ASTContext &Context, 94 DeclarationFragments &After) { 95 DeclarationFragments Fragments; 96 if (NNS->getPrefix()) 97 Fragments.append(getFragmentsForNNS(NNS->getPrefix(), Context, After)); 98 99 switch (NNS->getKind()) { 100 case NestedNameSpecifier::Identifier: 101 Fragments.append(NNS->getAsIdentifier()->getName(), 102 DeclarationFragments::FragmentKind::Identifier); 103 break; 104 105 case NestedNameSpecifier::Namespace: { 106 const NamespaceDecl *NS = NNS->getAsNamespace(); 107 if (NS->isAnonymousNamespace()) 108 return Fragments; 109 SmallString<128> USR; 110 index::generateUSRForDecl(NS, USR); 111 Fragments.append(NS->getName(), 112 DeclarationFragments::FragmentKind::Identifier, USR, NS); 113 break; 114 } 115 116 case NestedNameSpecifier::NamespaceAlias: { 117 const NamespaceAliasDecl *Alias = NNS->getAsNamespaceAlias(); 118 SmallString<128> USR; 119 index::generateUSRForDecl(Alias, USR); 120 Fragments.append(Alias->getName(), 121 DeclarationFragments::FragmentKind::Identifier, USR, 122 Alias); 123 break; 124 } 125 126 case NestedNameSpecifier::Global: 127 // The global specifier `::` at the beginning. No stored value. 128 break; 129 130 case NestedNameSpecifier::Super: 131 // Microsoft's `__super` specifier. 132 Fragments.append("__super", DeclarationFragments::FragmentKind::Keyword); 133 break; 134 135 case NestedNameSpecifier::TypeSpecWithTemplate: 136 // A type prefixed by the `template` keyword. 137 Fragments.append("template", DeclarationFragments::FragmentKind::Keyword); 138 Fragments.appendSpace(); 139 // Fallthrough after adding the keyword to handle the actual type. 140 [[fallthrough]]; 141 142 case NestedNameSpecifier::TypeSpec: { 143 const Type *T = NNS->getAsType(); 144 // FIXME: Handle C++ template specialization type 145 Fragments.append(getFragmentsForType(T, Context, After)); 146 break; 147 } 148 } 149 150 // Add the separator text `::` for this segment. 151 return Fragments.append("::", DeclarationFragments::FragmentKind::Text); 152 } 153 154 // Recursively build the declaration fragments for an underlying `Type` with 155 // qualifiers removed. 156 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType( 157 const Type *T, ASTContext &Context, DeclarationFragments &After) { 158 assert(T && "invalid type"); 159 160 DeclarationFragments Fragments; 161 162 // Declaration fragments of a pointer type is the declaration fragments of 163 // the pointee type followed by a `*`, except for Objective-C `id` and `Class` 164 // pointers, where we do not spell out the `*`. 165 if (T->isPointerType() || 166 (T->isObjCObjectPointerType() && 167 !T->getAs<ObjCObjectPointerType>()->isObjCIdOrClassType())) { 168 return Fragments 169 .append(getFragmentsForType(T->getPointeeType(), Context, After)) 170 .append(" *", DeclarationFragments::FragmentKind::Text); 171 } 172 173 // Declaration fragments of a lvalue reference type is the declaration 174 // fragments of the underlying type followed by a `&`. 175 if (const LValueReferenceType *LRT = dyn_cast<LValueReferenceType>(T)) 176 return Fragments 177 .append( 178 getFragmentsForType(LRT->getPointeeTypeAsWritten(), Context, After)) 179 .append(" &", DeclarationFragments::FragmentKind::Text); 180 181 // Declaration fragments of a rvalue reference type is the declaration 182 // fragments of the underlying type followed by a `&&`. 183 if (const RValueReferenceType *RRT = dyn_cast<RValueReferenceType>(T)) 184 return Fragments 185 .append( 186 getFragmentsForType(RRT->getPointeeTypeAsWritten(), Context, After)) 187 .append(" &&", DeclarationFragments::FragmentKind::Text); 188 189 // Declaration fragments of an array-typed variable have two parts: 190 // 1. the element type of the array that appears before the variable name; 191 // 2. array brackets `[(0-9)?]` that appear after the variable name. 192 if (const ArrayType *AT = T->getAsArrayTypeUnsafe()) { 193 // Build the "after" part first because the inner element type might also 194 // be an array-type. For example `int matrix[3][4]` which has a type of 195 // "(array 3 of (array 4 of ints))." 196 // Push the array size part first to make sure they are in the right order. 197 After.append("[", DeclarationFragments::FragmentKind::Text); 198 199 switch (AT->getSizeModifier()) { 200 case ArrayType::Normal: 201 break; 202 case ArrayType::Static: 203 Fragments.append("static", DeclarationFragments::FragmentKind::Keyword); 204 break; 205 case ArrayType::Star: 206 Fragments.append("*", DeclarationFragments::FragmentKind::Text); 207 break; 208 } 209 210 if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) { 211 // FIXME: right now this would evaluate any expressions/macros written in 212 // the original source to concrete values. For example 213 // `int nums[MAX]` -> `int nums[100]` 214 // `char *str[5 + 1]` -> `char *str[6]` 215 SmallString<128> Size; 216 CAT->getSize().toStringUnsigned(Size); 217 After.append(Size, DeclarationFragments::FragmentKind::NumberLiteral); 218 } 219 220 After.append("]", DeclarationFragments::FragmentKind::Text); 221 222 return Fragments.append( 223 getFragmentsForType(AT->getElementType(), Context, After)); 224 } 225 226 // An ElaboratedType is a sugar for types that are referred to using an 227 // elaborated keyword, e.g., `struct S`, `enum E`, or (in C++) via a 228 // qualified name, e.g., `N::M::type`, or both. 229 if (const ElaboratedType *ET = dyn_cast<ElaboratedType>(T)) { 230 ElaboratedTypeKeyword Keyword = ET->getKeyword(); 231 if (Keyword != ETK_None) { 232 Fragments 233 .append(ElaboratedType::getKeywordName(Keyword), 234 DeclarationFragments::FragmentKind::Keyword) 235 .appendSpace(); 236 } 237 238 if (const NestedNameSpecifier *NNS = ET->getQualifier()) 239 Fragments.append(getFragmentsForNNS(NNS, Context, After)); 240 241 // After handling the elaborated keyword or qualified name, build 242 // declaration fragments for the desugared underlying type. 243 return Fragments.append(getFragmentsForType(ET->desugar(), Context, After)); 244 } 245 246 // Everything we care about has been handled now, reduce to the canonical 247 // unqualified base type. 248 QualType Base = T->getCanonicalTypeUnqualified(); 249 250 // Render Objective-C `id`/`instancetype` as keywords. 251 if (T->isObjCIdType()) 252 return Fragments.append(Base.getAsString(), 253 DeclarationFragments::FragmentKind::Keyword); 254 255 // If the type is a typedefed type, get the underlying TypedefNameDecl for a 256 // direct reference to the typedef instead of the wrapped type. 257 if (const TypedefType *TypedefTy = dyn_cast<TypedefType>(T)) { 258 const TypedefNameDecl *Decl = TypedefTy->getDecl(); 259 TypedefUnderlyingTypeResolver TypedefResolver(Context); 260 std::string USR = TypedefResolver.getUSRForType(QualType(T, 0)); 261 return Fragments.append( 262 Decl->getName(), DeclarationFragments::FragmentKind::TypeIdentifier, 263 USR, TypedefResolver.getUnderlyingTypeDecl(QualType(T, 0))); 264 } 265 266 // If the base type is a TagType (struct/interface/union/class/enum), let's 267 // get the underlying Decl for better names and USRs. 268 if (const TagType *TagTy = dyn_cast<TagType>(Base)) { 269 const TagDecl *Decl = TagTy->getDecl(); 270 // Anonymous decl, skip this fragment. 271 if (Decl->getName().empty()) 272 return Fragments; 273 SmallString<128> TagUSR; 274 clang::index::generateUSRForDecl(Decl, TagUSR); 275 return Fragments.append(Decl->getName(), 276 DeclarationFragments::FragmentKind::TypeIdentifier, 277 TagUSR, Decl); 278 } 279 280 // If the base type is an ObjCInterfaceType, use the underlying 281 // ObjCInterfaceDecl for the true USR. 282 if (const auto *ObjCIT = dyn_cast<ObjCInterfaceType>(Base)) { 283 const auto *Decl = ObjCIT->getDecl(); 284 SmallString<128> USR; 285 index::generateUSRForDecl(Decl, USR); 286 return Fragments.append(Decl->getName(), 287 DeclarationFragments::FragmentKind::TypeIdentifier, 288 USR, Decl); 289 } 290 291 // Default fragment builder for other kinds of types (BuiltinType etc.) 292 SmallString<128> USR; 293 clang::index::generateUSRForType(Base, Context, USR); 294 Fragments.append(Base.getAsString(), 295 DeclarationFragments::FragmentKind::TypeIdentifier, USR); 296 297 return Fragments; 298 } 299 300 DeclarationFragments 301 DeclarationFragmentsBuilder::getFragmentsForQualifiers(const Qualifiers Quals) { 302 DeclarationFragments Fragments; 303 if (Quals.hasConst()) 304 Fragments.append("const", DeclarationFragments::FragmentKind::Keyword); 305 if (Quals.hasVolatile()) 306 Fragments.append("volatile", DeclarationFragments::FragmentKind::Keyword); 307 if (Quals.hasRestrict()) 308 Fragments.append("restrict", DeclarationFragments::FragmentKind::Keyword); 309 310 return Fragments; 311 } 312 313 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType( 314 const QualType QT, ASTContext &Context, DeclarationFragments &After) { 315 assert(!QT.isNull() && "invalid type"); 316 317 if (const ParenType *PT = dyn_cast<ParenType>(QT)) { 318 After.append(")", DeclarationFragments::FragmentKind::Text); 319 return getFragmentsForType(PT->getInnerType(), Context, After) 320 .append("(", DeclarationFragments::FragmentKind::Text); 321 } 322 323 const SplitQualType SQT = QT.split(); 324 DeclarationFragments QualsFragments = getFragmentsForQualifiers(SQT.Quals), 325 TypeFragments = 326 getFragmentsForType(SQT.Ty, Context, After); 327 if (QualsFragments.getFragments().empty()) 328 return TypeFragments; 329 330 // Use east qualifier for pointer types 331 // For example: 332 // ``` 333 // int * const 334 // ^---- ^---- 335 // type qualifier 336 // ^----------------- 337 // const pointer to int 338 // ``` 339 // should not be reconstructed as 340 // ``` 341 // const int * 342 // ^---- ^-- 343 // qualifier type 344 // ^---------------- ^ 345 // pointer to const int 346 // ``` 347 if (SQT.Ty->isAnyPointerType()) 348 return TypeFragments.appendSpace().append(std::move(QualsFragments)); 349 350 return QualsFragments.appendSpace().append(std::move(TypeFragments)); 351 } 352 353 DeclarationFragments 354 DeclarationFragmentsBuilder::getFragmentsForVar(const VarDecl *Var) { 355 DeclarationFragments Fragments; 356 StorageClass SC = Var->getStorageClass(); 357 if (SC != SC_None) 358 Fragments 359 .append(VarDecl::getStorageClassSpecifierString(SC), 360 DeclarationFragments::FragmentKind::Keyword) 361 .appendSpace(); 362 QualType T = 363 Var->getTypeSourceInfo() 364 ? Var->getTypeSourceInfo()->getType() 365 : Var->getASTContext().getUnqualifiedObjCPointerType(Var->getType()); 366 367 // Capture potential fragments that needs to be placed after the variable name 368 // ``` 369 // int nums[5]; 370 // char (*ptr_to_array)[6]; 371 // ``` 372 DeclarationFragments After; 373 return Fragments.append(getFragmentsForType(T, Var->getASTContext(), After)) 374 .appendSpace() 375 .append(Var->getName(), DeclarationFragments::FragmentKind::Identifier) 376 .append(std::move(After)); 377 } 378 379 DeclarationFragments 380 DeclarationFragmentsBuilder::getFragmentsForParam(const ParmVarDecl *Param) { 381 DeclarationFragments Fragments, After; 382 383 QualType T = Param->getTypeSourceInfo() 384 ? Param->getTypeSourceInfo()->getType() 385 : Param->getASTContext().getUnqualifiedObjCPointerType( 386 Param->getType()); 387 388 DeclarationFragments TypeFragments = 389 getFragmentsForType(T, Param->getASTContext(), After); 390 391 if (Param->isObjCMethodParameter()) 392 Fragments.append("(", DeclarationFragments::FragmentKind::Text) 393 .append(std::move(TypeFragments)) 394 .append(") ", DeclarationFragments::FragmentKind::Text); 395 else 396 Fragments.append(std::move(TypeFragments)).appendSpace(); 397 398 return Fragments 399 .append(Param->getName(), 400 DeclarationFragments::FragmentKind::InternalParam) 401 .append(std::move(After)); 402 } 403 404 DeclarationFragments 405 DeclarationFragmentsBuilder::getFragmentsForFunction(const FunctionDecl *Func) { 406 DeclarationFragments Fragments; 407 // FIXME: Handle template specialization 408 switch (Func->getStorageClass()) { 409 case SC_None: 410 case SC_PrivateExtern: 411 break; 412 case SC_Extern: 413 Fragments.append("extern", DeclarationFragments::FragmentKind::Keyword) 414 .appendSpace(); 415 break; 416 case SC_Static: 417 Fragments.append("static", DeclarationFragments::FragmentKind::Keyword) 418 .appendSpace(); 419 break; 420 case SC_Auto: 421 case SC_Register: 422 llvm_unreachable("invalid for functions"); 423 } 424 // FIXME: Handle C++ function specifiers: constexpr, consteval, explicit, etc. 425 426 // FIXME: Is `after` actually needed here? 427 DeclarationFragments After; 428 Fragments 429 .append(getFragmentsForType(Func->getReturnType(), Func->getASTContext(), 430 After)) 431 .appendSpace() 432 .append(Func->getName(), DeclarationFragments::FragmentKind::Identifier) 433 .append(std::move(After)); 434 435 Fragments.append("(", DeclarationFragments::FragmentKind::Text); 436 for (unsigned i = 0, end = Func->getNumParams(); i != end; ++i) { 437 if (i) 438 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 439 Fragments.append(getFragmentsForParam(Func->getParamDecl(i))); 440 } 441 Fragments.append(")", DeclarationFragments::FragmentKind::Text); 442 443 // FIXME: Handle exception specifiers: throw, noexcept 444 return Fragments; 445 } 446 447 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForEnumConstant( 448 const EnumConstantDecl *EnumConstDecl) { 449 DeclarationFragments Fragments; 450 return Fragments.append(EnumConstDecl->getName(), 451 DeclarationFragments::FragmentKind::Identifier); 452 } 453 454 DeclarationFragments 455 DeclarationFragmentsBuilder::getFragmentsForEnum(const EnumDecl *EnumDecl) { 456 if (const auto *TypedefNameDecl = EnumDecl->getTypedefNameForAnonDecl()) 457 return getFragmentsForTypedef(TypedefNameDecl); 458 459 DeclarationFragments Fragments, After; 460 Fragments.append("enum", DeclarationFragments::FragmentKind::Keyword); 461 462 if (!EnumDecl->getName().empty()) 463 Fragments.appendSpace().append( 464 EnumDecl->getName(), DeclarationFragments::FragmentKind::Identifier); 465 466 QualType IntegerType = EnumDecl->getIntegerType(); 467 if (!IntegerType.isNull()) 468 Fragments.append(": ", DeclarationFragments::FragmentKind::Text) 469 .append( 470 getFragmentsForType(IntegerType, EnumDecl->getASTContext(), After)) 471 .append(std::move(After)); 472 473 return Fragments; 474 } 475 476 DeclarationFragments 477 DeclarationFragmentsBuilder::getFragmentsForField(const FieldDecl *Field) { 478 DeclarationFragments After; 479 return getFragmentsForType(Field->getType(), Field->getASTContext(), After) 480 .appendSpace() 481 .append(Field->getName(), DeclarationFragments::FragmentKind::Identifier) 482 .append(std::move(After)); 483 } 484 485 DeclarationFragments 486 DeclarationFragmentsBuilder::getFragmentsForStruct(const RecordDecl *Record) { 487 if (const auto *TypedefNameDecl = Record->getTypedefNameForAnonDecl()) 488 return getFragmentsForTypedef(TypedefNameDecl); 489 490 DeclarationFragments Fragments; 491 Fragments.append("struct", DeclarationFragments::FragmentKind::Keyword); 492 493 if (!Record->getName().empty()) 494 Fragments.appendSpace().append( 495 Record->getName(), DeclarationFragments::FragmentKind::Identifier); 496 return Fragments; 497 } 498 499 DeclarationFragments 500 DeclarationFragmentsBuilder::getFragmentsForMacro(StringRef Name, 501 const MacroDirective *MD) { 502 DeclarationFragments Fragments; 503 Fragments.append("#define", DeclarationFragments::FragmentKind::Keyword) 504 .appendSpace(); 505 Fragments.append(Name, DeclarationFragments::FragmentKind::Identifier); 506 507 auto *MI = MD->getMacroInfo(); 508 509 if (MI->isFunctionLike()) { 510 Fragments.append("(", DeclarationFragments::FragmentKind::Text); 511 unsigned numParameters = MI->getNumParams(); 512 if (MI->isC99Varargs()) 513 --numParameters; 514 for (unsigned i = 0; i < numParameters; ++i) { 515 if (i) 516 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 517 Fragments.append(MI->params()[i]->getName(), 518 DeclarationFragments::FragmentKind::InternalParam); 519 } 520 if (MI->isVariadic()) { 521 if (numParameters && MI->isC99Varargs()) 522 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 523 Fragments.append("...", DeclarationFragments::FragmentKind::Text); 524 } 525 Fragments.append(")", DeclarationFragments::FragmentKind::Text); 526 } 527 return Fragments; 528 } 529 530 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCCategory( 531 const ObjCCategoryDecl *Category) { 532 DeclarationFragments Fragments; 533 534 auto *Interface = Category->getClassInterface(); 535 SmallString<128> InterfaceUSR; 536 index::generateUSRForDecl(Interface, InterfaceUSR); 537 538 Fragments.append("@interface", DeclarationFragments::FragmentKind::Keyword) 539 .appendSpace() 540 .append(Category->getClassInterface()->getName(), 541 DeclarationFragments::FragmentKind::TypeIdentifier, InterfaceUSR, 542 Interface) 543 .append(" (", DeclarationFragments::FragmentKind::Text) 544 .append(Category->getName(), 545 DeclarationFragments::FragmentKind::Identifier) 546 .append(")", DeclarationFragments::FragmentKind::Text); 547 548 return Fragments; 549 } 550 551 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCInterface( 552 const ObjCInterfaceDecl *Interface) { 553 DeclarationFragments Fragments; 554 // Build the base of the Objective-C interface declaration. 555 Fragments.append("@interface", DeclarationFragments::FragmentKind::Keyword) 556 .appendSpace() 557 .append(Interface->getName(), 558 DeclarationFragments::FragmentKind::Identifier); 559 560 // Build the inheritance part of the declaration. 561 if (const ObjCInterfaceDecl *SuperClass = Interface->getSuperClass()) { 562 SmallString<128> SuperUSR; 563 index::generateUSRForDecl(SuperClass, SuperUSR); 564 Fragments.append(" : ", DeclarationFragments::FragmentKind::Text) 565 .append(SuperClass->getName(), 566 DeclarationFragments::FragmentKind::TypeIdentifier, SuperUSR, 567 SuperClass); 568 } 569 570 return Fragments; 571 } 572 573 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCMethod( 574 const ObjCMethodDecl *Method) { 575 DeclarationFragments Fragments, After; 576 // Build the instance/class method indicator. 577 if (Method->isClassMethod()) 578 Fragments.append("+ ", DeclarationFragments::FragmentKind::Text); 579 else if (Method->isInstanceMethod()) 580 Fragments.append("- ", DeclarationFragments::FragmentKind::Text); 581 582 // Build the return type. 583 Fragments.append("(", DeclarationFragments::FragmentKind::Text) 584 .append(getFragmentsForType(Method->getReturnType(), 585 Method->getASTContext(), After)) 586 .append(std::move(After)) 587 .append(")", DeclarationFragments::FragmentKind::Text); 588 589 // Build the selector part. 590 Selector Selector = Method->getSelector(); 591 if (Selector.getNumArgs() == 0) 592 // For Objective-C methods that don't take arguments, the first (and only) 593 // slot of the selector is the method name. 594 Fragments.appendSpace().append( 595 Selector.getNameForSlot(0), 596 DeclarationFragments::FragmentKind::Identifier); 597 598 // For Objective-C methods that take arguments, build the selector slots. 599 for (unsigned i = 0, end = Method->param_size(); i != end; ++i) { 600 // Objective-C method selector parts are considered as identifiers instead 601 // of "external parameters" as in Swift. This is because Objective-C method 602 // symbols are referenced with the entire selector, instead of just the 603 // method name in Swift. 604 SmallString<32> ParamID(Selector.getNameForSlot(i)); 605 ParamID.append(":"); 606 Fragments.appendSpace().append( 607 ParamID, DeclarationFragments::FragmentKind::Identifier); 608 609 // Build the internal parameter. 610 const ParmVarDecl *Param = Method->getParamDecl(i); 611 Fragments.append(getFragmentsForParam(Param)); 612 } 613 614 return Fragments.append(";", DeclarationFragments::FragmentKind::Text); 615 } 616 617 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProperty( 618 const ObjCPropertyDecl *Property) { 619 DeclarationFragments Fragments, After; 620 621 // Build the Objective-C property keyword. 622 Fragments.append("@property", DeclarationFragments::FragmentKind::Keyword); 623 624 const auto Attributes = Property->getPropertyAttributes(); 625 // Build the attributes if there is any associated with the property. 626 if (Attributes != ObjCPropertyAttribute::kind_noattr) { 627 // No leading comma for the first attribute. 628 bool First = true; 629 Fragments.append(" (", DeclarationFragments::FragmentKind::Text); 630 // Helper function to render the attribute. 631 auto RenderAttribute = 632 [&](ObjCPropertyAttribute::Kind Kind, StringRef Spelling, 633 StringRef Arg = "", 634 DeclarationFragments::FragmentKind ArgKind = 635 DeclarationFragments::FragmentKind::Identifier) { 636 // Check if the `Kind` attribute is set for this property. 637 if ((Attributes & Kind) && !Spelling.empty()) { 638 // Add a leading comma if this is not the first attribute rendered. 639 if (!First) 640 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 641 // Render the spelling of this attribute `Kind` as a keyword. 642 Fragments.append(Spelling, 643 DeclarationFragments::FragmentKind::Keyword); 644 // If this attribute takes in arguments (e.g. `getter=getterName`), 645 // render the arguments. 646 if (!Arg.empty()) 647 Fragments.append("=", DeclarationFragments::FragmentKind::Text) 648 .append(Arg, ArgKind); 649 First = false; 650 } 651 }; 652 653 // Go through all possible Objective-C property attributes and render set 654 // ones. 655 RenderAttribute(ObjCPropertyAttribute::kind_class, "class"); 656 RenderAttribute(ObjCPropertyAttribute::kind_direct, "direct"); 657 RenderAttribute(ObjCPropertyAttribute::kind_nonatomic, "nonatomic"); 658 RenderAttribute(ObjCPropertyAttribute::kind_atomic, "atomic"); 659 RenderAttribute(ObjCPropertyAttribute::kind_assign, "assign"); 660 RenderAttribute(ObjCPropertyAttribute::kind_retain, "retain"); 661 RenderAttribute(ObjCPropertyAttribute::kind_strong, "strong"); 662 RenderAttribute(ObjCPropertyAttribute::kind_copy, "copy"); 663 RenderAttribute(ObjCPropertyAttribute::kind_weak, "weak"); 664 RenderAttribute(ObjCPropertyAttribute::kind_unsafe_unretained, 665 "unsafe_unretained"); 666 RenderAttribute(ObjCPropertyAttribute::kind_readwrite, "readwrite"); 667 RenderAttribute(ObjCPropertyAttribute::kind_readonly, "readonly"); 668 RenderAttribute(ObjCPropertyAttribute::kind_getter, "getter", 669 Property->getGetterName().getAsString()); 670 RenderAttribute(ObjCPropertyAttribute::kind_setter, "setter", 671 Property->getSetterName().getAsString()); 672 673 // Render nullability attributes. 674 if (Attributes & ObjCPropertyAttribute::kind_nullability) { 675 QualType Type = Property->getType(); 676 if (const auto Nullability = 677 AttributedType::stripOuterNullability(Type)) { 678 if (!First) 679 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 680 if (*Nullability == NullabilityKind::Unspecified && 681 (Attributes & ObjCPropertyAttribute::kind_null_resettable)) 682 Fragments.append("null_resettable", 683 DeclarationFragments::FragmentKind::Keyword); 684 else 685 Fragments.append( 686 getNullabilitySpelling(*Nullability, /*isContextSensitive=*/true), 687 DeclarationFragments::FragmentKind::Keyword); 688 First = false; 689 } 690 } 691 692 Fragments.append(")", DeclarationFragments::FragmentKind::Text); 693 } 694 695 // Build the property type and name, and return the completed fragments. 696 return Fragments.appendSpace() 697 .append(getFragmentsForType(Property->getType(), 698 Property->getASTContext(), After)) 699 .appendSpace() 700 .append(Property->getName(), 701 DeclarationFragments::FragmentKind::Identifier) 702 .append(std::move(After)); 703 } 704 705 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProtocol( 706 const ObjCProtocolDecl *Protocol) { 707 DeclarationFragments Fragments; 708 // Build basic protocol declaration. 709 Fragments.append("@protocol", DeclarationFragments::FragmentKind::Keyword) 710 .appendSpace() 711 .append(Protocol->getName(), 712 DeclarationFragments::FragmentKind::Identifier); 713 714 // If this protocol conforms to other protocols, build the conformance list. 715 if (!Protocol->protocols().empty()) { 716 Fragments.append(" <", DeclarationFragments::FragmentKind::Text); 717 for (ObjCProtocolDecl::protocol_iterator It = Protocol->protocol_begin(); 718 It != Protocol->protocol_end(); It++) { 719 // Add a leading comma if this is not the first protocol rendered. 720 if (It != Protocol->protocol_begin()) 721 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 722 723 SmallString<128> USR; 724 index::generateUSRForDecl(*It, USR); 725 Fragments.append((*It)->getName(), 726 DeclarationFragments::FragmentKind::TypeIdentifier, USR, 727 *It); 728 } 729 Fragments.append(">", DeclarationFragments::FragmentKind::Text); 730 } 731 732 return Fragments; 733 } 734 735 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForTypedef( 736 const TypedefNameDecl *Decl) { 737 DeclarationFragments Fragments, After; 738 Fragments.append("typedef", DeclarationFragments::FragmentKind::Keyword) 739 .appendSpace() 740 .append(getFragmentsForType(Decl->getUnderlyingType(), 741 Decl->getASTContext(), After)) 742 .append(std::move(After)) 743 .appendSpace() 744 .append(Decl->getName(), DeclarationFragments::FragmentKind::Identifier); 745 746 return Fragments; 747 } 748 749 template <typename FunctionT> 750 FunctionSignature 751 DeclarationFragmentsBuilder::getFunctionSignature(const FunctionT *Function) { 752 FunctionSignature Signature; 753 754 DeclarationFragments ReturnType, After; 755 ReturnType 756 .append(getFragmentsForType(Function->getReturnType(), 757 Function->getASTContext(), After)) 758 .append(std::move(After)); 759 Signature.setReturnType(ReturnType); 760 761 for (const auto *Param : Function->parameters()) 762 Signature.addParameter(Param->getName(), getFragmentsForParam(Param)); 763 764 return Signature; 765 } 766 767 // Instantiate template for FunctionDecl. 768 template FunctionSignature 769 DeclarationFragmentsBuilder::getFunctionSignature(const FunctionDecl *); 770 771 // Instantiate template for ObjCMethodDecl. 772 template FunctionSignature 773 DeclarationFragmentsBuilder::getFunctionSignature(const ObjCMethodDecl *); 774 775 // Subheading of a symbol defaults to its name. 776 DeclarationFragments 777 DeclarationFragmentsBuilder::getSubHeading(const NamedDecl *Decl) { 778 DeclarationFragments Fragments; 779 if (!Decl->getName().empty()) 780 Fragments.append(Decl->getName(), 781 DeclarationFragments::FragmentKind::Identifier); 782 return Fragments; 783 } 784 785 // Subheading of an Objective-C method is a `+` or `-` sign indicating whether 786 // it's a class method or an instance method, followed by the selector name. 787 DeclarationFragments 788 DeclarationFragmentsBuilder::getSubHeading(const ObjCMethodDecl *Method) { 789 DeclarationFragments Fragments; 790 if (Method->isClassMethod()) 791 Fragments.append("+ ", DeclarationFragments::FragmentKind::Text); 792 else if (Method->isInstanceMethod()) 793 Fragments.append("- ", DeclarationFragments::FragmentKind::Text); 794 795 return Fragments.append(Method->getNameAsString(), 796 DeclarationFragments::FragmentKind::Identifier); 797 } 798 799 // Subheading of a symbol defaults to its name. 800 DeclarationFragments 801 DeclarationFragmentsBuilder::getSubHeadingForMacro(StringRef Name) { 802 DeclarationFragments Fragments; 803 Fragments.append(Name, DeclarationFragments::FragmentKind::Identifier); 804 return Fragments; 805 } 806