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