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