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