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 ArraySizeModifier::Normal: 270 break; 271 case ArraySizeModifier::Static: 272 Fragments.append("static", DeclarationFragments::FragmentKind::Keyword); 273 break; 274 case ArraySizeModifier::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 (QT.getAsString() == "_Bool") 401 TypeFragments.replace("bool", 0); 402 403 if (QualsFragments.getFragments().empty()) 404 return TypeFragments; 405 406 // Use east qualifier for pointer types 407 // For example: 408 // ``` 409 // int * const 410 // ^---- ^---- 411 // type qualifier 412 // ^----------------- 413 // const pointer to int 414 // ``` 415 // should not be reconstructed as 416 // ``` 417 // const int * 418 // ^---- ^-- 419 // qualifier type 420 // ^---------------- ^ 421 // pointer to const int 422 // ``` 423 if (SQT.Ty->isAnyPointerType()) 424 return TypeFragments.appendSpace().append(std::move(QualsFragments)); 425 426 return QualsFragments.appendSpace().append(std::move(TypeFragments)); 427 } 428 429 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForNamespace( 430 const NamespaceDecl *Decl) { 431 DeclarationFragments Fragments; 432 Fragments.append("namespace", DeclarationFragments::FragmentKind::Keyword); 433 if (!Decl->isAnonymousNamespace()) 434 Fragments.appendSpace().append( 435 Decl->getName(), DeclarationFragments::FragmentKind::Identifier); 436 return Fragments.append(";", DeclarationFragments::FragmentKind::Text); 437 } 438 439 DeclarationFragments 440 DeclarationFragmentsBuilder::getFragmentsForVar(const VarDecl *Var) { 441 DeclarationFragments Fragments; 442 if (Var->isConstexpr()) 443 Fragments.append("constexpr", DeclarationFragments::FragmentKind::Keyword) 444 .appendSpace(); 445 446 StorageClass SC = Var->getStorageClass(); 447 if (SC != SC_None) 448 Fragments 449 .append(VarDecl::getStorageClassSpecifierString(SC), 450 DeclarationFragments::FragmentKind::Keyword) 451 .appendSpace(); 452 QualType T = 453 Var->getTypeSourceInfo() 454 ? Var->getTypeSourceInfo()->getType() 455 : Var->getASTContext().getUnqualifiedObjCPointerType(Var->getType()); 456 457 // Capture potential fragments that needs to be placed after the variable name 458 // ``` 459 // int nums[5]; 460 // char (*ptr_to_array)[6]; 461 // ``` 462 DeclarationFragments After; 463 return Fragments.append(getFragmentsForType(T, Var->getASTContext(), After)) 464 .appendSpace() 465 .append(Var->getName(), DeclarationFragments::FragmentKind::Identifier) 466 .append(std::move(After)) 467 .append(";", DeclarationFragments::FragmentKind::Text); 468 } 469 470 DeclarationFragments 471 DeclarationFragmentsBuilder::getFragmentsForVarTemplate(const VarDecl *Var) { 472 DeclarationFragments Fragments; 473 if (Var->isConstexpr()) 474 Fragments.append("constexpr", DeclarationFragments::FragmentKind::Keyword) 475 .appendSpace(); 476 QualType T = 477 Var->getTypeSourceInfo() 478 ? Var->getTypeSourceInfo()->getType() 479 : Var->getASTContext().getUnqualifiedObjCPointerType(Var->getType()); 480 481 // Might be a member, so might be static. 482 if (Var->isStaticDataMember()) 483 Fragments.append("static", DeclarationFragments::FragmentKind::Keyword) 484 .appendSpace(); 485 486 DeclarationFragments After; 487 DeclarationFragments ArgumentFragment = 488 getFragmentsForType(T, Var->getASTContext(), After); 489 if (ArgumentFragment.begin()->Spelling.substr(0, 14).compare( 490 "type-parameter") == 0) { 491 std::string ProperArgName = getNameForTemplateArgument( 492 Var->getDescribedVarTemplate()->getTemplateParameters()->asArray(), 493 ArgumentFragment.begin()->Spelling); 494 ArgumentFragment.begin()->Spelling.swap(ProperArgName); 495 } 496 Fragments.append(std::move(ArgumentFragment)) 497 .appendSpace() 498 .append(Var->getName(), DeclarationFragments::FragmentKind::Identifier) 499 .append(";", DeclarationFragments::FragmentKind::Text); 500 return Fragments; 501 } 502 503 DeclarationFragments 504 DeclarationFragmentsBuilder::getFragmentsForParam(const ParmVarDecl *Param) { 505 DeclarationFragments Fragments, After; 506 507 QualType T = Param->getTypeSourceInfo() 508 ? Param->getTypeSourceInfo()->getType() 509 : Param->getASTContext().getUnqualifiedObjCPointerType( 510 Param->getType()); 511 512 DeclarationFragments TypeFragments = 513 getFragmentsForType(T, Param->getASTContext(), After); 514 if (TypeFragments.begin()->Spelling.substr(0, 14).compare("type-parameter") == 515 0) { 516 std::string ProperArgName = getNameForTemplateArgument( 517 dyn_cast<FunctionDecl>(Param->getDeclContext()) 518 ->getDescribedFunctionTemplate() 519 ->getTemplateParameters() 520 ->asArray(), 521 TypeFragments.begin()->Spelling); 522 TypeFragments.begin()->Spelling.swap(ProperArgName); 523 } 524 525 if (Param->isObjCMethodParameter()) 526 Fragments.append("(", DeclarationFragments::FragmentKind::Text) 527 .append(std::move(TypeFragments)) 528 .append(") ", DeclarationFragments::FragmentKind::Text); 529 else 530 Fragments.append(std::move(TypeFragments)).appendSpace(); 531 532 return Fragments 533 .append(Param->getName(), 534 DeclarationFragments::FragmentKind::InternalParam) 535 .append(std::move(After)); 536 } 537 538 DeclarationFragments 539 DeclarationFragmentsBuilder::getFragmentsForFunction(const FunctionDecl *Func) { 540 DeclarationFragments Fragments; 541 // FIXME: Handle template specialization 542 switch (Func->getStorageClass()) { 543 case SC_None: 544 case SC_PrivateExtern: 545 break; 546 case SC_Extern: 547 Fragments.append("extern", DeclarationFragments::FragmentKind::Keyword) 548 .appendSpace(); 549 break; 550 case SC_Static: 551 Fragments.append("static", DeclarationFragments::FragmentKind::Keyword) 552 .appendSpace(); 553 break; 554 case SC_Auto: 555 case SC_Register: 556 llvm_unreachable("invalid for functions"); 557 } 558 if (Func->isConsteval()) // if consteval, it is also constexpr 559 Fragments.append("consteval", DeclarationFragments::FragmentKind::Keyword) 560 .appendSpace(); 561 else if (Func->isConstexpr()) 562 Fragments.append("constexpr", DeclarationFragments::FragmentKind::Keyword) 563 .appendSpace(); 564 565 // FIXME: Is `after` actually needed here? 566 DeclarationFragments After; 567 auto ReturnValueFragment = 568 getFragmentsForType(Func->getReturnType(), Func->getASTContext(), After); 569 if (ReturnValueFragment.begin()->Spelling.substr(0, 14).compare( 570 "type-parameter") == 0) { 571 std::string ProperArgName = 572 getNameForTemplateArgument(Func->getDescribedFunctionTemplate() 573 ->getTemplateParameters() 574 ->asArray(), 575 ReturnValueFragment.begin()->Spelling); 576 ReturnValueFragment.begin()->Spelling.swap(ProperArgName); 577 } 578 579 Fragments.append(std::move(ReturnValueFragment)) 580 .appendSpace() 581 .append(Func->getName(), DeclarationFragments::FragmentKind::Identifier); 582 583 if (Func->getTemplateSpecializationInfo()) { 584 Fragments.append("<", DeclarationFragments::FragmentKind::Text); 585 586 for (unsigned i = 0, end = Func->getNumParams(); i != end; ++i) { 587 if (i) 588 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 589 Fragments.append( 590 getFragmentsForType(Func->getParamDecl(i)->getType(), 591 Func->getParamDecl(i)->getASTContext(), After)); 592 } 593 Fragments.append(">", DeclarationFragments::FragmentKind::Text); 594 } 595 Fragments.append(std::move(After)); 596 597 Fragments.append("(", DeclarationFragments::FragmentKind::Text); 598 for (unsigned i = 0, end = Func->getNumParams(); i != end; ++i) { 599 if (i) 600 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 601 Fragments.append(getFragmentsForParam(Func->getParamDecl(i))); 602 } 603 Fragments.append(")", DeclarationFragments::FragmentKind::Text); 604 605 Fragments.append(DeclarationFragments::getExceptionSpecificationString( 606 Func->getExceptionSpecType())); 607 608 return Fragments.append(";", DeclarationFragments::FragmentKind::Text); 609 } 610 611 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForEnumConstant( 612 const EnumConstantDecl *EnumConstDecl) { 613 DeclarationFragments Fragments; 614 return Fragments.append(EnumConstDecl->getName(), 615 DeclarationFragments::FragmentKind::Identifier); 616 } 617 618 DeclarationFragments 619 DeclarationFragmentsBuilder::getFragmentsForEnum(const EnumDecl *EnumDecl) { 620 if (const auto *TypedefNameDecl = EnumDecl->getTypedefNameForAnonDecl()) 621 return getFragmentsForTypedef(TypedefNameDecl); 622 623 DeclarationFragments Fragments, After; 624 Fragments.append("enum", DeclarationFragments::FragmentKind::Keyword); 625 626 if (!EnumDecl->getName().empty()) 627 Fragments.appendSpace().append( 628 EnumDecl->getName(), DeclarationFragments::FragmentKind::Identifier); 629 630 QualType IntegerType = EnumDecl->getIntegerType(); 631 if (!IntegerType.isNull()) 632 Fragments.append(": ", DeclarationFragments::FragmentKind::Text) 633 .append( 634 getFragmentsForType(IntegerType, EnumDecl->getASTContext(), After)) 635 .append(std::move(After)); 636 637 return Fragments.append(";", DeclarationFragments::FragmentKind::Text); 638 } 639 640 DeclarationFragments 641 DeclarationFragmentsBuilder::getFragmentsForField(const FieldDecl *Field) { 642 DeclarationFragments After; 643 DeclarationFragments Fragments; 644 if (Field->isMutable()) 645 Fragments.append("mutable", DeclarationFragments::FragmentKind::Keyword) 646 .appendSpace(); 647 return Fragments 648 .append( 649 getFragmentsForType(Field->getType(), Field->getASTContext(), After)) 650 .appendSpace() 651 .append(Field->getName(), DeclarationFragments::FragmentKind::Identifier) 652 .append(std::move(After)) 653 .append(";", DeclarationFragments::FragmentKind::Text); 654 } 655 656 DeclarationFragments 657 DeclarationFragmentsBuilder::getFragmentsForStruct(const RecordDecl *Record) { 658 if (const auto *TypedefNameDecl = Record->getTypedefNameForAnonDecl()) 659 return getFragmentsForTypedef(TypedefNameDecl); 660 661 DeclarationFragments Fragments; 662 Fragments.append("struct", DeclarationFragments::FragmentKind::Keyword); 663 664 if (!Record->getName().empty()) 665 Fragments.appendSpace().append( 666 Record->getName(), DeclarationFragments::FragmentKind::Identifier); 667 668 return Fragments.append(";", DeclarationFragments::FragmentKind::Text); 669 } 670 671 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForCXXClass( 672 const CXXRecordDecl *Record) { 673 if (const auto *TypedefNameDecl = Record->getTypedefNameForAnonDecl()) 674 return getFragmentsForTypedef(TypedefNameDecl); 675 676 DeclarationFragments Fragments; 677 Fragments.append(DeclarationFragments::getStructureTypeFragment(Record)); 678 679 if (!Record->getName().empty()) 680 Fragments.appendSpace().append( 681 Record->getName(), DeclarationFragments::FragmentKind::Identifier); 682 683 return Fragments.append(";", DeclarationFragments::FragmentKind::Text); 684 } 685 686 DeclarationFragments 687 DeclarationFragmentsBuilder::getFragmentsForSpecialCXXMethod( 688 const CXXMethodDecl *Method) { 689 DeclarationFragments Fragments; 690 std::string Name; 691 if (const auto *Constructor = dyn_cast<CXXConstructorDecl>(Method)) { 692 Name = Method->getNameAsString(); 693 if (Constructor->isExplicit()) 694 Fragments.append("explicit", DeclarationFragments::FragmentKind::Keyword) 695 .appendSpace(); 696 } else if (isa<CXXDestructorDecl>(Method)) 697 Name = Method->getNameAsString(); 698 699 DeclarationFragments After; 700 Fragments.append(Name, DeclarationFragments::FragmentKind::Identifier) 701 .append(std::move(After)); 702 Fragments.append("(", DeclarationFragments::FragmentKind::Text); 703 for (unsigned i = 0, end = Method->getNumParams(); i != end; ++i) { 704 if (i) 705 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 706 Fragments.append(getFragmentsForParam(Method->getParamDecl(i))); 707 } 708 Fragments.append(")", DeclarationFragments::FragmentKind::Text); 709 710 Fragments.append(DeclarationFragments::getExceptionSpecificationString( 711 Method->getExceptionSpecType())); 712 713 return Fragments.append(";", DeclarationFragments::FragmentKind::Text); 714 } 715 716 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForCXXMethod( 717 const CXXMethodDecl *Method) { 718 DeclarationFragments Fragments; 719 StringRef Name = Method->getName(); 720 if (Method->isStatic()) 721 Fragments.append("static", DeclarationFragments::FragmentKind::Keyword) 722 .appendSpace(); 723 if (Method->isConstexpr()) 724 Fragments.append("constexpr", DeclarationFragments::FragmentKind::Keyword) 725 .appendSpace(); 726 if (Method->isVolatile()) 727 Fragments.append("volatile", DeclarationFragments::FragmentKind::Keyword) 728 .appendSpace(); 729 730 // Build return type 731 DeclarationFragments After; 732 Fragments 733 .append(getFragmentsForType(Method->getReturnType(), 734 Method->getASTContext(), After)) 735 .appendSpace() 736 .append(Name, DeclarationFragments::FragmentKind::Identifier) 737 .append(std::move(After)); 738 Fragments.append("(", DeclarationFragments::FragmentKind::Text); 739 for (unsigned i = 0, end = Method->getNumParams(); i != end; ++i) { 740 if (i) 741 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 742 Fragments.append(getFragmentsForParam(Method->getParamDecl(i))); 743 } 744 Fragments.append(")", DeclarationFragments::FragmentKind::Text); 745 746 if (Method->isConst()) 747 Fragments.appendSpace().append("const", 748 DeclarationFragments::FragmentKind::Keyword); 749 750 Fragments.append(DeclarationFragments::getExceptionSpecificationString( 751 Method->getExceptionSpecType())); 752 753 return Fragments.append(";", DeclarationFragments::FragmentKind::Text); 754 } 755 756 DeclarationFragments 757 DeclarationFragmentsBuilder::getFragmentsForConversionFunction( 758 const CXXConversionDecl *ConversionFunction) { 759 DeclarationFragments Fragments; 760 761 if (ConversionFunction->isExplicit()) 762 Fragments.append("explicit", DeclarationFragments::FragmentKind::Keyword) 763 .appendSpace(); 764 765 Fragments.append("operator", DeclarationFragments::FragmentKind::Keyword) 766 .appendSpace(); 767 768 Fragments 769 .append(ConversionFunction->getConversionType().getAsString(), 770 DeclarationFragments::FragmentKind::TypeIdentifier) 771 .append("(", DeclarationFragments::FragmentKind::Text); 772 for (unsigned i = 0, end = ConversionFunction->getNumParams(); i != end; 773 ++i) { 774 if (i) 775 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 776 Fragments.append(getFragmentsForParam(ConversionFunction->getParamDecl(i))); 777 } 778 Fragments.append(")", DeclarationFragments::FragmentKind::Text); 779 780 if (ConversionFunction->isConst()) 781 Fragments.appendSpace().append("const", 782 DeclarationFragments::FragmentKind::Keyword); 783 784 return Fragments.append(";", DeclarationFragments::FragmentKind::Text); 785 } 786 787 DeclarationFragments 788 DeclarationFragmentsBuilder::getFragmentsForOverloadedOperator( 789 const CXXMethodDecl *Method) { 790 DeclarationFragments Fragments; 791 792 // Build return type 793 DeclarationFragments After; 794 Fragments 795 .append(getFragmentsForType(Method->getReturnType(), 796 Method->getASTContext(), After)) 797 .appendSpace() 798 .append(Method->getNameAsString(), 799 DeclarationFragments::FragmentKind::Identifier) 800 .append(std::move(After)); 801 Fragments.append("(", DeclarationFragments::FragmentKind::Text); 802 for (unsigned i = 0, end = Method->getNumParams(); i != end; ++i) { 803 if (i) 804 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 805 Fragments.append(getFragmentsForParam(Method->getParamDecl(i))); 806 } 807 Fragments.append(")", DeclarationFragments::FragmentKind::Text); 808 809 if (Method->isConst()) 810 Fragments.appendSpace().append("const", 811 DeclarationFragments::FragmentKind::Keyword); 812 813 Fragments.append(DeclarationFragments::getExceptionSpecificationString( 814 Method->getExceptionSpecType())); 815 816 return Fragments.append(";", DeclarationFragments::FragmentKind::Text); 817 } 818 819 // Get fragments for template parameters, e.g. T in tempalte<typename T> ... 820 DeclarationFragments 821 DeclarationFragmentsBuilder::getFragmentsForTemplateParameters( 822 ArrayRef<NamedDecl *> ParameterArray) { 823 DeclarationFragments Fragments; 824 for (unsigned i = 0, end = ParameterArray.size(); i != end; ++i) { 825 if (i) 826 Fragments.append(",", DeclarationFragments::FragmentKind::Text) 827 .appendSpace(); 828 829 const auto *TemplateParam = 830 dyn_cast<TemplateTypeParmDecl>(ParameterArray[i]); 831 if (!TemplateParam) 832 continue; 833 if (TemplateParam->hasTypeConstraint()) 834 Fragments.append(TemplateParam->getTypeConstraint() 835 ->getNamedConcept() 836 ->getName() 837 .str(), 838 DeclarationFragments::FragmentKind::TypeIdentifier); 839 else if (TemplateParam->wasDeclaredWithTypename()) 840 Fragments.append("typename", DeclarationFragments::FragmentKind::Keyword); 841 else 842 Fragments.append("class", DeclarationFragments::FragmentKind::Keyword); 843 844 if (TemplateParam->isParameterPack()) 845 Fragments.append("...", DeclarationFragments::FragmentKind::Text); 846 847 Fragments.appendSpace().append( 848 TemplateParam->getName(), 849 DeclarationFragments::FragmentKind::GenericParameter); 850 } 851 return Fragments; 852 } 853 854 // Find the name of a template argument from the template's parameters. 855 std::string DeclarationFragmentsBuilder::getNameForTemplateArgument( 856 const ArrayRef<NamedDecl *> TemplateParameters, std::string TypeParameter) { 857 // The arg is a generic parameter from a partial spec, e.g. 858 // T in template<typename T> Foo<T, int>. 859 // 860 // Those names appear as "type-parameter-<index>-<depth>", so we must find its 861 // name from the template's parameter list. 862 for (unsigned i = 0; i < TemplateParameters.size(); ++i) { 863 const auto *Parameter = 864 dyn_cast<TemplateTypeParmDecl>(TemplateParameters[i]); 865 if (TypeParameter.compare("type-parameter-" + 866 std::to_string(Parameter->getDepth()) + "-" + 867 std::to_string(Parameter->getIndex())) == 0) 868 return std::string(TemplateParameters[i]->getName()); 869 } 870 llvm_unreachable("Could not find the name of a template argument."); 871 } 872 873 // Get fragments for template arguments, e.g. int in template<typename T> 874 // Foo<int>; 875 // 876 // Note: TemplateParameters is only necessary if the Decl is a 877 // PartialSpecialization, where we need the parameters to deduce the name of the 878 // generic arguments. 879 DeclarationFragments 880 DeclarationFragmentsBuilder::getFragmentsForTemplateArguments( 881 const ArrayRef<TemplateArgument> TemplateArguments, ASTContext &Context, 882 const std::optional<ArrayRef<NamedDecl *>> TemplateParameters) { 883 DeclarationFragments Fragments; 884 for (unsigned i = 0, end = TemplateArguments.size(); i != end; ++i) { 885 if (i) 886 Fragments.append(",", DeclarationFragments::FragmentKind::Text) 887 .appendSpace(); 888 889 std::string Type = TemplateArguments[i].getAsType().getAsString(); 890 DeclarationFragments After; 891 DeclarationFragments ArgumentFragment = 892 getFragmentsForType(TemplateArguments[i].getAsType(), Context, After); 893 894 if (ArgumentFragment.begin()->Spelling.substr(0, 14).compare( 895 "type-parameter") == 0) { 896 std::string ProperArgName = getNameForTemplateArgument( 897 TemplateParameters.value(), ArgumentFragment.begin()->Spelling); 898 ArgumentFragment.begin()->Spelling.swap(ProperArgName); 899 } 900 Fragments.append(std::move(ArgumentFragment)); 901 902 if (TemplateArguments[i].isPackExpansion()) 903 Fragments.append("...", DeclarationFragments::FragmentKind::Text); 904 } 905 return Fragments; 906 } 907 908 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForConcept( 909 const ConceptDecl *Concept) { 910 DeclarationFragments Fragments; 911 return Fragments 912 .append("template", DeclarationFragments::FragmentKind::Keyword) 913 .append("<", DeclarationFragments::FragmentKind::Text) 914 .append(getFragmentsForTemplateParameters( 915 Concept->getTemplateParameters()->asArray())) 916 .append("> ", DeclarationFragments::FragmentKind::Text) 917 .append("concept", DeclarationFragments::FragmentKind::Keyword) 918 .appendSpace() 919 .append(Concept->getName().str(), 920 DeclarationFragments::FragmentKind::Identifier) 921 .append(";", DeclarationFragments::FragmentKind::Text); 922 } 923 924 DeclarationFragments 925 DeclarationFragmentsBuilder::getFragmentsForRedeclarableTemplate( 926 const RedeclarableTemplateDecl *RedeclarableTemplate) { 927 DeclarationFragments Fragments; 928 Fragments.append("template", DeclarationFragments::FragmentKind::Keyword) 929 .append("<", DeclarationFragments::FragmentKind::Text) 930 .append(getFragmentsForTemplateParameters( 931 RedeclarableTemplate->getTemplateParameters()->asArray())) 932 .append(">", DeclarationFragments::FragmentKind::Text) 933 .appendSpace(); 934 935 if (isa<TypeAliasTemplateDecl>(RedeclarableTemplate)) 936 Fragments.appendSpace() 937 .append("using", DeclarationFragments::FragmentKind::Keyword) 938 .appendSpace() 939 .append(RedeclarableTemplate->getName(), 940 DeclarationFragments::FragmentKind::Identifier); 941 // the templated records will be resposbible for injecting their templates 942 return Fragments.appendSpace(); 943 } 944 945 DeclarationFragments 946 DeclarationFragmentsBuilder::getFragmentsForClassTemplateSpecialization( 947 const ClassTemplateSpecializationDecl *Decl) { 948 DeclarationFragments Fragments; 949 return Fragments 950 .append("template", DeclarationFragments::FragmentKind::Keyword) 951 .append("<", DeclarationFragments::FragmentKind::Text) 952 .append(">", DeclarationFragments::FragmentKind::Text) 953 .appendSpace() 954 .append(DeclarationFragmentsBuilder::getFragmentsForCXXClass( 955 cast<CXXRecordDecl>(Decl))) 956 .pop_back() // there is an extra semicolon now 957 .append("<", DeclarationFragments::FragmentKind::Text) 958 .append( 959 getFragmentsForTemplateArguments(Decl->getTemplateArgs().asArray(), 960 Decl->getASTContext(), std::nullopt)) 961 .append(">", DeclarationFragments::FragmentKind::Text) 962 .append(";", DeclarationFragments::FragmentKind::Text); 963 } 964 965 DeclarationFragments 966 DeclarationFragmentsBuilder::getFragmentsForClassTemplatePartialSpecialization( 967 const ClassTemplatePartialSpecializationDecl *Decl) { 968 DeclarationFragments Fragments; 969 return Fragments 970 .append("template", DeclarationFragments::FragmentKind::Keyword) 971 .append("<", DeclarationFragments::FragmentKind::Text) 972 .append(getFragmentsForTemplateParameters( 973 Decl->getTemplateParameters()->asArray())) 974 .append(">", DeclarationFragments::FragmentKind::Text) 975 .appendSpace() 976 .append(DeclarationFragmentsBuilder::getFragmentsForCXXClass( 977 cast<CXXRecordDecl>(Decl))) 978 .pop_back() // there is an extra semicolon now 979 .append("<", DeclarationFragments::FragmentKind::Text) 980 .append(getFragmentsForTemplateArguments( 981 Decl->getTemplateArgs().asArray(), Decl->getASTContext(), 982 Decl->getTemplateParameters()->asArray())) 983 .append(">", DeclarationFragments::FragmentKind::Text) 984 .append(";", DeclarationFragments::FragmentKind::Text); 985 } 986 987 DeclarationFragments 988 DeclarationFragmentsBuilder::getFragmentsForVarTemplateSpecialization( 989 const VarTemplateSpecializationDecl *Decl) { 990 DeclarationFragments Fragments; 991 return Fragments 992 .append("template", DeclarationFragments::FragmentKind::Keyword) 993 .append("<", DeclarationFragments::FragmentKind::Text) 994 .append(">", DeclarationFragments::FragmentKind::Text) 995 .appendSpace() 996 .append(DeclarationFragmentsBuilder::getFragmentsForVarTemplate(Decl)) 997 .pop_back() // there is an extra semicolon now 998 .append("<", DeclarationFragments::FragmentKind::Text) 999 .append( 1000 getFragmentsForTemplateArguments(Decl->getTemplateArgs().asArray(), 1001 Decl->getASTContext(), std::nullopt)) 1002 .append(">", DeclarationFragments::FragmentKind::Text) 1003 .append(";", DeclarationFragments::FragmentKind::Text); 1004 } 1005 1006 DeclarationFragments 1007 DeclarationFragmentsBuilder::getFragmentsForVarTemplatePartialSpecialization( 1008 const VarTemplatePartialSpecializationDecl *Decl) { 1009 DeclarationFragments Fragments; 1010 return Fragments 1011 .append("template", DeclarationFragments::FragmentKind::Keyword) 1012 .append("<", DeclarationFragments::FragmentKind::Text) 1013 // Partial specs may have new params. 1014 .append(getFragmentsForTemplateParameters( 1015 Decl->getTemplateParameters()->asArray())) 1016 .append(">", DeclarationFragments::FragmentKind::Text) 1017 .appendSpace() 1018 .append(DeclarationFragmentsBuilder::getFragmentsForVarTemplate(Decl)) 1019 .pop_back() // there is an extra semicolon now 1020 .append("<", DeclarationFragments::FragmentKind::Text) 1021 .append(getFragmentsForTemplateArguments( 1022 Decl->getTemplateArgs().asArray(), Decl->getASTContext(), 1023 Decl->getTemplateParameters()->asArray())) 1024 .append(">", DeclarationFragments::FragmentKind::Text) 1025 .append(";", DeclarationFragments::FragmentKind::Text); 1026 } 1027 1028 DeclarationFragments 1029 DeclarationFragmentsBuilder::getFragmentsForFunctionTemplate( 1030 const FunctionTemplateDecl *Decl) { 1031 DeclarationFragments Fragments; 1032 return Fragments 1033 .append("template", DeclarationFragments::FragmentKind::Keyword) 1034 .append("<", DeclarationFragments::FragmentKind::Text) 1035 // Partial specs may have new params. 1036 .append(getFragmentsForTemplateParameters( 1037 Decl->getTemplateParameters()->asArray())) 1038 .append(">", DeclarationFragments::FragmentKind::Text) 1039 .appendSpace() 1040 .append(DeclarationFragmentsBuilder::getFragmentsForFunction( 1041 Decl->getAsFunction())); 1042 } 1043 1044 DeclarationFragments 1045 DeclarationFragmentsBuilder::getFragmentsForFunctionTemplateSpecialization( 1046 const FunctionDecl *Decl) { 1047 DeclarationFragments Fragments; 1048 return Fragments 1049 .append("template", DeclarationFragments::FragmentKind::Keyword) 1050 .append("<>", DeclarationFragments::FragmentKind::Text) 1051 .appendSpace() 1052 .append(DeclarationFragmentsBuilder::getFragmentsForFunction(Decl)); 1053 } 1054 1055 DeclarationFragments 1056 DeclarationFragmentsBuilder::getFragmentsForMacro(StringRef Name, 1057 const MacroDirective *MD) { 1058 DeclarationFragments Fragments; 1059 Fragments.append("#define", DeclarationFragments::FragmentKind::Keyword) 1060 .appendSpace(); 1061 Fragments.append(Name, DeclarationFragments::FragmentKind::Identifier); 1062 1063 auto *MI = MD->getMacroInfo(); 1064 1065 if (MI->isFunctionLike()) { 1066 Fragments.append("(", DeclarationFragments::FragmentKind::Text); 1067 unsigned numParameters = MI->getNumParams(); 1068 if (MI->isC99Varargs()) 1069 --numParameters; 1070 for (unsigned i = 0; i < numParameters; ++i) { 1071 if (i) 1072 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 1073 Fragments.append(MI->params()[i]->getName(), 1074 DeclarationFragments::FragmentKind::InternalParam); 1075 } 1076 if (MI->isVariadic()) { 1077 if (numParameters && MI->isC99Varargs()) 1078 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 1079 Fragments.append("...", DeclarationFragments::FragmentKind::Text); 1080 } 1081 Fragments.append(")", DeclarationFragments::FragmentKind::Text); 1082 } 1083 return Fragments; 1084 } 1085 1086 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCCategory( 1087 const ObjCCategoryDecl *Category) { 1088 DeclarationFragments Fragments; 1089 1090 auto *Interface = Category->getClassInterface(); 1091 SmallString<128> InterfaceUSR; 1092 index::generateUSRForDecl(Interface, InterfaceUSR); 1093 1094 Fragments.append("@interface", DeclarationFragments::FragmentKind::Keyword) 1095 .appendSpace() 1096 .append(Category->getClassInterface()->getName(), 1097 DeclarationFragments::FragmentKind::TypeIdentifier, InterfaceUSR, 1098 Interface) 1099 .append(" (", DeclarationFragments::FragmentKind::Text) 1100 .append(Category->getName(), 1101 DeclarationFragments::FragmentKind::Identifier) 1102 .append(")", DeclarationFragments::FragmentKind::Text); 1103 1104 return Fragments; 1105 } 1106 1107 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCInterface( 1108 const ObjCInterfaceDecl *Interface) { 1109 DeclarationFragments Fragments; 1110 // Build the base of the Objective-C interface declaration. 1111 Fragments.append("@interface", DeclarationFragments::FragmentKind::Keyword) 1112 .appendSpace() 1113 .append(Interface->getName(), 1114 DeclarationFragments::FragmentKind::Identifier); 1115 1116 // Build the inheritance part of the declaration. 1117 if (const ObjCInterfaceDecl *SuperClass = Interface->getSuperClass()) { 1118 SmallString<128> SuperUSR; 1119 index::generateUSRForDecl(SuperClass, SuperUSR); 1120 Fragments.append(" : ", DeclarationFragments::FragmentKind::Text) 1121 .append(SuperClass->getName(), 1122 DeclarationFragments::FragmentKind::TypeIdentifier, SuperUSR, 1123 SuperClass); 1124 } 1125 1126 return Fragments; 1127 } 1128 1129 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCMethod( 1130 const ObjCMethodDecl *Method) { 1131 DeclarationFragments Fragments, After; 1132 // Build the instance/class method indicator. 1133 if (Method->isClassMethod()) 1134 Fragments.append("+ ", DeclarationFragments::FragmentKind::Text); 1135 else if (Method->isInstanceMethod()) 1136 Fragments.append("- ", DeclarationFragments::FragmentKind::Text); 1137 1138 // Build the return type. 1139 Fragments.append("(", DeclarationFragments::FragmentKind::Text) 1140 .append(getFragmentsForType(Method->getReturnType(), 1141 Method->getASTContext(), After)) 1142 .append(std::move(After)) 1143 .append(")", DeclarationFragments::FragmentKind::Text); 1144 1145 // Build the selector part. 1146 Selector Selector = Method->getSelector(); 1147 if (Selector.getNumArgs() == 0) 1148 // For Objective-C methods that don't take arguments, the first (and only) 1149 // slot of the selector is the method name. 1150 Fragments.appendSpace().append( 1151 Selector.getNameForSlot(0), 1152 DeclarationFragments::FragmentKind::Identifier); 1153 1154 // For Objective-C methods that take arguments, build the selector slots. 1155 for (unsigned i = 0, end = Method->param_size(); i != end; ++i) { 1156 // Objective-C method selector parts are considered as identifiers instead 1157 // of "external parameters" as in Swift. This is because Objective-C method 1158 // symbols are referenced with the entire selector, instead of just the 1159 // method name in Swift. 1160 SmallString<32> ParamID(Selector.getNameForSlot(i)); 1161 ParamID.append(":"); 1162 Fragments.appendSpace().append( 1163 ParamID, DeclarationFragments::FragmentKind::Identifier); 1164 1165 // Build the internal parameter. 1166 const ParmVarDecl *Param = Method->getParamDecl(i); 1167 Fragments.append(getFragmentsForParam(Param)); 1168 } 1169 1170 return Fragments.append(";", DeclarationFragments::FragmentKind::Text); 1171 } 1172 1173 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProperty( 1174 const ObjCPropertyDecl *Property) { 1175 DeclarationFragments Fragments, After; 1176 1177 // Build the Objective-C property keyword. 1178 Fragments.append("@property", DeclarationFragments::FragmentKind::Keyword); 1179 1180 const auto Attributes = Property->getPropertyAttributesAsWritten(); 1181 // Build the attributes if there is any associated with the property. 1182 if (Attributes != ObjCPropertyAttribute::kind_noattr) { 1183 // No leading comma for the first attribute. 1184 bool First = true; 1185 Fragments.append(" (", DeclarationFragments::FragmentKind::Text); 1186 // Helper function to render the attribute. 1187 auto RenderAttribute = 1188 [&](ObjCPropertyAttribute::Kind Kind, StringRef Spelling, 1189 StringRef Arg = "", 1190 DeclarationFragments::FragmentKind ArgKind = 1191 DeclarationFragments::FragmentKind::Identifier) { 1192 // Check if the `Kind` attribute is set for this property. 1193 if ((Attributes & Kind) && !Spelling.empty()) { 1194 // Add a leading comma if this is not the first attribute rendered. 1195 if (!First) 1196 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 1197 // Render the spelling of this attribute `Kind` as a keyword. 1198 Fragments.append(Spelling, 1199 DeclarationFragments::FragmentKind::Keyword); 1200 // If this attribute takes in arguments (e.g. `getter=getterName`), 1201 // render the arguments. 1202 if (!Arg.empty()) 1203 Fragments.append("=", DeclarationFragments::FragmentKind::Text) 1204 .append(Arg, ArgKind); 1205 First = false; 1206 } 1207 }; 1208 1209 // Go through all possible Objective-C property attributes and render set 1210 // ones. 1211 RenderAttribute(ObjCPropertyAttribute::kind_class, "class"); 1212 RenderAttribute(ObjCPropertyAttribute::kind_direct, "direct"); 1213 RenderAttribute(ObjCPropertyAttribute::kind_nonatomic, "nonatomic"); 1214 RenderAttribute(ObjCPropertyAttribute::kind_atomic, "atomic"); 1215 RenderAttribute(ObjCPropertyAttribute::kind_assign, "assign"); 1216 RenderAttribute(ObjCPropertyAttribute::kind_retain, "retain"); 1217 RenderAttribute(ObjCPropertyAttribute::kind_strong, "strong"); 1218 RenderAttribute(ObjCPropertyAttribute::kind_copy, "copy"); 1219 RenderAttribute(ObjCPropertyAttribute::kind_weak, "weak"); 1220 RenderAttribute(ObjCPropertyAttribute::kind_unsafe_unretained, 1221 "unsafe_unretained"); 1222 RenderAttribute(ObjCPropertyAttribute::kind_readwrite, "readwrite"); 1223 RenderAttribute(ObjCPropertyAttribute::kind_readonly, "readonly"); 1224 RenderAttribute(ObjCPropertyAttribute::kind_getter, "getter", 1225 Property->getGetterName().getAsString()); 1226 RenderAttribute(ObjCPropertyAttribute::kind_setter, "setter", 1227 Property->getSetterName().getAsString()); 1228 1229 // Render nullability attributes. 1230 if (Attributes & ObjCPropertyAttribute::kind_nullability) { 1231 QualType Type = Property->getType(); 1232 if (const auto Nullability = 1233 AttributedType::stripOuterNullability(Type)) { 1234 if (!First) 1235 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 1236 if (*Nullability == NullabilityKind::Unspecified && 1237 (Attributes & ObjCPropertyAttribute::kind_null_resettable)) 1238 Fragments.append("null_resettable", 1239 DeclarationFragments::FragmentKind::Keyword); 1240 else 1241 Fragments.append( 1242 getNullabilitySpelling(*Nullability, /*isContextSensitive=*/true), 1243 DeclarationFragments::FragmentKind::Keyword); 1244 First = false; 1245 } 1246 } 1247 1248 Fragments.append(")", DeclarationFragments::FragmentKind::Text); 1249 } 1250 1251 // Build the property type and name, and return the completed fragments. 1252 return Fragments.appendSpace() 1253 .append(getFragmentsForType(Property->getType(), 1254 Property->getASTContext(), After)) 1255 .appendSpace() 1256 .append(Property->getName(), 1257 DeclarationFragments::FragmentKind::Identifier) 1258 .append(std::move(After)); 1259 } 1260 1261 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProtocol( 1262 const ObjCProtocolDecl *Protocol) { 1263 DeclarationFragments Fragments; 1264 // Build basic protocol declaration. 1265 Fragments.append("@protocol", DeclarationFragments::FragmentKind::Keyword) 1266 .appendSpace() 1267 .append(Protocol->getName(), 1268 DeclarationFragments::FragmentKind::Identifier); 1269 1270 // If this protocol conforms to other protocols, build the conformance list. 1271 if (!Protocol->protocols().empty()) { 1272 Fragments.append(" <", DeclarationFragments::FragmentKind::Text); 1273 for (ObjCProtocolDecl::protocol_iterator It = Protocol->protocol_begin(); 1274 It != Protocol->protocol_end(); It++) { 1275 // Add a leading comma if this is not the first protocol rendered. 1276 if (It != Protocol->protocol_begin()) 1277 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 1278 1279 SmallString<128> USR; 1280 index::generateUSRForDecl(*It, USR); 1281 Fragments.append((*It)->getName(), 1282 DeclarationFragments::FragmentKind::TypeIdentifier, USR, 1283 *It); 1284 } 1285 Fragments.append(">", DeclarationFragments::FragmentKind::Text); 1286 } 1287 1288 return Fragments; 1289 } 1290 1291 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForTypedef( 1292 const TypedefNameDecl *Decl) { 1293 DeclarationFragments Fragments, After; 1294 Fragments.append("typedef", DeclarationFragments::FragmentKind::Keyword) 1295 .appendSpace() 1296 .append(getFragmentsForType(Decl->getUnderlyingType(), 1297 Decl->getASTContext(), After)) 1298 .append(std::move(After)) 1299 .appendSpace() 1300 .append(Decl->getName(), DeclarationFragments::FragmentKind::Identifier); 1301 1302 return Fragments.append(";", DeclarationFragments::FragmentKind::Text); 1303 } 1304 1305 // Instantiate template for FunctionDecl. 1306 template FunctionSignature 1307 DeclarationFragmentsBuilder::getFunctionSignature(const FunctionDecl *); 1308 1309 // Instantiate template for ObjCMethodDecl. 1310 template FunctionSignature 1311 DeclarationFragmentsBuilder::getFunctionSignature(const ObjCMethodDecl *); 1312 1313 // Subheading of a symbol defaults to its name. 1314 DeclarationFragments 1315 DeclarationFragmentsBuilder::getSubHeading(const NamedDecl *Decl) { 1316 DeclarationFragments Fragments; 1317 if (isa<CXXConstructorDecl>(Decl) || isa<CXXDestructorDecl>(Decl)) 1318 Fragments.append(cast<CXXRecordDecl>(Decl->getDeclContext())->getName(), 1319 DeclarationFragments::FragmentKind::Identifier); 1320 else if (isa<CXXConversionDecl>(Decl)) { 1321 Fragments.append( 1322 cast<CXXConversionDecl>(Decl)->getConversionType().getAsString(), 1323 DeclarationFragments::FragmentKind::Identifier); 1324 } else if (isa<CXXMethodDecl>(Decl) && 1325 cast<CXXMethodDecl>(Decl)->isOverloadedOperator()) { 1326 Fragments.append(Decl->getNameAsString(), 1327 DeclarationFragments::FragmentKind::Identifier); 1328 } else if (!Decl->getName().empty()) 1329 Fragments.append(Decl->getName(), 1330 DeclarationFragments::FragmentKind::Identifier); 1331 return Fragments; 1332 } 1333 1334 // Subheading of an Objective-C method is a `+` or `-` sign indicating whether 1335 // it's a class method or an instance method, followed by the selector name. 1336 DeclarationFragments 1337 DeclarationFragmentsBuilder::getSubHeading(const ObjCMethodDecl *Method) { 1338 DeclarationFragments Fragments; 1339 if (Method->isClassMethod()) 1340 Fragments.append("+ ", DeclarationFragments::FragmentKind::Text); 1341 else if (Method->isInstanceMethod()) 1342 Fragments.append("- ", DeclarationFragments::FragmentKind::Text); 1343 1344 return Fragments.append(Method->getNameAsString(), 1345 DeclarationFragments::FragmentKind::Identifier); 1346 } 1347 1348 // Subheading of a symbol defaults to its name. 1349 DeclarationFragments 1350 DeclarationFragmentsBuilder::getSubHeadingForMacro(StringRef Name) { 1351 DeclarationFragments Fragments; 1352 Fragments.append(Name, DeclarationFragments::FragmentKind::Identifier); 1353 return Fragments; 1354 } 1355