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 // Declaration fragments of a pointer type is the declaration fragments of 256 // the pointee type followed by a `*`, 257 if (T->isPointerType() && !T->isFunctionPointerType()) 258 return Fragments 259 .append(getFragmentsForType(T->getPointeeType(), Context, After)) 260 .append(" *", DeclarationFragments::FragmentKind::Text); 261 262 // For Objective-C `id` and `Class` pointers 263 // we do not spell out the `*`. 264 if (T->isObjCObjectPointerType() && 265 !T->getAs<ObjCObjectPointerType>()->isObjCIdOrClassType()) { 266 267 Fragments.append(getFragmentsForType(T->getPointeeType(), Context, After)); 268 269 // id<protocol> is an qualified id type 270 // id<protocol>* is not an qualified id type 271 if (!T->getAs<ObjCObjectPointerType>()->isObjCQualifiedIdType()) { 272 Fragments.append(" *", DeclarationFragments::FragmentKind::Text); 273 } 274 275 return Fragments; 276 } 277 278 // Declaration fragments of a lvalue reference type is the declaration 279 // fragments of the underlying type followed by a `&`. 280 if (const LValueReferenceType *LRT = dyn_cast<LValueReferenceType>(T)) 281 return Fragments 282 .append( 283 getFragmentsForType(LRT->getPointeeTypeAsWritten(), Context, After)) 284 .append(" &", DeclarationFragments::FragmentKind::Text); 285 286 // Declaration fragments of a rvalue reference type is the declaration 287 // fragments of the underlying type followed by a `&&`. 288 if (const RValueReferenceType *RRT = dyn_cast<RValueReferenceType>(T)) 289 return Fragments 290 .append( 291 getFragmentsForType(RRT->getPointeeTypeAsWritten(), Context, After)) 292 .append(" &&", DeclarationFragments::FragmentKind::Text); 293 294 // Declaration fragments of an array-typed variable have two parts: 295 // 1. the element type of the array that appears before the variable name; 296 // 2. array brackets `[(0-9)?]` that appear after the variable name. 297 if (const ArrayType *AT = T->getAsArrayTypeUnsafe()) { 298 // Build the "after" part first because the inner element type might also 299 // be an array-type. For example `int matrix[3][4]` which has a type of 300 // "(array 3 of (array 4 of ints))." 301 // Push the array size part first to make sure they are in the right order. 302 After.append("[", DeclarationFragments::FragmentKind::Text); 303 304 switch (AT->getSizeModifier()) { 305 case ArraySizeModifier::Normal: 306 break; 307 case ArraySizeModifier::Static: 308 Fragments.append("static", DeclarationFragments::FragmentKind::Keyword); 309 break; 310 case ArraySizeModifier::Star: 311 Fragments.append("*", DeclarationFragments::FragmentKind::Text); 312 break; 313 } 314 315 if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) { 316 // FIXME: right now this would evaluate any expressions/macros written in 317 // the original source to concrete values. For example 318 // `int nums[MAX]` -> `int nums[100]` 319 // `char *str[5 + 1]` -> `char *str[6]` 320 SmallString<128> Size; 321 CAT->getSize().toStringUnsigned(Size); 322 After.append(Size, DeclarationFragments::FragmentKind::NumberLiteral); 323 } 324 325 After.append("]", DeclarationFragments::FragmentKind::Text); 326 327 return Fragments.append( 328 getFragmentsForType(AT->getElementType(), Context, After)); 329 } 330 331 // An ElaboratedType is a sugar for types that are referred to using an 332 // elaborated keyword, e.g., `struct S`, `enum E`, or (in C++) via a 333 // qualified name, e.g., `N::M::type`, or both. 334 if (const ElaboratedType *ET = dyn_cast<ElaboratedType>(T)) { 335 ElaboratedTypeKeyword Keyword = ET->getKeyword(); 336 if (Keyword != ElaboratedTypeKeyword::None) { 337 Fragments 338 .append(ElaboratedType::getKeywordName(Keyword), 339 DeclarationFragments::FragmentKind::Keyword) 340 .appendSpace(); 341 } 342 343 if (const NestedNameSpecifier *NNS = ET->getQualifier()) 344 Fragments.append(getFragmentsForNNS(NNS, Context, After)); 345 346 // After handling the elaborated keyword or qualified name, build 347 // declaration fragments for the desugared underlying type. 348 return Fragments.append(getFragmentsForType(ET->desugar(), Context, After)); 349 } 350 351 // If the type is a typedefed type, get the underlying TypedefNameDecl for a 352 // direct reference to the typedef instead of the wrapped type. 353 354 // 'id' type is a typedef for an ObjCObjectPointerType 355 // we treat it as a typedef 356 if (const TypedefType *TypedefTy = dyn_cast<TypedefType>(T)) { 357 const TypedefNameDecl *Decl = TypedefTy->getDecl(); 358 TypedefUnderlyingTypeResolver TypedefResolver(Context); 359 std::string USR = TypedefResolver.getUSRForType(QualType(T, 0)); 360 361 if (T->isObjCIdType()) { 362 return Fragments.append(Decl->getName(), 363 DeclarationFragments::FragmentKind::Keyword); 364 } 365 366 return Fragments.append( 367 Decl->getName(), DeclarationFragments::FragmentKind::TypeIdentifier, 368 USR, TypedefResolver.getUnderlyingTypeDecl(QualType(T, 0))); 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 764 DeclarationFragmentsBuilder::getFragmentsForStruct(const RecordDecl *Record) { 765 if (const auto *TypedefNameDecl = Record->getTypedefNameForAnonDecl()) 766 return getFragmentsForTypedef(TypedefNameDecl); 767 768 DeclarationFragments Fragments; 769 Fragments.append("struct", DeclarationFragments::FragmentKind::Keyword); 770 771 if (!Record->getName().empty()) 772 Fragments.appendSpace().append( 773 Record->getName(), DeclarationFragments::FragmentKind::Identifier); 774 775 return Fragments.append(";", DeclarationFragments::FragmentKind::Text); 776 } 777 778 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForCXXClass( 779 const CXXRecordDecl *Record) { 780 if (const auto *TypedefNameDecl = Record->getTypedefNameForAnonDecl()) 781 return getFragmentsForTypedef(TypedefNameDecl); 782 783 DeclarationFragments Fragments; 784 Fragments.append(DeclarationFragments::getStructureTypeFragment(Record)); 785 786 if (!Record->getName().empty()) 787 Fragments.appendSpace().append( 788 Record->getName(), DeclarationFragments::FragmentKind::Identifier); 789 790 return Fragments.append(";", DeclarationFragments::FragmentKind::Text); 791 } 792 793 DeclarationFragments 794 DeclarationFragmentsBuilder::getFragmentsForSpecialCXXMethod( 795 const CXXMethodDecl *Method) { 796 DeclarationFragments Fragments; 797 std::string Name; 798 if (const auto *Constructor = dyn_cast<CXXConstructorDecl>(Method)) { 799 Name = Method->getNameAsString(); 800 if (Constructor->isExplicit()) 801 Fragments.append("explicit", DeclarationFragments::FragmentKind::Keyword) 802 .appendSpace(); 803 } else if (isa<CXXDestructorDecl>(Method)) 804 Name = Method->getNameAsString(); 805 806 DeclarationFragments After; 807 Fragments.append(Name, DeclarationFragments::FragmentKind::Identifier) 808 .append(std::move(After)); 809 Fragments.append("(", DeclarationFragments::FragmentKind::Text); 810 for (unsigned i = 0, end = Method->getNumParams(); i != end; ++i) { 811 if (i) 812 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 813 Fragments.append(getFragmentsForParam(Method->getParamDecl(i))); 814 } 815 Fragments.append(")", DeclarationFragments::FragmentKind::Text); 816 817 Fragments.append(DeclarationFragments::getExceptionSpecificationString( 818 Method->getExceptionSpecType())); 819 820 return Fragments.append(";", DeclarationFragments::FragmentKind::Text); 821 } 822 823 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForCXXMethod( 824 const CXXMethodDecl *Method) { 825 DeclarationFragments Fragments; 826 StringRef Name = Method->getName(); 827 if (Method->isStatic()) 828 Fragments.append("static", DeclarationFragments::FragmentKind::Keyword) 829 .appendSpace(); 830 if (Method->isConstexpr()) 831 Fragments.append("constexpr", DeclarationFragments::FragmentKind::Keyword) 832 .appendSpace(); 833 if (Method->isVolatile()) 834 Fragments.append("volatile", DeclarationFragments::FragmentKind::Keyword) 835 .appendSpace(); 836 837 // Build return type 838 DeclarationFragments After; 839 Fragments 840 .append(getFragmentsForType(Method->getReturnType(), 841 Method->getASTContext(), After)) 842 .appendSpace() 843 .append(Name, DeclarationFragments::FragmentKind::Identifier) 844 .append(std::move(After)); 845 Fragments.append("(", DeclarationFragments::FragmentKind::Text); 846 for (unsigned i = 0, end = Method->getNumParams(); i != end; ++i) { 847 if (i) 848 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 849 Fragments.append(getFragmentsForParam(Method->getParamDecl(i))); 850 } 851 Fragments.append(")", DeclarationFragments::FragmentKind::Text); 852 853 if (Method->isConst()) 854 Fragments.appendSpace().append("const", 855 DeclarationFragments::FragmentKind::Keyword); 856 857 Fragments.append(DeclarationFragments::getExceptionSpecificationString( 858 Method->getExceptionSpecType())); 859 860 return Fragments.append(";", DeclarationFragments::FragmentKind::Text); 861 } 862 863 DeclarationFragments 864 DeclarationFragmentsBuilder::getFragmentsForConversionFunction( 865 const CXXConversionDecl *ConversionFunction) { 866 DeclarationFragments Fragments; 867 868 if (ConversionFunction->isExplicit()) 869 Fragments.append("explicit", DeclarationFragments::FragmentKind::Keyword) 870 .appendSpace(); 871 872 Fragments.append("operator", DeclarationFragments::FragmentKind::Keyword) 873 .appendSpace(); 874 875 Fragments 876 .append(ConversionFunction->getConversionType().getAsString(), 877 DeclarationFragments::FragmentKind::TypeIdentifier) 878 .append("(", DeclarationFragments::FragmentKind::Text); 879 for (unsigned i = 0, end = ConversionFunction->getNumParams(); i != end; 880 ++i) { 881 if (i) 882 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 883 Fragments.append(getFragmentsForParam(ConversionFunction->getParamDecl(i))); 884 } 885 Fragments.append(")", DeclarationFragments::FragmentKind::Text); 886 887 if (ConversionFunction->isConst()) 888 Fragments.appendSpace().append("const", 889 DeclarationFragments::FragmentKind::Keyword); 890 891 return Fragments.append(";", DeclarationFragments::FragmentKind::Text); 892 } 893 894 DeclarationFragments 895 DeclarationFragmentsBuilder::getFragmentsForOverloadedOperator( 896 const CXXMethodDecl *Method) { 897 DeclarationFragments Fragments; 898 899 // Build return type 900 DeclarationFragments After; 901 Fragments 902 .append(getFragmentsForType(Method->getReturnType(), 903 Method->getASTContext(), After)) 904 .appendSpace() 905 .append(Method->getNameAsString(), 906 DeclarationFragments::FragmentKind::Identifier) 907 .append(std::move(After)); 908 Fragments.append("(", DeclarationFragments::FragmentKind::Text); 909 for (unsigned i = 0, end = Method->getNumParams(); i != end; ++i) { 910 if (i) 911 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 912 Fragments.append(getFragmentsForParam(Method->getParamDecl(i))); 913 } 914 Fragments.append(")", DeclarationFragments::FragmentKind::Text); 915 916 if (Method->isConst()) 917 Fragments.appendSpace().append("const", 918 DeclarationFragments::FragmentKind::Keyword); 919 920 Fragments.append(DeclarationFragments::getExceptionSpecificationString( 921 Method->getExceptionSpecType())); 922 923 return Fragments.append(";", DeclarationFragments::FragmentKind::Text); 924 } 925 926 // Get fragments for template parameters, e.g. T in tempalte<typename T> ... 927 DeclarationFragments 928 DeclarationFragmentsBuilder::getFragmentsForTemplateParameters( 929 ArrayRef<NamedDecl *> ParameterArray) { 930 DeclarationFragments Fragments; 931 for (unsigned i = 0, end = ParameterArray.size(); i != end; ++i) { 932 if (i) 933 Fragments.append(",", DeclarationFragments::FragmentKind::Text) 934 .appendSpace(); 935 936 const auto *TemplateParam = 937 dyn_cast<TemplateTypeParmDecl>(ParameterArray[i]); 938 if (!TemplateParam) 939 continue; 940 if (TemplateParam->hasTypeConstraint()) 941 Fragments.append(TemplateParam->getTypeConstraint() 942 ->getNamedConcept() 943 ->getName() 944 .str(), 945 DeclarationFragments::FragmentKind::TypeIdentifier); 946 else if (TemplateParam->wasDeclaredWithTypename()) 947 Fragments.append("typename", DeclarationFragments::FragmentKind::Keyword); 948 else 949 Fragments.append("class", DeclarationFragments::FragmentKind::Keyword); 950 951 if (TemplateParam->isParameterPack()) 952 Fragments.append("...", DeclarationFragments::FragmentKind::Text); 953 954 Fragments.appendSpace().append( 955 TemplateParam->getName(), 956 DeclarationFragments::FragmentKind::GenericParameter); 957 } 958 return Fragments; 959 } 960 961 // Find the name of a template argument from the template's parameters. 962 std::string DeclarationFragmentsBuilder::getNameForTemplateArgument( 963 const ArrayRef<NamedDecl *> TemplateParameters, std::string TypeParameter) { 964 // The arg is a generic parameter from a partial spec, e.g. 965 // T in template<typename T> Foo<T, int>. 966 // 967 // Those names appear as "type-parameter-<index>-<depth>", so we must find its 968 // name from the template's parameter list. 969 for (unsigned i = 0; i < TemplateParameters.size(); ++i) { 970 const auto *Parameter = 971 dyn_cast<TemplateTypeParmDecl>(TemplateParameters[i]); 972 if (TypeParameter.compare("type-parameter-" + 973 std::to_string(Parameter->getDepth()) + "-" + 974 std::to_string(Parameter->getIndex())) == 0) 975 return std::string(TemplateParameters[i]->getName()); 976 } 977 llvm_unreachable("Could not find the name of a template argument."); 978 } 979 980 // Get fragments for template arguments, e.g. int in template<typename T> 981 // Foo<int>; 982 // 983 // Note: TemplateParameters is only necessary if the Decl is a 984 // PartialSpecialization, where we need the parameters to deduce the name of the 985 // generic arguments. 986 DeclarationFragments 987 DeclarationFragmentsBuilder::getFragmentsForTemplateArguments( 988 const ArrayRef<TemplateArgument> TemplateArguments, ASTContext &Context, 989 const std::optional<ArrayRef<NamedDecl *>> TemplateParameters) { 990 DeclarationFragments Fragments; 991 for (unsigned i = 0, end = TemplateArguments.size(); i != end; ++i) { 992 if (i) 993 Fragments.append(",", DeclarationFragments::FragmentKind::Text) 994 .appendSpace(); 995 996 std::string Type = TemplateArguments[i].getAsType().getAsString(); 997 DeclarationFragments After; 998 DeclarationFragments ArgumentFragment = 999 getFragmentsForType(TemplateArguments[i].getAsType(), Context, After); 1000 1001 if (ArgumentFragment.begin()->Spelling.substr(0, 14).compare( 1002 "type-parameter") == 0) { 1003 std::string ProperArgName = getNameForTemplateArgument( 1004 TemplateParameters.value(), ArgumentFragment.begin()->Spelling); 1005 ArgumentFragment.begin()->Spelling.swap(ProperArgName); 1006 } 1007 Fragments.append(std::move(ArgumentFragment)); 1008 1009 if (TemplateArguments[i].isPackExpansion()) 1010 Fragments.append("...", DeclarationFragments::FragmentKind::Text); 1011 } 1012 return Fragments; 1013 } 1014 1015 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForConcept( 1016 const ConceptDecl *Concept) { 1017 DeclarationFragments Fragments; 1018 return Fragments 1019 .append("template", DeclarationFragments::FragmentKind::Keyword) 1020 .append("<", DeclarationFragments::FragmentKind::Text) 1021 .append(getFragmentsForTemplateParameters( 1022 Concept->getTemplateParameters()->asArray())) 1023 .append("> ", DeclarationFragments::FragmentKind::Text) 1024 .append("concept", DeclarationFragments::FragmentKind::Keyword) 1025 .appendSpace() 1026 .append(Concept->getName().str(), 1027 DeclarationFragments::FragmentKind::Identifier) 1028 .append(";", DeclarationFragments::FragmentKind::Text); 1029 } 1030 1031 DeclarationFragments 1032 DeclarationFragmentsBuilder::getFragmentsForRedeclarableTemplate( 1033 const RedeclarableTemplateDecl *RedeclarableTemplate) { 1034 DeclarationFragments Fragments; 1035 Fragments.append("template", DeclarationFragments::FragmentKind::Keyword) 1036 .append("<", DeclarationFragments::FragmentKind::Text) 1037 .append(getFragmentsForTemplateParameters( 1038 RedeclarableTemplate->getTemplateParameters()->asArray())) 1039 .append(">", DeclarationFragments::FragmentKind::Text) 1040 .appendSpace(); 1041 1042 if (isa<TypeAliasTemplateDecl>(RedeclarableTemplate)) 1043 Fragments.appendSpace() 1044 .append("using", DeclarationFragments::FragmentKind::Keyword) 1045 .appendSpace() 1046 .append(RedeclarableTemplate->getName(), 1047 DeclarationFragments::FragmentKind::Identifier); 1048 // the templated records will be resposbible for injecting their templates 1049 return Fragments.appendSpace(); 1050 } 1051 1052 DeclarationFragments 1053 DeclarationFragmentsBuilder::getFragmentsForClassTemplateSpecialization( 1054 const ClassTemplateSpecializationDecl *Decl) { 1055 DeclarationFragments Fragments; 1056 return Fragments 1057 .append("template", DeclarationFragments::FragmentKind::Keyword) 1058 .append("<", DeclarationFragments::FragmentKind::Text) 1059 .append(">", DeclarationFragments::FragmentKind::Text) 1060 .appendSpace() 1061 .append(DeclarationFragmentsBuilder::getFragmentsForCXXClass( 1062 cast<CXXRecordDecl>(Decl))) 1063 .pop_back() // there is an extra semicolon now 1064 .append("<", DeclarationFragments::FragmentKind::Text) 1065 .append( 1066 getFragmentsForTemplateArguments(Decl->getTemplateArgs().asArray(), 1067 Decl->getASTContext(), std::nullopt)) 1068 .append(">", DeclarationFragments::FragmentKind::Text) 1069 .append(";", DeclarationFragments::FragmentKind::Text); 1070 } 1071 1072 DeclarationFragments 1073 DeclarationFragmentsBuilder::getFragmentsForClassTemplatePartialSpecialization( 1074 const ClassTemplatePartialSpecializationDecl *Decl) { 1075 DeclarationFragments Fragments; 1076 return Fragments 1077 .append("template", DeclarationFragments::FragmentKind::Keyword) 1078 .append("<", DeclarationFragments::FragmentKind::Text) 1079 .append(getFragmentsForTemplateParameters( 1080 Decl->getTemplateParameters()->asArray())) 1081 .append(">", DeclarationFragments::FragmentKind::Text) 1082 .appendSpace() 1083 .append(DeclarationFragmentsBuilder::getFragmentsForCXXClass( 1084 cast<CXXRecordDecl>(Decl))) 1085 .pop_back() // there is an extra semicolon now 1086 .append("<", DeclarationFragments::FragmentKind::Text) 1087 .append(getFragmentsForTemplateArguments( 1088 Decl->getTemplateArgs().asArray(), Decl->getASTContext(), 1089 Decl->getTemplateParameters()->asArray())) 1090 .append(">", DeclarationFragments::FragmentKind::Text) 1091 .append(";", DeclarationFragments::FragmentKind::Text); 1092 } 1093 1094 DeclarationFragments 1095 DeclarationFragmentsBuilder::getFragmentsForVarTemplateSpecialization( 1096 const VarTemplateSpecializationDecl *Decl) { 1097 DeclarationFragments Fragments; 1098 return Fragments 1099 .append("template", DeclarationFragments::FragmentKind::Keyword) 1100 .append("<", DeclarationFragments::FragmentKind::Text) 1101 .append(">", DeclarationFragments::FragmentKind::Text) 1102 .appendSpace() 1103 .append(DeclarationFragmentsBuilder::getFragmentsForVarTemplate(Decl)) 1104 .pop_back() // there is an extra semicolon now 1105 .append("<", DeclarationFragments::FragmentKind::Text) 1106 .append( 1107 getFragmentsForTemplateArguments(Decl->getTemplateArgs().asArray(), 1108 Decl->getASTContext(), std::nullopt)) 1109 .append(">", DeclarationFragments::FragmentKind::Text) 1110 .append(";", DeclarationFragments::FragmentKind::Text); 1111 } 1112 1113 DeclarationFragments 1114 DeclarationFragmentsBuilder::getFragmentsForVarTemplatePartialSpecialization( 1115 const VarTemplatePartialSpecializationDecl *Decl) { 1116 DeclarationFragments Fragments; 1117 return Fragments 1118 .append("template", DeclarationFragments::FragmentKind::Keyword) 1119 .append("<", DeclarationFragments::FragmentKind::Text) 1120 // Partial specs may have new params. 1121 .append(getFragmentsForTemplateParameters( 1122 Decl->getTemplateParameters()->asArray())) 1123 .append(">", DeclarationFragments::FragmentKind::Text) 1124 .appendSpace() 1125 .append(DeclarationFragmentsBuilder::getFragmentsForVarTemplate(Decl)) 1126 .pop_back() // there is an extra semicolon now 1127 .append("<", DeclarationFragments::FragmentKind::Text) 1128 .append(getFragmentsForTemplateArguments( 1129 Decl->getTemplateArgs().asArray(), Decl->getASTContext(), 1130 Decl->getTemplateParameters()->asArray())) 1131 .append(">", DeclarationFragments::FragmentKind::Text) 1132 .append(";", DeclarationFragments::FragmentKind::Text); 1133 } 1134 1135 DeclarationFragments 1136 DeclarationFragmentsBuilder::getFragmentsForFunctionTemplate( 1137 const FunctionTemplateDecl *Decl) { 1138 DeclarationFragments Fragments; 1139 return Fragments 1140 .append("template", DeclarationFragments::FragmentKind::Keyword) 1141 .append("<", DeclarationFragments::FragmentKind::Text) 1142 // Partial specs may have new params. 1143 .append(getFragmentsForTemplateParameters( 1144 Decl->getTemplateParameters()->asArray())) 1145 .append(">", DeclarationFragments::FragmentKind::Text) 1146 .appendSpace() 1147 .append(DeclarationFragmentsBuilder::getFragmentsForFunction( 1148 Decl->getAsFunction())); 1149 } 1150 1151 DeclarationFragments 1152 DeclarationFragmentsBuilder::getFragmentsForFunctionTemplateSpecialization( 1153 const FunctionDecl *Decl) { 1154 DeclarationFragments Fragments; 1155 return Fragments 1156 .append("template", DeclarationFragments::FragmentKind::Keyword) 1157 .append("<>", DeclarationFragments::FragmentKind::Text) 1158 .appendSpace() 1159 .append(DeclarationFragmentsBuilder::getFragmentsForFunction(Decl)); 1160 } 1161 1162 DeclarationFragments 1163 DeclarationFragmentsBuilder::getFragmentsForMacro(StringRef Name, 1164 const MacroDirective *MD) { 1165 DeclarationFragments Fragments; 1166 Fragments.append("#define", DeclarationFragments::FragmentKind::Keyword) 1167 .appendSpace(); 1168 Fragments.append(Name, DeclarationFragments::FragmentKind::Identifier); 1169 1170 auto *MI = MD->getMacroInfo(); 1171 1172 if (MI->isFunctionLike()) { 1173 Fragments.append("(", DeclarationFragments::FragmentKind::Text); 1174 unsigned numParameters = MI->getNumParams(); 1175 if (MI->isC99Varargs()) 1176 --numParameters; 1177 for (unsigned i = 0; i < numParameters; ++i) { 1178 if (i) 1179 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 1180 Fragments.append(MI->params()[i]->getName(), 1181 DeclarationFragments::FragmentKind::InternalParam); 1182 } 1183 if (MI->isVariadic()) { 1184 if (numParameters && MI->isC99Varargs()) 1185 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 1186 Fragments.append("...", DeclarationFragments::FragmentKind::Text); 1187 } 1188 Fragments.append(")", DeclarationFragments::FragmentKind::Text); 1189 } 1190 return Fragments; 1191 } 1192 1193 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCCategory( 1194 const ObjCCategoryDecl *Category) { 1195 DeclarationFragments Fragments; 1196 1197 auto *Interface = Category->getClassInterface(); 1198 SmallString<128> InterfaceUSR; 1199 index::generateUSRForDecl(Interface, InterfaceUSR); 1200 1201 Fragments.append("@interface", DeclarationFragments::FragmentKind::Keyword) 1202 .appendSpace() 1203 .append(Category->getClassInterface()->getName(), 1204 DeclarationFragments::FragmentKind::TypeIdentifier, InterfaceUSR, 1205 Interface) 1206 .append(" (", DeclarationFragments::FragmentKind::Text) 1207 .append(Category->getName(), 1208 DeclarationFragments::FragmentKind::Identifier) 1209 .append(")", DeclarationFragments::FragmentKind::Text); 1210 1211 return Fragments; 1212 } 1213 1214 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCInterface( 1215 const ObjCInterfaceDecl *Interface) { 1216 DeclarationFragments Fragments; 1217 // Build the base of the Objective-C interface declaration. 1218 Fragments.append("@interface", DeclarationFragments::FragmentKind::Keyword) 1219 .appendSpace() 1220 .append(Interface->getName(), 1221 DeclarationFragments::FragmentKind::Identifier); 1222 1223 // Build the inheritance part of the declaration. 1224 if (const ObjCInterfaceDecl *SuperClass = Interface->getSuperClass()) { 1225 SmallString<128> SuperUSR; 1226 index::generateUSRForDecl(SuperClass, SuperUSR); 1227 Fragments.append(" : ", DeclarationFragments::FragmentKind::Text) 1228 .append(SuperClass->getName(), 1229 DeclarationFragments::FragmentKind::TypeIdentifier, SuperUSR, 1230 SuperClass); 1231 } 1232 1233 return Fragments; 1234 } 1235 1236 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCMethod( 1237 const ObjCMethodDecl *Method) { 1238 DeclarationFragments Fragments, After; 1239 // Build the instance/class method indicator. 1240 if (Method->isClassMethod()) 1241 Fragments.append("+ ", DeclarationFragments::FragmentKind::Text); 1242 else if (Method->isInstanceMethod()) 1243 Fragments.append("- ", DeclarationFragments::FragmentKind::Text); 1244 1245 // Build the return type. 1246 Fragments.append("(", DeclarationFragments::FragmentKind::Text) 1247 .append(getFragmentsForType(Method->getReturnType(), 1248 Method->getASTContext(), After)) 1249 .append(std::move(After)) 1250 .append(")", DeclarationFragments::FragmentKind::Text); 1251 1252 // Build the selector part. 1253 Selector Selector = Method->getSelector(); 1254 if (Selector.getNumArgs() == 0) 1255 // For Objective-C methods that don't take arguments, the first (and only) 1256 // slot of the selector is the method name. 1257 Fragments.appendSpace().append( 1258 Selector.getNameForSlot(0), 1259 DeclarationFragments::FragmentKind::Identifier); 1260 1261 // For Objective-C methods that take arguments, build the selector slots. 1262 for (unsigned i = 0, end = Method->param_size(); i != end; ++i) { 1263 // Objective-C method selector parts are considered as identifiers instead 1264 // of "external parameters" as in Swift. This is because Objective-C method 1265 // symbols are referenced with the entire selector, instead of just the 1266 // method name in Swift. 1267 SmallString<32> ParamID(Selector.getNameForSlot(i)); 1268 ParamID.append(":"); 1269 Fragments.appendSpace().append( 1270 ParamID, DeclarationFragments::FragmentKind::Identifier); 1271 1272 // Build the internal parameter. 1273 const ParmVarDecl *Param = Method->getParamDecl(i); 1274 Fragments.append(getFragmentsForParam(Param)); 1275 } 1276 1277 return Fragments.append(";", DeclarationFragments::FragmentKind::Text); 1278 } 1279 1280 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProperty( 1281 const ObjCPropertyDecl *Property) { 1282 DeclarationFragments Fragments, After; 1283 1284 // Build the Objective-C property keyword. 1285 Fragments.append("@property", DeclarationFragments::FragmentKind::Keyword); 1286 1287 const auto Attributes = Property->getPropertyAttributesAsWritten(); 1288 // Build the attributes if there is any associated with the property. 1289 if (Attributes != ObjCPropertyAttribute::kind_noattr) { 1290 // No leading comma for the first attribute. 1291 bool First = true; 1292 Fragments.append(" (", DeclarationFragments::FragmentKind::Text); 1293 // Helper function to render the attribute. 1294 auto RenderAttribute = 1295 [&](ObjCPropertyAttribute::Kind Kind, StringRef Spelling, 1296 StringRef Arg = "", 1297 DeclarationFragments::FragmentKind ArgKind = 1298 DeclarationFragments::FragmentKind::Identifier) { 1299 // Check if the `Kind` attribute is set for this property. 1300 if ((Attributes & Kind) && !Spelling.empty()) { 1301 // Add a leading comma if this is not the first attribute rendered. 1302 if (!First) 1303 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 1304 // Render the spelling of this attribute `Kind` as a keyword. 1305 Fragments.append(Spelling, 1306 DeclarationFragments::FragmentKind::Keyword); 1307 // If this attribute takes in arguments (e.g. `getter=getterName`), 1308 // render the arguments. 1309 if (!Arg.empty()) 1310 Fragments.append("=", DeclarationFragments::FragmentKind::Text) 1311 .append(Arg, ArgKind); 1312 First = false; 1313 } 1314 }; 1315 1316 // Go through all possible Objective-C property attributes and render set 1317 // ones. 1318 RenderAttribute(ObjCPropertyAttribute::kind_class, "class"); 1319 RenderAttribute(ObjCPropertyAttribute::kind_direct, "direct"); 1320 RenderAttribute(ObjCPropertyAttribute::kind_nonatomic, "nonatomic"); 1321 RenderAttribute(ObjCPropertyAttribute::kind_atomic, "atomic"); 1322 RenderAttribute(ObjCPropertyAttribute::kind_assign, "assign"); 1323 RenderAttribute(ObjCPropertyAttribute::kind_retain, "retain"); 1324 RenderAttribute(ObjCPropertyAttribute::kind_strong, "strong"); 1325 RenderAttribute(ObjCPropertyAttribute::kind_copy, "copy"); 1326 RenderAttribute(ObjCPropertyAttribute::kind_weak, "weak"); 1327 RenderAttribute(ObjCPropertyAttribute::kind_unsafe_unretained, 1328 "unsafe_unretained"); 1329 RenderAttribute(ObjCPropertyAttribute::kind_readwrite, "readwrite"); 1330 RenderAttribute(ObjCPropertyAttribute::kind_readonly, "readonly"); 1331 RenderAttribute(ObjCPropertyAttribute::kind_getter, "getter", 1332 Property->getGetterName().getAsString()); 1333 RenderAttribute(ObjCPropertyAttribute::kind_setter, "setter", 1334 Property->getSetterName().getAsString()); 1335 1336 // Render nullability attributes. 1337 if (Attributes & ObjCPropertyAttribute::kind_nullability) { 1338 QualType Type = Property->getType(); 1339 if (const auto Nullability = 1340 AttributedType::stripOuterNullability(Type)) { 1341 if (!First) 1342 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 1343 if (*Nullability == NullabilityKind::Unspecified && 1344 (Attributes & ObjCPropertyAttribute::kind_null_resettable)) 1345 Fragments.append("null_resettable", 1346 DeclarationFragments::FragmentKind::Keyword); 1347 else 1348 Fragments.append( 1349 getNullabilitySpelling(*Nullability, /*isContextSensitive=*/true), 1350 DeclarationFragments::FragmentKind::Keyword); 1351 First = false; 1352 } 1353 } 1354 1355 Fragments.append(")", DeclarationFragments::FragmentKind::Text); 1356 } 1357 1358 Fragments.appendSpace(); 1359 1360 FunctionTypeLoc BlockLoc; 1361 FunctionProtoTypeLoc BlockProtoLoc; 1362 findTypeLocForBlockDecl(Property->getTypeSourceInfo(), BlockLoc, 1363 BlockProtoLoc); 1364 1365 auto PropType = Property->getType(); 1366 if (!BlockLoc) 1367 Fragments 1368 .append(getFragmentsForType(PropType, Property->getASTContext(), After)) 1369 .appendSpace(); 1370 else 1371 Fragments.append( 1372 getFragmentsForBlock(Property, BlockLoc, BlockProtoLoc, After)); 1373 1374 return Fragments 1375 .append(Property->getName(), 1376 DeclarationFragments::FragmentKind::Identifier) 1377 .append(std::move(After)) 1378 .append(";", DeclarationFragments::FragmentKind::Text); 1379 } 1380 1381 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProtocol( 1382 const ObjCProtocolDecl *Protocol) { 1383 DeclarationFragments Fragments; 1384 // Build basic protocol declaration. 1385 Fragments.append("@protocol", DeclarationFragments::FragmentKind::Keyword) 1386 .appendSpace() 1387 .append(Protocol->getName(), 1388 DeclarationFragments::FragmentKind::Identifier); 1389 1390 // If this protocol conforms to other protocols, build the conformance list. 1391 if (!Protocol->protocols().empty()) { 1392 Fragments.append(" <", DeclarationFragments::FragmentKind::Text); 1393 for (ObjCProtocolDecl::protocol_iterator It = Protocol->protocol_begin(); 1394 It != Protocol->protocol_end(); It++) { 1395 // Add a leading comma if this is not the first protocol rendered. 1396 if (It != Protocol->protocol_begin()) 1397 Fragments.append(", ", DeclarationFragments::FragmentKind::Text); 1398 1399 SmallString<128> USR; 1400 index::generateUSRForDecl(*It, USR); 1401 Fragments.append((*It)->getName(), 1402 DeclarationFragments::FragmentKind::TypeIdentifier, USR, 1403 *It); 1404 } 1405 Fragments.append(">", DeclarationFragments::FragmentKind::Text); 1406 } 1407 1408 return Fragments; 1409 } 1410 1411 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForTypedef( 1412 const TypedefNameDecl *Decl) { 1413 DeclarationFragments Fragments, After; 1414 Fragments.append("typedef", DeclarationFragments::FragmentKind::Keyword) 1415 .appendSpace() 1416 .append(getFragmentsForType(Decl->getUnderlyingType(), 1417 Decl->getASTContext(), After)) 1418 .append(std::move(After)) 1419 .appendSpace() 1420 .append(Decl->getName(), DeclarationFragments::FragmentKind::Identifier); 1421 1422 return Fragments.append(";", DeclarationFragments::FragmentKind::Text); 1423 } 1424 1425 // Instantiate template for FunctionDecl. 1426 template FunctionSignature 1427 DeclarationFragmentsBuilder::getFunctionSignature(const FunctionDecl *); 1428 1429 // Instantiate template for ObjCMethodDecl. 1430 template FunctionSignature 1431 DeclarationFragmentsBuilder::getFunctionSignature(const ObjCMethodDecl *); 1432 1433 // Subheading of a symbol defaults to its name. 1434 DeclarationFragments 1435 DeclarationFragmentsBuilder::getSubHeading(const NamedDecl *Decl) { 1436 DeclarationFragments Fragments; 1437 if (isa<CXXConstructorDecl>(Decl) || isa<CXXDestructorDecl>(Decl)) 1438 Fragments.append(cast<CXXRecordDecl>(Decl->getDeclContext())->getName(), 1439 DeclarationFragments::FragmentKind::Identifier); 1440 else if (isa<CXXConversionDecl>(Decl)) { 1441 Fragments.append( 1442 cast<CXXConversionDecl>(Decl)->getConversionType().getAsString(), 1443 DeclarationFragments::FragmentKind::Identifier); 1444 } else if (isa<CXXMethodDecl>(Decl) && 1445 cast<CXXMethodDecl>(Decl)->isOverloadedOperator()) { 1446 Fragments.append(Decl->getNameAsString(), 1447 DeclarationFragments::FragmentKind::Identifier); 1448 } else if (!Decl->getName().empty()) 1449 Fragments.append(Decl->getName(), 1450 DeclarationFragments::FragmentKind::Identifier); 1451 return Fragments; 1452 } 1453 1454 // Subheading of an Objective-C method is a `+` or `-` sign indicating whether 1455 // it's a class method or an instance method, followed by the selector name. 1456 DeclarationFragments 1457 DeclarationFragmentsBuilder::getSubHeading(const ObjCMethodDecl *Method) { 1458 DeclarationFragments Fragments; 1459 if (Method->isClassMethod()) 1460 Fragments.append("+ ", DeclarationFragments::FragmentKind::Text); 1461 else if (Method->isInstanceMethod()) 1462 Fragments.append("- ", DeclarationFragments::FragmentKind::Text); 1463 1464 return Fragments.append(Method->getNameAsString(), 1465 DeclarationFragments::FragmentKind::Identifier); 1466 } 1467 1468 // Subheading of a symbol defaults to its name. 1469 DeclarationFragments 1470 DeclarationFragmentsBuilder::getSubHeadingForMacro(StringRef Name) { 1471 DeclarationFragments Fragments; 1472 Fragments.append(Name, DeclarationFragments::FragmentKind::Identifier); 1473 return Fragments; 1474 } 1475