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