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