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