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