xref: /llvm-project/clang/lib/ExtractAPI/DeclarationFragments.cpp (revision 49fd28d9601dde429436655ec74234e895c60b89)
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 ArraySizeModifier::Normal:
270       break;
271     case ArraySizeModifier::Static:
272       Fragments.append("static", DeclarationFragments::FragmentKind::Keyword);
273       break;
274     case ArraySizeModifier::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 (QT.getAsString() == "_Bool")
401     TypeFragments.replace("bool", 0);
402 
403   if (QualsFragments.getFragments().empty())
404     return TypeFragments;
405 
406   // Use east qualifier for pointer types
407   // For example:
408   // ```
409   // int *   const
410   // ^----   ^----
411   //  type    qualifier
412   // ^-----------------
413   //  const pointer to int
414   // ```
415   // should not be reconstructed as
416   // ```
417   // const       int       *
418   // ^----       ^--
419   //  qualifier   type
420   // ^----------------     ^
421   //  pointer to const int
422   // ```
423   if (SQT.Ty->isAnyPointerType())
424     return TypeFragments.appendSpace().append(std::move(QualsFragments));
425 
426   return QualsFragments.appendSpace().append(std::move(TypeFragments));
427 }
428 
429 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForNamespace(
430     const NamespaceDecl *Decl) {
431   DeclarationFragments Fragments;
432   Fragments.append("namespace", DeclarationFragments::FragmentKind::Keyword);
433   if (!Decl->isAnonymousNamespace())
434     Fragments.appendSpace().append(
435         Decl->getName(), DeclarationFragments::FragmentKind::Identifier);
436   return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
437 }
438 
439 DeclarationFragments
440 DeclarationFragmentsBuilder::getFragmentsForVar(const VarDecl *Var) {
441   DeclarationFragments Fragments;
442   if (Var->isConstexpr())
443     Fragments.append("constexpr", DeclarationFragments::FragmentKind::Keyword)
444         .appendSpace();
445 
446   StorageClass SC = Var->getStorageClass();
447   if (SC != SC_None)
448     Fragments
449         .append(VarDecl::getStorageClassSpecifierString(SC),
450                 DeclarationFragments::FragmentKind::Keyword)
451         .appendSpace();
452   QualType T =
453       Var->getTypeSourceInfo()
454           ? Var->getTypeSourceInfo()->getType()
455           : Var->getASTContext().getUnqualifiedObjCPointerType(Var->getType());
456 
457   // Capture potential fragments that needs to be placed after the variable name
458   // ```
459   // int nums[5];
460   // char (*ptr_to_array)[6];
461   // ```
462   DeclarationFragments After;
463   return Fragments.append(getFragmentsForType(T, Var->getASTContext(), After))
464       .appendSpace()
465       .append(Var->getName(), DeclarationFragments::FragmentKind::Identifier)
466       .append(std::move(After))
467       .append(";", DeclarationFragments::FragmentKind::Text);
468 }
469 
470 DeclarationFragments
471 DeclarationFragmentsBuilder::getFragmentsForVarTemplate(const VarDecl *Var) {
472   DeclarationFragments Fragments;
473   if (Var->isConstexpr())
474     Fragments.append("constexpr", DeclarationFragments::FragmentKind::Keyword)
475         .appendSpace();
476   QualType T =
477       Var->getTypeSourceInfo()
478           ? Var->getTypeSourceInfo()->getType()
479           : Var->getASTContext().getUnqualifiedObjCPointerType(Var->getType());
480 
481   // Might be a member, so might be static.
482   if (Var->isStaticDataMember())
483     Fragments.append("static", DeclarationFragments::FragmentKind::Keyword)
484         .appendSpace();
485 
486   DeclarationFragments After;
487   DeclarationFragments ArgumentFragment =
488       getFragmentsForType(T, Var->getASTContext(), After);
489   if (ArgumentFragment.begin()->Spelling.substr(0, 14).compare(
490           "type-parameter") == 0) {
491     std::string ProperArgName = getNameForTemplateArgument(
492         Var->getDescribedVarTemplate()->getTemplateParameters()->asArray(),
493         ArgumentFragment.begin()->Spelling);
494     ArgumentFragment.begin()->Spelling.swap(ProperArgName);
495   }
496   Fragments.append(std::move(ArgumentFragment))
497       .appendSpace()
498       .append(Var->getName(), DeclarationFragments::FragmentKind::Identifier)
499       .append(";", DeclarationFragments::FragmentKind::Text);
500   return Fragments;
501 }
502 
503 DeclarationFragments
504 DeclarationFragmentsBuilder::getFragmentsForParam(const ParmVarDecl *Param) {
505   DeclarationFragments Fragments, After;
506 
507   QualType T = Param->getTypeSourceInfo()
508                    ? Param->getTypeSourceInfo()->getType()
509                    : Param->getASTContext().getUnqualifiedObjCPointerType(
510                          Param->getType());
511 
512   DeclarationFragments TypeFragments =
513       getFragmentsForType(T, Param->getASTContext(), After);
514   if (TypeFragments.begin()->Spelling.substr(0, 14).compare("type-parameter") ==
515       0) {
516     std::string ProperArgName = getNameForTemplateArgument(
517         dyn_cast<FunctionDecl>(Param->getDeclContext())
518             ->getDescribedFunctionTemplate()
519             ->getTemplateParameters()
520             ->asArray(),
521         TypeFragments.begin()->Spelling);
522     TypeFragments.begin()->Spelling.swap(ProperArgName);
523   }
524 
525   if (Param->isObjCMethodParameter())
526     Fragments.append("(", DeclarationFragments::FragmentKind::Text)
527         .append(std::move(TypeFragments))
528         .append(") ", DeclarationFragments::FragmentKind::Text);
529   else
530     Fragments.append(std::move(TypeFragments)).appendSpace();
531 
532   return Fragments
533       .append(Param->getName(),
534               DeclarationFragments::FragmentKind::InternalParam)
535       .append(std::move(After));
536 }
537 
538 DeclarationFragments
539 DeclarationFragmentsBuilder::getFragmentsForFunction(const FunctionDecl *Func) {
540   DeclarationFragments Fragments;
541   // FIXME: Handle template specialization
542   switch (Func->getStorageClass()) {
543   case SC_None:
544   case SC_PrivateExtern:
545     break;
546   case SC_Extern:
547     Fragments.append("extern", DeclarationFragments::FragmentKind::Keyword)
548         .appendSpace();
549     break;
550   case SC_Static:
551     Fragments.append("static", DeclarationFragments::FragmentKind::Keyword)
552         .appendSpace();
553     break;
554   case SC_Auto:
555   case SC_Register:
556     llvm_unreachable("invalid for functions");
557   }
558   if (Func->isConsteval()) // if consteval, it is also constexpr
559     Fragments.append("consteval", DeclarationFragments::FragmentKind::Keyword)
560         .appendSpace();
561   else if (Func->isConstexpr())
562     Fragments.append("constexpr", DeclarationFragments::FragmentKind::Keyword)
563         .appendSpace();
564 
565   // FIXME: Is `after` actually needed here?
566   DeclarationFragments After;
567   auto ReturnValueFragment =
568       getFragmentsForType(Func->getReturnType(), Func->getASTContext(), After);
569   if (ReturnValueFragment.begin()->Spelling.substr(0, 14).compare(
570           "type-parameter") == 0) {
571     std::string ProperArgName =
572         getNameForTemplateArgument(Func->getDescribedFunctionTemplate()
573                                        ->getTemplateParameters()
574                                        ->asArray(),
575                                    ReturnValueFragment.begin()->Spelling);
576     ReturnValueFragment.begin()->Spelling.swap(ProperArgName);
577   }
578 
579   Fragments.append(std::move(ReturnValueFragment))
580       .appendSpace()
581       .append(Func->getName(), DeclarationFragments::FragmentKind::Identifier);
582 
583   if (Func->getTemplateSpecializationInfo()) {
584     Fragments.append("<", DeclarationFragments::FragmentKind::Text);
585 
586     for (unsigned i = 0, end = Func->getNumParams(); i != end; ++i) {
587       if (i)
588         Fragments.append(", ", DeclarationFragments::FragmentKind::Text);
589       Fragments.append(
590           getFragmentsForType(Func->getParamDecl(i)->getType(),
591                               Func->getParamDecl(i)->getASTContext(), After));
592     }
593     Fragments.append(">", DeclarationFragments::FragmentKind::Text);
594   }
595   Fragments.append(std::move(After));
596 
597   Fragments.append("(", DeclarationFragments::FragmentKind::Text);
598   for (unsigned i = 0, end = Func->getNumParams(); i != end; ++i) {
599     if (i)
600       Fragments.append(", ", DeclarationFragments::FragmentKind::Text);
601     Fragments.append(getFragmentsForParam(Func->getParamDecl(i)));
602   }
603   Fragments.append(")", DeclarationFragments::FragmentKind::Text);
604 
605   Fragments.append(DeclarationFragments::getExceptionSpecificationString(
606       Func->getExceptionSpecType()));
607 
608   return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
609 }
610 
611 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForEnumConstant(
612     const EnumConstantDecl *EnumConstDecl) {
613   DeclarationFragments Fragments;
614   return Fragments.append(EnumConstDecl->getName(),
615                           DeclarationFragments::FragmentKind::Identifier);
616 }
617 
618 DeclarationFragments
619 DeclarationFragmentsBuilder::getFragmentsForEnum(const EnumDecl *EnumDecl) {
620   if (const auto *TypedefNameDecl = EnumDecl->getTypedefNameForAnonDecl())
621     return getFragmentsForTypedef(TypedefNameDecl);
622 
623   DeclarationFragments Fragments, After;
624   Fragments.append("enum", DeclarationFragments::FragmentKind::Keyword);
625 
626   if (!EnumDecl->getName().empty())
627     Fragments.appendSpace().append(
628         EnumDecl->getName(), DeclarationFragments::FragmentKind::Identifier);
629 
630   QualType IntegerType = EnumDecl->getIntegerType();
631   if (!IntegerType.isNull())
632     Fragments.append(": ", DeclarationFragments::FragmentKind::Text)
633         .append(
634             getFragmentsForType(IntegerType, EnumDecl->getASTContext(), After))
635         .append(std::move(After));
636 
637   return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
638 }
639 
640 DeclarationFragments
641 DeclarationFragmentsBuilder::getFragmentsForField(const FieldDecl *Field) {
642   DeclarationFragments After;
643   DeclarationFragments Fragments;
644   if (Field->isMutable())
645     Fragments.append("mutable", DeclarationFragments::FragmentKind::Keyword)
646         .appendSpace();
647   return Fragments
648       .append(
649           getFragmentsForType(Field->getType(), Field->getASTContext(), After))
650       .appendSpace()
651       .append(Field->getName(), DeclarationFragments::FragmentKind::Identifier)
652       .append(std::move(After))
653       .append(";", DeclarationFragments::FragmentKind::Text);
654 }
655 
656 DeclarationFragments
657 DeclarationFragmentsBuilder::getFragmentsForStruct(const RecordDecl *Record) {
658   if (const auto *TypedefNameDecl = Record->getTypedefNameForAnonDecl())
659     return getFragmentsForTypedef(TypedefNameDecl);
660 
661   DeclarationFragments Fragments;
662   Fragments.append("struct", DeclarationFragments::FragmentKind::Keyword);
663 
664   if (!Record->getName().empty())
665     Fragments.appendSpace().append(
666         Record->getName(), DeclarationFragments::FragmentKind::Identifier);
667 
668   return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
669 }
670 
671 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForCXXClass(
672     const CXXRecordDecl *Record) {
673   if (const auto *TypedefNameDecl = Record->getTypedefNameForAnonDecl())
674     return getFragmentsForTypedef(TypedefNameDecl);
675 
676   DeclarationFragments Fragments;
677   Fragments.append(DeclarationFragments::getStructureTypeFragment(Record));
678 
679   if (!Record->getName().empty())
680     Fragments.appendSpace().append(
681         Record->getName(), DeclarationFragments::FragmentKind::Identifier);
682 
683   return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
684 }
685 
686 DeclarationFragments
687 DeclarationFragmentsBuilder::getFragmentsForSpecialCXXMethod(
688     const CXXMethodDecl *Method) {
689   DeclarationFragments Fragments;
690   std::string Name;
691   if (const auto *Constructor = dyn_cast<CXXConstructorDecl>(Method)) {
692     Name = Method->getNameAsString();
693     if (Constructor->isExplicit())
694       Fragments.append("explicit", DeclarationFragments::FragmentKind::Keyword)
695           .appendSpace();
696   } else if (isa<CXXDestructorDecl>(Method))
697     Name = Method->getNameAsString();
698 
699   DeclarationFragments After;
700   Fragments.append(Name, DeclarationFragments::FragmentKind::Identifier)
701       .append(std::move(After));
702   Fragments.append("(", DeclarationFragments::FragmentKind::Text);
703   for (unsigned i = 0, end = Method->getNumParams(); i != end; ++i) {
704     if (i)
705       Fragments.append(", ", DeclarationFragments::FragmentKind::Text);
706     Fragments.append(getFragmentsForParam(Method->getParamDecl(i)));
707   }
708   Fragments.append(")", DeclarationFragments::FragmentKind::Text);
709 
710   Fragments.append(DeclarationFragments::getExceptionSpecificationString(
711       Method->getExceptionSpecType()));
712 
713   return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
714 }
715 
716 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForCXXMethod(
717     const CXXMethodDecl *Method) {
718   DeclarationFragments Fragments;
719   StringRef Name = Method->getName();
720   if (Method->isStatic())
721     Fragments.append("static", DeclarationFragments::FragmentKind::Keyword)
722         .appendSpace();
723   if (Method->isConstexpr())
724     Fragments.append("constexpr", DeclarationFragments::FragmentKind::Keyword)
725         .appendSpace();
726   if (Method->isVolatile())
727     Fragments.append("volatile", DeclarationFragments::FragmentKind::Keyword)
728         .appendSpace();
729 
730   // Build return type
731   DeclarationFragments After;
732   Fragments
733       .append(getFragmentsForType(Method->getReturnType(),
734                                   Method->getASTContext(), After))
735       .appendSpace()
736       .append(Name, DeclarationFragments::FragmentKind::Identifier)
737       .append(std::move(After));
738   Fragments.append("(", DeclarationFragments::FragmentKind::Text);
739   for (unsigned i = 0, end = Method->getNumParams(); i != end; ++i) {
740     if (i)
741       Fragments.append(", ", DeclarationFragments::FragmentKind::Text);
742     Fragments.append(getFragmentsForParam(Method->getParamDecl(i)));
743   }
744   Fragments.append(")", DeclarationFragments::FragmentKind::Text);
745 
746   if (Method->isConst())
747     Fragments.appendSpace().append("const",
748                                    DeclarationFragments::FragmentKind::Keyword);
749 
750   Fragments.append(DeclarationFragments::getExceptionSpecificationString(
751       Method->getExceptionSpecType()));
752 
753   return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
754 }
755 
756 DeclarationFragments
757 DeclarationFragmentsBuilder::getFragmentsForConversionFunction(
758     const CXXConversionDecl *ConversionFunction) {
759   DeclarationFragments Fragments;
760 
761   if (ConversionFunction->isExplicit())
762     Fragments.append("explicit", DeclarationFragments::FragmentKind::Keyword)
763         .appendSpace();
764 
765   Fragments.append("operator", DeclarationFragments::FragmentKind::Keyword)
766       .appendSpace();
767 
768   Fragments
769       .append(ConversionFunction->getConversionType().getAsString(),
770               DeclarationFragments::FragmentKind::TypeIdentifier)
771       .append("(", DeclarationFragments::FragmentKind::Text);
772   for (unsigned i = 0, end = ConversionFunction->getNumParams(); i != end;
773        ++i) {
774     if (i)
775       Fragments.append(", ", DeclarationFragments::FragmentKind::Text);
776     Fragments.append(getFragmentsForParam(ConversionFunction->getParamDecl(i)));
777   }
778   Fragments.append(")", DeclarationFragments::FragmentKind::Text);
779 
780   if (ConversionFunction->isConst())
781     Fragments.appendSpace().append("const",
782                                    DeclarationFragments::FragmentKind::Keyword);
783 
784   return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
785 }
786 
787 DeclarationFragments
788 DeclarationFragmentsBuilder::getFragmentsForOverloadedOperator(
789     const CXXMethodDecl *Method) {
790   DeclarationFragments Fragments;
791 
792   // Build return type
793   DeclarationFragments After;
794   Fragments
795       .append(getFragmentsForType(Method->getReturnType(),
796                                   Method->getASTContext(), After))
797       .appendSpace()
798       .append(Method->getNameAsString(),
799               DeclarationFragments::FragmentKind::Identifier)
800       .append(std::move(After));
801   Fragments.append("(", DeclarationFragments::FragmentKind::Text);
802   for (unsigned i = 0, end = Method->getNumParams(); i != end; ++i) {
803     if (i)
804       Fragments.append(", ", DeclarationFragments::FragmentKind::Text);
805     Fragments.append(getFragmentsForParam(Method->getParamDecl(i)));
806   }
807   Fragments.append(")", DeclarationFragments::FragmentKind::Text);
808 
809   if (Method->isConst())
810     Fragments.appendSpace().append("const",
811                                    DeclarationFragments::FragmentKind::Keyword);
812 
813   Fragments.append(DeclarationFragments::getExceptionSpecificationString(
814       Method->getExceptionSpecType()));
815 
816   return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
817 }
818 
819 // Get fragments for template parameters, e.g. T in tempalte<typename T> ...
820 DeclarationFragments
821 DeclarationFragmentsBuilder::getFragmentsForTemplateParameters(
822     ArrayRef<NamedDecl *> ParameterArray) {
823   DeclarationFragments Fragments;
824   for (unsigned i = 0, end = ParameterArray.size(); i != end; ++i) {
825     if (i)
826       Fragments.append(",", DeclarationFragments::FragmentKind::Text)
827           .appendSpace();
828 
829     const auto *TemplateParam =
830         dyn_cast<TemplateTypeParmDecl>(ParameterArray[i]);
831     if (!TemplateParam)
832       continue;
833     if (TemplateParam->hasTypeConstraint())
834       Fragments.append(TemplateParam->getTypeConstraint()
835                            ->getNamedConcept()
836                            ->getName()
837                            .str(),
838                        DeclarationFragments::FragmentKind::TypeIdentifier);
839     else if (TemplateParam->wasDeclaredWithTypename())
840       Fragments.append("typename", DeclarationFragments::FragmentKind::Keyword);
841     else
842       Fragments.append("class", DeclarationFragments::FragmentKind::Keyword);
843 
844     if (TemplateParam->isParameterPack())
845       Fragments.append("...", DeclarationFragments::FragmentKind::Text);
846 
847     Fragments.appendSpace().append(
848         TemplateParam->getName(),
849         DeclarationFragments::FragmentKind::GenericParameter);
850   }
851   return Fragments;
852 }
853 
854 // Find the name of a template argument from the template's parameters.
855 std::string DeclarationFragmentsBuilder::getNameForTemplateArgument(
856     const ArrayRef<NamedDecl *> TemplateParameters, std::string TypeParameter) {
857   // The arg is a generic parameter from a partial spec, e.g.
858   // T in template<typename T> Foo<T, int>.
859   //
860   // Those names appear as "type-parameter-<index>-<depth>", so we must find its
861   // name from the template's parameter list.
862   for (unsigned i = 0; i < TemplateParameters.size(); ++i) {
863     const auto *Parameter =
864         dyn_cast<TemplateTypeParmDecl>(TemplateParameters[i]);
865     if (TypeParameter.compare("type-parameter-" +
866                               std::to_string(Parameter->getDepth()) + "-" +
867                               std::to_string(Parameter->getIndex())) == 0)
868       return std::string(TemplateParameters[i]->getName());
869   }
870   llvm_unreachable("Could not find the name of a template argument.");
871 }
872 
873 // Get fragments for template arguments, e.g. int in template<typename T>
874 // Foo<int>;
875 //
876 // Note: TemplateParameters is only necessary if the Decl is a
877 // PartialSpecialization, where we need the parameters to deduce the name of the
878 // generic arguments.
879 DeclarationFragments
880 DeclarationFragmentsBuilder::getFragmentsForTemplateArguments(
881     const ArrayRef<TemplateArgument> TemplateArguments, ASTContext &Context,
882     const std::optional<ArrayRef<NamedDecl *>> TemplateParameters) {
883   DeclarationFragments Fragments;
884   for (unsigned i = 0, end = TemplateArguments.size(); i != end; ++i) {
885     if (i)
886       Fragments.append(",", DeclarationFragments::FragmentKind::Text)
887           .appendSpace();
888 
889     std::string Type = TemplateArguments[i].getAsType().getAsString();
890     DeclarationFragments After;
891     DeclarationFragments ArgumentFragment =
892         getFragmentsForType(TemplateArguments[i].getAsType(), Context, After);
893 
894     if (ArgumentFragment.begin()->Spelling.substr(0, 14).compare(
895             "type-parameter") == 0) {
896       std::string ProperArgName = getNameForTemplateArgument(
897           TemplateParameters.value(), ArgumentFragment.begin()->Spelling);
898       ArgumentFragment.begin()->Spelling.swap(ProperArgName);
899     }
900     Fragments.append(std::move(ArgumentFragment));
901 
902     if (TemplateArguments[i].isPackExpansion())
903       Fragments.append("...", DeclarationFragments::FragmentKind::Text);
904   }
905   return Fragments;
906 }
907 
908 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForConcept(
909     const ConceptDecl *Concept) {
910   DeclarationFragments Fragments;
911   return Fragments
912       .append("template", DeclarationFragments::FragmentKind::Keyword)
913       .append("<", DeclarationFragments::FragmentKind::Text)
914       .append(getFragmentsForTemplateParameters(
915           Concept->getTemplateParameters()->asArray()))
916       .append("> ", DeclarationFragments::FragmentKind::Text)
917       .append("concept", DeclarationFragments::FragmentKind::Keyword)
918       .appendSpace()
919       .append(Concept->getName().str(),
920               DeclarationFragments::FragmentKind::Identifier)
921       .append(";", DeclarationFragments::FragmentKind::Text);
922 }
923 
924 DeclarationFragments
925 DeclarationFragmentsBuilder::getFragmentsForRedeclarableTemplate(
926     const RedeclarableTemplateDecl *RedeclarableTemplate) {
927   DeclarationFragments Fragments;
928   Fragments.append("template", DeclarationFragments::FragmentKind::Keyword)
929       .append("<", DeclarationFragments::FragmentKind::Text)
930       .append(getFragmentsForTemplateParameters(
931           RedeclarableTemplate->getTemplateParameters()->asArray()))
932       .append(">", DeclarationFragments::FragmentKind::Text)
933       .appendSpace();
934 
935   if (isa<TypeAliasTemplateDecl>(RedeclarableTemplate))
936     Fragments.appendSpace()
937         .append("using", DeclarationFragments::FragmentKind::Keyword)
938         .appendSpace()
939         .append(RedeclarableTemplate->getName(),
940                 DeclarationFragments::FragmentKind::Identifier);
941   // the templated records will be resposbible for injecting their templates
942   return Fragments.appendSpace();
943 }
944 
945 DeclarationFragments
946 DeclarationFragmentsBuilder::getFragmentsForClassTemplateSpecialization(
947     const ClassTemplateSpecializationDecl *Decl) {
948   DeclarationFragments Fragments;
949   return Fragments
950       .append("template", DeclarationFragments::FragmentKind::Keyword)
951       .append("<", DeclarationFragments::FragmentKind::Text)
952       .append(">", DeclarationFragments::FragmentKind::Text)
953       .appendSpace()
954       .append(DeclarationFragmentsBuilder::getFragmentsForCXXClass(
955           cast<CXXRecordDecl>(Decl)))
956       .pop_back() // there is an extra semicolon now
957       .append("<", DeclarationFragments::FragmentKind::Text)
958       .append(
959           getFragmentsForTemplateArguments(Decl->getTemplateArgs().asArray(),
960                                            Decl->getASTContext(), std::nullopt))
961       .append(">", DeclarationFragments::FragmentKind::Text)
962       .append(";", DeclarationFragments::FragmentKind::Text);
963 }
964 
965 DeclarationFragments
966 DeclarationFragmentsBuilder::getFragmentsForClassTemplatePartialSpecialization(
967     const ClassTemplatePartialSpecializationDecl *Decl) {
968   DeclarationFragments Fragments;
969   return Fragments
970       .append("template", DeclarationFragments::FragmentKind::Keyword)
971       .append("<", DeclarationFragments::FragmentKind::Text)
972       .append(getFragmentsForTemplateParameters(
973           Decl->getTemplateParameters()->asArray()))
974       .append(">", DeclarationFragments::FragmentKind::Text)
975       .appendSpace()
976       .append(DeclarationFragmentsBuilder::getFragmentsForCXXClass(
977           cast<CXXRecordDecl>(Decl)))
978       .pop_back() // there is an extra semicolon now
979       .append("<", DeclarationFragments::FragmentKind::Text)
980       .append(getFragmentsForTemplateArguments(
981           Decl->getTemplateArgs().asArray(), Decl->getASTContext(),
982           Decl->getTemplateParameters()->asArray()))
983       .append(">", DeclarationFragments::FragmentKind::Text)
984       .append(";", DeclarationFragments::FragmentKind::Text);
985 }
986 
987 DeclarationFragments
988 DeclarationFragmentsBuilder::getFragmentsForVarTemplateSpecialization(
989     const VarTemplateSpecializationDecl *Decl) {
990   DeclarationFragments Fragments;
991   return Fragments
992       .append("template", DeclarationFragments::FragmentKind::Keyword)
993       .append("<", DeclarationFragments::FragmentKind::Text)
994       .append(">", DeclarationFragments::FragmentKind::Text)
995       .appendSpace()
996       .append(DeclarationFragmentsBuilder::getFragmentsForVarTemplate(Decl))
997       .pop_back() // there is an extra semicolon now
998       .append("<", DeclarationFragments::FragmentKind::Text)
999       .append(
1000           getFragmentsForTemplateArguments(Decl->getTemplateArgs().asArray(),
1001                                            Decl->getASTContext(), std::nullopt))
1002       .append(">", DeclarationFragments::FragmentKind::Text)
1003       .append(";", DeclarationFragments::FragmentKind::Text);
1004 }
1005 
1006 DeclarationFragments
1007 DeclarationFragmentsBuilder::getFragmentsForVarTemplatePartialSpecialization(
1008     const VarTemplatePartialSpecializationDecl *Decl) {
1009   DeclarationFragments Fragments;
1010   return Fragments
1011       .append("template", DeclarationFragments::FragmentKind::Keyword)
1012       .append("<", DeclarationFragments::FragmentKind::Text)
1013       // Partial specs may have new params.
1014       .append(getFragmentsForTemplateParameters(
1015           Decl->getTemplateParameters()->asArray()))
1016       .append(">", DeclarationFragments::FragmentKind::Text)
1017       .appendSpace()
1018       .append(DeclarationFragmentsBuilder::getFragmentsForVarTemplate(Decl))
1019       .pop_back() // there is an extra semicolon now
1020       .append("<", DeclarationFragments::FragmentKind::Text)
1021       .append(getFragmentsForTemplateArguments(
1022           Decl->getTemplateArgs().asArray(), Decl->getASTContext(),
1023           Decl->getTemplateParameters()->asArray()))
1024       .append(">", DeclarationFragments::FragmentKind::Text)
1025       .append(";", DeclarationFragments::FragmentKind::Text);
1026 }
1027 
1028 DeclarationFragments
1029 DeclarationFragmentsBuilder::getFragmentsForFunctionTemplate(
1030     const FunctionTemplateDecl *Decl) {
1031   DeclarationFragments Fragments;
1032   return Fragments
1033       .append("template", DeclarationFragments::FragmentKind::Keyword)
1034       .append("<", DeclarationFragments::FragmentKind::Text)
1035       // Partial specs may have new params.
1036       .append(getFragmentsForTemplateParameters(
1037           Decl->getTemplateParameters()->asArray()))
1038       .append(">", DeclarationFragments::FragmentKind::Text)
1039       .appendSpace()
1040       .append(DeclarationFragmentsBuilder::getFragmentsForFunction(
1041           Decl->getAsFunction()));
1042 }
1043 
1044 DeclarationFragments
1045 DeclarationFragmentsBuilder::getFragmentsForFunctionTemplateSpecialization(
1046     const FunctionDecl *Decl) {
1047   DeclarationFragments Fragments;
1048   return Fragments
1049       .append("template", DeclarationFragments::FragmentKind::Keyword)
1050       .append("<>", DeclarationFragments::FragmentKind::Text)
1051       .appendSpace()
1052       .append(DeclarationFragmentsBuilder::getFragmentsForFunction(Decl));
1053 }
1054 
1055 DeclarationFragments
1056 DeclarationFragmentsBuilder::getFragmentsForMacro(StringRef Name,
1057                                                   const MacroDirective *MD) {
1058   DeclarationFragments Fragments;
1059   Fragments.append("#define", DeclarationFragments::FragmentKind::Keyword)
1060       .appendSpace();
1061   Fragments.append(Name, DeclarationFragments::FragmentKind::Identifier);
1062 
1063   auto *MI = MD->getMacroInfo();
1064 
1065   if (MI->isFunctionLike()) {
1066     Fragments.append("(", DeclarationFragments::FragmentKind::Text);
1067     unsigned numParameters = MI->getNumParams();
1068     if (MI->isC99Varargs())
1069       --numParameters;
1070     for (unsigned i = 0; i < numParameters; ++i) {
1071       if (i)
1072         Fragments.append(", ", DeclarationFragments::FragmentKind::Text);
1073       Fragments.append(MI->params()[i]->getName(),
1074                        DeclarationFragments::FragmentKind::InternalParam);
1075     }
1076     if (MI->isVariadic()) {
1077       if (numParameters && MI->isC99Varargs())
1078         Fragments.append(", ", DeclarationFragments::FragmentKind::Text);
1079       Fragments.append("...", DeclarationFragments::FragmentKind::Text);
1080     }
1081     Fragments.append(")", DeclarationFragments::FragmentKind::Text);
1082   }
1083   return Fragments;
1084 }
1085 
1086 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCCategory(
1087     const ObjCCategoryDecl *Category) {
1088   DeclarationFragments Fragments;
1089 
1090   auto *Interface = Category->getClassInterface();
1091   SmallString<128> InterfaceUSR;
1092   index::generateUSRForDecl(Interface, InterfaceUSR);
1093 
1094   Fragments.append("@interface", DeclarationFragments::FragmentKind::Keyword)
1095       .appendSpace()
1096       .append(Category->getClassInterface()->getName(),
1097               DeclarationFragments::FragmentKind::TypeIdentifier, InterfaceUSR,
1098               Interface)
1099       .append(" (", DeclarationFragments::FragmentKind::Text)
1100       .append(Category->getName(),
1101               DeclarationFragments::FragmentKind::Identifier)
1102       .append(")", DeclarationFragments::FragmentKind::Text);
1103 
1104   return Fragments;
1105 }
1106 
1107 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCInterface(
1108     const ObjCInterfaceDecl *Interface) {
1109   DeclarationFragments Fragments;
1110   // Build the base of the Objective-C interface declaration.
1111   Fragments.append("@interface", DeclarationFragments::FragmentKind::Keyword)
1112       .appendSpace()
1113       .append(Interface->getName(),
1114               DeclarationFragments::FragmentKind::Identifier);
1115 
1116   // Build the inheritance part of the declaration.
1117   if (const ObjCInterfaceDecl *SuperClass = Interface->getSuperClass()) {
1118     SmallString<128> SuperUSR;
1119     index::generateUSRForDecl(SuperClass, SuperUSR);
1120     Fragments.append(" : ", DeclarationFragments::FragmentKind::Text)
1121         .append(SuperClass->getName(),
1122                 DeclarationFragments::FragmentKind::TypeIdentifier, SuperUSR,
1123                 SuperClass);
1124   }
1125 
1126   return Fragments;
1127 }
1128 
1129 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCMethod(
1130     const ObjCMethodDecl *Method) {
1131   DeclarationFragments Fragments, After;
1132   // Build the instance/class method indicator.
1133   if (Method->isClassMethod())
1134     Fragments.append("+ ", DeclarationFragments::FragmentKind::Text);
1135   else if (Method->isInstanceMethod())
1136     Fragments.append("- ", DeclarationFragments::FragmentKind::Text);
1137 
1138   // Build the return type.
1139   Fragments.append("(", DeclarationFragments::FragmentKind::Text)
1140       .append(getFragmentsForType(Method->getReturnType(),
1141                                   Method->getASTContext(), After))
1142       .append(std::move(After))
1143       .append(")", DeclarationFragments::FragmentKind::Text);
1144 
1145   // Build the selector part.
1146   Selector Selector = Method->getSelector();
1147   if (Selector.getNumArgs() == 0)
1148     // For Objective-C methods that don't take arguments, the first (and only)
1149     // slot of the selector is the method name.
1150     Fragments.appendSpace().append(
1151         Selector.getNameForSlot(0),
1152         DeclarationFragments::FragmentKind::Identifier);
1153 
1154   // For Objective-C methods that take arguments, build the selector slots.
1155   for (unsigned i = 0, end = Method->param_size(); i != end; ++i) {
1156     // Objective-C method selector parts are considered as identifiers instead
1157     // of "external parameters" as in Swift. This is because Objective-C method
1158     // symbols are referenced with the entire selector, instead of just the
1159     // method name in Swift.
1160     SmallString<32> ParamID(Selector.getNameForSlot(i));
1161     ParamID.append(":");
1162     Fragments.appendSpace().append(
1163         ParamID, DeclarationFragments::FragmentKind::Identifier);
1164 
1165     // Build the internal parameter.
1166     const ParmVarDecl *Param = Method->getParamDecl(i);
1167     Fragments.append(getFragmentsForParam(Param));
1168   }
1169 
1170   return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
1171 }
1172 
1173 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProperty(
1174     const ObjCPropertyDecl *Property) {
1175   DeclarationFragments Fragments, After;
1176 
1177   // Build the Objective-C property keyword.
1178   Fragments.append("@property", DeclarationFragments::FragmentKind::Keyword);
1179 
1180   const auto Attributes = Property->getPropertyAttributesAsWritten();
1181   // Build the attributes if there is any associated with the property.
1182   if (Attributes != ObjCPropertyAttribute::kind_noattr) {
1183     // No leading comma for the first attribute.
1184     bool First = true;
1185     Fragments.append(" (", DeclarationFragments::FragmentKind::Text);
1186     // Helper function to render the attribute.
1187     auto RenderAttribute =
1188         [&](ObjCPropertyAttribute::Kind Kind, StringRef Spelling,
1189             StringRef Arg = "",
1190             DeclarationFragments::FragmentKind ArgKind =
1191                 DeclarationFragments::FragmentKind::Identifier) {
1192           // Check if the `Kind` attribute is set for this property.
1193           if ((Attributes & Kind) && !Spelling.empty()) {
1194             // Add a leading comma if this is not the first attribute rendered.
1195             if (!First)
1196               Fragments.append(", ", DeclarationFragments::FragmentKind::Text);
1197             // Render the spelling of this attribute `Kind` as a keyword.
1198             Fragments.append(Spelling,
1199                              DeclarationFragments::FragmentKind::Keyword);
1200             // If this attribute takes in arguments (e.g. `getter=getterName`),
1201             // render the arguments.
1202             if (!Arg.empty())
1203               Fragments.append("=", DeclarationFragments::FragmentKind::Text)
1204                   .append(Arg, ArgKind);
1205             First = false;
1206           }
1207         };
1208 
1209     // Go through all possible Objective-C property attributes and render set
1210     // ones.
1211     RenderAttribute(ObjCPropertyAttribute::kind_class, "class");
1212     RenderAttribute(ObjCPropertyAttribute::kind_direct, "direct");
1213     RenderAttribute(ObjCPropertyAttribute::kind_nonatomic, "nonatomic");
1214     RenderAttribute(ObjCPropertyAttribute::kind_atomic, "atomic");
1215     RenderAttribute(ObjCPropertyAttribute::kind_assign, "assign");
1216     RenderAttribute(ObjCPropertyAttribute::kind_retain, "retain");
1217     RenderAttribute(ObjCPropertyAttribute::kind_strong, "strong");
1218     RenderAttribute(ObjCPropertyAttribute::kind_copy, "copy");
1219     RenderAttribute(ObjCPropertyAttribute::kind_weak, "weak");
1220     RenderAttribute(ObjCPropertyAttribute::kind_unsafe_unretained,
1221                     "unsafe_unretained");
1222     RenderAttribute(ObjCPropertyAttribute::kind_readwrite, "readwrite");
1223     RenderAttribute(ObjCPropertyAttribute::kind_readonly, "readonly");
1224     RenderAttribute(ObjCPropertyAttribute::kind_getter, "getter",
1225                     Property->getGetterName().getAsString());
1226     RenderAttribute(ObjCPropertyAttribute::kind_setter, "setter",
1227                     Property->getSetterName().getAsString());
1228 
1229     // Render nullability attributes.
1230     if (Attributes & ObjCPropertyAttribute::kind_nullability) {
1231       QualType Type = Property->getType();
1232       if (const auto Nullability =
1233               AttributedType::stripOuterNullability(Type)) {
1234         if (!First)
1235           Fragments.append(", ", DeclarationFragments::FragmentKind::Text);
1236         if (*Nullability == NullabilityKind::Unspecified &&
1237             (Attributes & ObjCPropertyAttribute::kind_null_resettable))
1238           Fragments.append("null_resettable",
1239                            DeclarationFragments::FragmentKind::Keyword);
1240         else
1241           Fragments.append(
1242               getNullabilitySpelling(*Nullability, /*isContextSensitive=*/true),
1243               DeclarationFragments::FragmentKind::Keyword);
1244         First = false;
1245       }
1246     }
1247 
1248     Fragments.append(")", DeclarationFragments::FragmentKind::Text);
1249   }
1250 
1251   // Build the property type and name, and return the completed fragments.
1252   return Fragments.appendSpace()
1253       .append(getFragmentsForType(Property->getType(),
1254                                   Property->getASTContext(), After))
1255       .appendSpace()
1256       .append(Property->getName(),
1257               DeclarationFragments::FragmentKind::Identifier)
1258       .append(std::move(After));
1259 }
1260 
1261 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProtocol(
1262     const ObjCProtocolDecl *Protocol) {
1263   DeclarationFragments Fragments;
1264   // Build basic protocol declaration.
1265   Fragments.append("@protocol", DeclarationFragments::FragmentKind::Keyword)
1266       .appendSpace()
1267       .append(Protocol->getName(),
1268               DeclarationFragments::FragmentKind::Identifier);
1269 
1270   // If this protocol conforms to other protocols, build the conformance list.
1271   if (!Protocol->protocols().empty()) {
1272     Fragments.append(" <", DeclarationFragments::FragmentKind::Text);
1273     for (ObjCProtocolDecl::protocol_iterator It = Protocol->protocol_begin();
1274          It != Protocol->protocol_end(); It++) {
1275       // Add a leading comma if this is not the first protocol rendered.
1276       if (It != Protocol->protocol_begin())
1277         Fragments.append(", ", DeclarationFragments::FragmentKind::Text);
1278 
1279       SmallString<128> USR;
1280       index::generateUSRForDecl(*It, USR);
1281       Fragments.append((*It)->getName(),
1282                        DeclarationFragments::FragmentKind::TypeIdentifier, USR,
1283                        *It);
1284     }
1285     Fragments.append(">", DeclarationFragments::FragmentKind::Text);
1286   }
1287 
1288   return Fragments;
1289 }
1290 
1291 DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForTypedef(
1292     const TypedefNameDecl *Decl) {
1293   DeclarationFragments Fragments, After;
1294   Fragments.append("typedef", DeclarationFragments::FragmentKind::Keyword)
1295       .appendSpace()
1296       .append(getFragmentsForType(Decl->getUnderlyingType(),
1297                                   Decl->getASTContext(), After))
1298       .append(std::move(After))
1299       .appendSpace()
1300       .append(Decl->getName(), DeclarationFragments::FragmentKind::Identifier);
1301 
1302   return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
1303 }
1304 
1305 // Instantiate template for FunctionDecl.
1306 template FunctionSignature
1307 DeclarationFragmentsBuilder::getFunctionSignature(const FunctionDecl *);
1308 
1309 // Instantiate template for ObjCMethodDecl.
1310 template FunctionSignature
1311 DeclarationFragmentsBuilder::getFunctionSignature(const ObjCMethodDecl *);
1312 
1313 // Subheading of a symbol defaults to its name.
1314 DeclarationFragments
1315 DeclarationFragmentsBuilder::getSubHeading(const NamedDecl *Decl) {
1316   DeclarationFragments Fragments;
1317   if (isa<CXXConstructorDecl>(Decl) || isa<CXXDestructorDecl>(Decl))
1318     Fragments.append(cast<CXXRecordDecl>(Decl->getDeclContext())->getName(),
1319                      DeclarationFragments::FragmentKind::Identifier);
1320   else if (isa<CXXConversionDecl>(Decl)) {
1321     Fragments.append(
1322         cast<CXXConversionDecl>(Decl)->getConversionType().getAsString(),
1323         DeclarationFragments::FragmentKind::Identifier);
1324   } else if (isa<CXXMethodDecl>(Decl) &&
1325              cast<CXXMethodDecl>(Decl)->isOverloadedOperator()) {
1326     Fragments.append(Decl->getNameAsString(),
1327                      DeclarationFragments::FragmentKind::Identifier);
1328   } else if (!Decl->getName().empty())
1329     Fragments.append(Decl->getName(),
1330                      DeclarationFragments::FragmentKind::Identifier);
1331   return Fragments;
1332 }
1333 
1334 // Subheading of an Objective-C method is a `+` or `-` sign indicating whether
1335 // it's a class method or an instance method, followed by the selector name.
1336 DeclarationFragments
1337 DeclarationFragmentsBuilder::getSubHeading(const ObjCMethodDecl *Method) {
1338   DeclarationFragments Fragments;
1339   if (Method->isClassMethod())
1340     Fragments.append("+ ", DeclarationFragments::FragmentKind::Text);
1341   else if (Method->isInstanceMethod())
1342     Fragments.append("- ", DeclarationFragments::FragmentKind::Text);
1343 
1344   return Fragments.append(Method->getNameAsString(),
1345                           DeclarationFragments::FragmentKind::Identifier);
1346 }
1347 
1348 // Subheading of a symbol defaults to its name.
1349 DeclarationFragments
1350 DeclarationFragmentsBuilder::getSubHeadingForMacro(StringRef Name) {
1351   DeclarationFragments Fragments;
1352   Fragments.append(Name, DeclarationFragments::FragmentKind::Identifier);
1353   return Fragments;
1354 }
1355