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