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