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