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