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