xref: /openbsd-src/gnu/llvm/clang/lib/ExtractAPI/DeclarationFragments.cpp (revision 12c855180aad702bbcca06e0398d774beeafb155)
1*12c85518Srobert //===- ExtractAPI/DeclarationFragments.cpp ----------------------*- C++ -*-===//
2*12c85518Srobert //
3*12c85518Srobert // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*12c85518Srobert // See https://llvm.org/LICENSE.txt for license information.
5*12c85518Srobert // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*12c85518Srobert //
7*12c85518Srobert //===----------------------------------------------------------------------===//
8*12c85518Srobert ///
9*12c85518Srobert /// \file
10*12c85518Srobert /// This file implements Declaration Fragments related classes.
11*12c85518Srobert ///
12*12c85518Srobert //===----------------------------------------------------------------------===//
13*12c85518Srobert 
14*12c85518Srobert #include "clang/ExtractAPI/DeclarationFragments.h"
15*12c85518Srobert #include "TypedefUnderlyingTypeResolver.h"
16*12c85518Srobert #include "clang/Index/USRGeneration.h"
17*12c85518Srobert #include "llvm/ADT/StringSwitch.h"
18*12c85518Srobert 
19*12c85518Srobert using namespace clang::extractapi;
20*12c85518Srobert using namespace llvm;
21*12c85518Srobert 
appendSpace()22*12c85518Srobert DeclarationFragments &DeclarationFragments::appendSpace() {
23*12c85518Srobert   if (!Fragments.empty()) {
24*12c85518Srobert     Fragment &Last = Fragments.back();
25*12c85518Srobert     if (Last.Kind == FragmentKind::Text) {
26*12c85518Srobert       // Merge the extra space into the last fragment if the last fragment is
27*12c85518Srobert       // also text.
28*12c85518Srobert       if (Last.Spelling.back() != ' ') { // avoid extra trailing spaces.
29*12c85518Srobert         Last.Spelling.push_back(' ');
30*12c85518Srobert       }
31*12c85518Srobert     } else {
32*12c85518Srobert       append(" ", FragmentKind::Text);
33*12c85518Srobert     }
34*12c85518Srobert   }
35*12c85518Srobert 
36*12c85518Srobert   return *this;
37*12c85518Srobert }
38*12c85518Srobert 
getFragmentKindString(DeclarationFragments::FragmentKind Kind)39*12c85518Srobert StringRef DeclarationFragments::getFragmentKindString(
40*12c85518Srobert     DeclarationFragments::FragmentKind Kind) {
41*12c85518Srobert   switch (Kind) {
42*12c85518Srobert   case DeclarationFragments::FragmentKind::None:
43*12c85518Srobert     return "none";
44*12c85518Srobert   case DeclarationFragments::FragmentKind::Keyword:
45*12c85518Srobert     return "keyword";
46*12c85518Srobert   case DeclarationFragments::FragmentKind::Attribute:
47*12c85518Srobert     return "attribute";
48*12c85518Srobert   case DeclarationFragments::FragmentKind::NumberLiteral:
49*12c85518Srobert     return "number";
50*12c85518Srobert   case DeclarationFragments::FragmentKind::StringLiteral:
51*12c85518Srobert     return "string";
52*12c85518Srobert   case DeclarationFragments::FragmentKind::Identifier:
53*12c85518Srobert     return "identifier";
54*12c85518Srobert   case DeclarationFragments::FragmentKind::TypeIdentifier:
55*12c85518Srobert     return "typeIdentifier";
56*12c85518Srobert   case DeclarationFragments::FragmentKind::GenericParameter:
57*12c85518Srobert     return "genericParameter";
58*12c85518Srobert   case DeclarationFragments::FragmentKind::ExternalParam:
59*12c85518Srobert     return "externalParam";
60*12c85518Srobert   case DeclarationFragments::FragmentKind::InternalParam:
61*12c85518Srobert     return "internalParam";
62*12c85518Srobert   case DeclarationFragments::FragmentKind::Text:
63*12c85518Srobert     return "text";
64*12c85518Srobert   }
65*12c85518Srobert 
66*12c85518Srobert   llvm_unreachable("Unhandled FragmentKind");
67*12c85518Srobert }
68*12c85518Srobert 
69*12c85518Srobert DeclarationFragments::FragmentKind
parseFragmentKindFromString(StringRef S)70*12c85518Srobert DeclarationFragments::parseFragmentKindFromString(StringRef S) {
71*12c85518Srobert   return llvm::StringSwitch<FragmentKind>(S)
72*12c85518Srobert       .Case("keyword", DeclarationFragments::FragmentKind::Keyword)
73*12c85518Srobert       .Case("attribute", DeclarationFragments::FragmentKind::Attribute)
74*12c85518Srobert       .Case("number", DeclarationFragments::FragmentKind::NumberLiteral)
75*12c85518Srobert       .Case("string", DeclarationFragments::FragmentKind::StringLiteral)
76*12c85518Srobert       .Case("identifier", DeclarationFragments::FragmentKind::Identifier)
77*12c85518Srobert       .Case("typeIdentifier",
78*12c85518Srobert             DeclarationFragments::FragmentKind::TypeIdentifier)
79*12c85518Srobert       .Case("genericParameter",
80*12c85518Srobert             DeclarationFragments::FragmentKind::GenericParameter)
81*12c85518Srobert       .Case("internalParam", DeclarationFragments::FragmentKind::InternalParam)
82*12c85518Srobert       .Case("externalParam", DeclarationFragments::FragmentKind::ExternalParam)
83*12c85518Srobert       .Case("text", DeclarationFragments::FragmentKind::Text)
84*12c85518Srobert       .Default(DeclarationFragments::FragmentKind::None);
85*12c85518Srobert }
86*12c85518Srobert 
87*12c85518Srobert // NNS stores C++ nested name specifiers, which are prefixes to qualified names.
88*12c85518Srobert // Build declaration fragments for NNS recursively so that we have the USR for
89*12c85518Srobert // every part in a qualified name, and also leaves the actual underlying type
90*12c85518Srobert // cleaner for its own fragment.
91*12c85518Srobert DeclarationFragments
getFragmentsForNNS(const NestedNameSpecifier * NNS,ASTContext & Context,DeclarationFragments & After)92*12c85518Srobert DeclarationFragmentsBuilder::getFragmentsForNNS(const NestedNameSpecifier *NNS,
93*12c85518Srobert                                                 ASTContext &Context,
94*12c85518Srobert                                                 DeclarationFragments &After) {
95*12c85518Srobert   DeclarationFragments Fragments;
96*12c85518Srobert   if (NNS->getPrefix())
97*12c85518Srobert     Fragments.append(getFragmentsForNNS(NNS->getPrefix(), Context, After));
98*12c85518Srobert 
99*12c85518Srobert   switch (NNS->getKind()) {
100*12c85518Srobert   case NestedNameSpecifier::Identifier:
101*12c85518Srobert     Fragments.append(NNS->getAsIdentifier()->getName(),
102*12c85518Srobert                      DeclarationFragments::FragmentKind::Identifier);
103*12c85518Srobert     break;
104*12c85518Srobert 
105*12c85518Srobert   case NestedNameSpecifier::Namespace: {
106*12c85518Srobert     const NamespaceDecl *NS = NNS->getAsNamespace();
107*12c85518Srobert     if (NS->isAnonymousNamespace())
108*12c85518Srobert       return Fragments;
109*12c85518Srobert     SmallString<128> USR;
110*12c85518Srobert     index::generateUSRForDecl(NS, USR);
111*12c85518Srobert     Fragments.append(NS->getName(),
112*12c85518Srobert                      DeclarationFragments::FragmentKind::Identifier, USR, NS);
113*12c85518Srobert     break;
114*12c85518Srobert   }
115*12c85518Srobert 
116*12c85518Srobert   case NestedNameSpecifier::NamespaceAlias: {
117*12c85518Srobert     const NamespaceAliasDecl *Alias = NNS->getAsNamespaceAlias();
118*12c85518Srobert     SmallString<128> USR;
119*12c85518Srobert     index::generateUSRForDecl(Alias, USR);
120*12c85518Srobert     Fragments.append(Alias->getName(),
121*12c85518Srobert                      DeclarationFragments::FragmentKind::Identifier, USR,
122*12c85518Srobert                      Alias);
123*12c85518Srobert     break;
124*12c85518Srobert   }
125*12c85518Srobert 
126*12c85518Srobert   case NestedNameSpecifier::Global:
127*12c85518Srobert     // The global specifier `::` at the beginning. No stored value.
128*12c85518Srobert     break;
129*12c85518Srobert 
130*12c85518Srobert   case NestedNameSpecifier::Super:
131*12c85518Srobert     // Microsoft's `__super` specifier.
132*12c85518Srobert     Fragments.append("__super", DeclarationFragments::FragmentKind::Keyword);
133*12c85518Srobert     break;
134*12c85518Srobert 
135*12c85518Srobert   case NestedNameSpecifier::TypeSpecWithTemplate:
136*12c85518Srobert     // A type prefixed by the `template` keyword.
137*12c85518Srobert     Fragments.append("template", DeclarationFragments::FragmentKind::Keyword);
138*12c85518Srobert     Fragments.appendSpace();
139*12c85518Srobert     // Fallthrough after adding the keyword to handle the actual type.
140*12c85518Srobert     [[fallthrough]];
141*12c85518Srobert 
142*12c85518Srobert   case NestedNameSpecifier::TypeSpec: {
143*12c85518Srobert     const Type *T = NNS->getAsType();
144*12c85518Srobert     // FIXME: Handle C++ template specialization type
145*12c85518Srobert     Fragments.append(getFragmentsForType(T, Context, After));
146*12c85518Srobert     break;
147*12c85518Srobert   }
148*12c85518Srobert   }
149*12c85518Srobert 
150*12c85518Srobert   // Add the separator text `::` for this segment.
151*12c85518Srobert   return Fragments.append("::", DeclarationFragments::FragmentKind::Text);
152*12c85518Srobert }
153*12c85518Srobert 
154*12c85518Srobert // Recursively build the declaration fragments for an underlying `Type` with
155*12c85518Srobert // qualifiers removed.
getFragmentsForType(const Type * T,ASTContext & Context,DeclarationFragments & After)156*12c85518Srobert DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType(
157*12c85518Srobert     const Type *T, ASTContext &Context, DeclarationFragments &After) {
158*12c85518Srobert   assert(T && "invalid type");
159*12c85518Srobert 
160*12c85518Srobert   DeclarationFragments Fragments;
161*12c85518Srobert 
162*12c85518Srobert   // Declaration fragments of a pointer type is the declaration fragments of
163*12c85518Srobert   // the pointee type followed by a `*`, except for Objective-C `id` and `Class`
164*12c85518Srobert   // pointers, where we do not spell out the `*`.
165*12c85518Srobert   if (T->isPointerType() ||
166*12c85518Srobert       (T->isObjCObjectPointerType() &&
167*12c85518Srobert        !T->getAs<ObjCObjectPointerType>()->isObjCIdOrClassType())) {
168*12c85518Srobert     return Fragments
169*12c85518Srobert         .append(getFragmentsForType(T->getPointeeType(), Context, After))
170*12c85518Srobert         .append(" *", DeclarationFragments::FragmentKind::Text);
171*12c85518Srobert   }
172*12c85518Srobert 
173*12c85518Srobert   // Declaration fragments of a lvalue reference type is the declaration
174*12c85518Srobert   // fragments of the underlying type followed by a `&`.
175*12c85518Srobert   if (const LValueReferenceType *LRT = dyn_cast<LValueReferenceType>(T))
176*12c85518Srobert     return Fragments
177*12c85518Srobert         .append(
178*12c85518Srobert             getFragmentsForType(LRT->getPointeeTypeAsWritten(), Context, After))
179*12c85518Srobert         .append(" &", DeclarationFragments::FragmentKind::Text);
180*12c85518Srobert 
181*12c85518Srobert   // Declaration fragments of a rvalue reference type is the declaration
182*12c85518Srobert   // fragments of the underlying type followed by a `&&`.
183*12c85518Srobert   if (const RValueReferenceType *RRT = dyn_cast<RValueReferenceType>(T))
184*12c85518Srobert     return Fragments
185*12c85518Srobert         .append(
186*12c85518Srobert             getFragmentsForType(RRT->getPointeeTypeAsWritten(), Context, After))
187*12c85518Srobert         .append(" &&", DeclarationFragments::FragmentKind::Text);
188*12c85518Srobert 
189*12c85518Srobert   // Declaration fragments of an array-typed variable have two parts:
190*12c85518Srobert   // 1. the element type of the array that appears before the variable name;
191*12c85518Srobert   // 2. array brackets `[(0-9)?]` that appear after the variable name.
192*12c85518Srobert   if (const ArrayType *AT = T->getAsArrayTypeUnsafe()) {
193*12c85518Srobert     // Build the "after" part first because the inner element type might also
194*12c85518Srobert     // be an array-type. For example `int matrix[3][4]` which has a type of
195*12c85518Srobert     // "(array 3 of (array 4 of ints))."
196*12c85518Srobert     // Push the array size part first to make sure they are in the right order.
197*12c85518Srobert     After.append("[", DeclarationFragments::FragmentKind::Text);
198*12c85518Srobert 
199*12c85518Srobert     switch (AT->getSizeModifier()) {
200*12c85518Srobert     case ArrayType::Normal:
201*12c85518Srobert       break;
202*12c85518Srobert     case ArrayType::Static:
203*12c85518Srobert       Fragments.append("static", DeclarationFragments::FragmentKind::Keyword);
204*12c85518Srobert       break;
205*12c85518Srobert     case ArrayType::Star:
206*12c85518Srobert       Fragments.append("*", DeclarationFragments::FragmentKind::Text);
207*12c85518Srobert       break;
208*12c85518Srobert     }
209*12c85518Srobert 
210*12c85518Srobert     if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) {
211*12c85518Srobert       // FIXME: right now this would evaluate any expressions/macros written in
212*12c85518Srobert       // the original source to concrete values. For example
213*12c85518Srobert       // `int nums[MAX]` -> `int nums[100]`
214*12c85518Srobert       // `char *str[5 + 1]` -> `char *str[6]`
215*12c85518Srobert       SmallString<128> Size;
216*12c85518Srobert       CAT->getSize().toStringUnsigned(Size);
217*12c85518Srobert       After.append(Size, DeclarationFragments::FragmentKind::NumberLiteral);
218*12c85518Srobert     }
219*12c85518Srobert 
220*12c85518Srobert     After.append("]", DeclarationFragments::FragmentKind::Text);
221*12c85518Srobert 
222*12c85518Srobert     return Fragments.append(
223*12c85518Srobert         getFragmentsForType(AT->getElementType(), Context, After));
224*12c85518Srobert   }
225*12c85518Srobert 
226*12c85518Srobert   // An ElaboratedType is a sugar for types that are referred to using an
227*12c85518Srobert   // elaborated keyword, e.g., `struct S`, `enum E`, or (in C++) via a
228*12c85518Srobert   // qualified name, e.g., `N::M::type`, or both.
229*12c85518Srobert   if (const ElaboratedType *ET = dyn_cast<ElaboratedType>(T)) {
230*12c85518Srobert     ElaboratedTypeKeyword Keyword = ET->getKeyword();
231*12c85518Srobert     if (Keyword != ETK_None) {
232*12c85518Srobert       Fragments
233*12c85518Srobert           .append(ElaboratedType::getKeywordName(Keyword),
234*12c85518Srobert                   DeclarationFragments::FragmentKind::Keyword)
235*12c85518Srobert           .appendSpace();
236*12c85518Srobert     }
237*12c85518Srobert 
238*12c85518Srobert     if (const NestedNameSpecifier *NNS = ET->getQualifier())
239*12c85518Srobert       Fragments.append(getFragmentsForNNS(NNS, Context, After));
240*12c85518Srobert 
241*12c85518Srobert     // After handling the elaborated keyword or qualified name, build
242*12c85518Srobert     // declaration fragments for the desugared underlying type.
243*12c85518Srobert     return Fragments.append(getFragmentsForType(ET->desugar(), Context, After));
244*12c85518Srobert   }
245*12c85518Srobert 
246*12c85518Srobert   // Everything we care about has been handled now, reduce to the canonical
247*12c85518Srobert   // unqualified base type.
248*12c85518Srobert   QualType Base = T->getCanonicalTypeUnqualified();
249*12c85518Srobert 
250*12c85518Srobert   // Render Objective-C `id`/`instancetype` as keywords.
251*12c85518Srobert   if (T->isObjCIdType())
252*12c85518Srobert     return Fragments.append(Base.getAsString(),
253*12c85518Srobert                             DeclarationFragments::FragmentKind::Keyword);
254*12c85518Srobert 
255*12c85518Srobert   // If the type is a typedefed type, get the underlying TypedefNameDecl for a
256*12c85518Srobert   // direct reference to the typedef instead of the wrapped type.
257*12c85518Srobert   if (const TypedefType *TypedefTy = dyn_cast<TypedefType>(T)) {
258*12c85518Srobert     const TypedefNameDecl *Decl = TypedefTy->getDecl();
259*12c85518Srobert     TypedefUnderlyingTypeResolver TypedefResolver(Context);
260*12c85518Srobert     std::string USR = TypedefResolver.getUSRForType(QualType(T, 0));
261*12c85518Srobert     return Fragments.append(
262*12c85518Srobert         Decl->getName(), DeclarationFragments::FragmentKind::TypeIdentifier,
263*12c85518Srobert         USR, TypedefResolver.getUnderlyingTypeDecl(QualType(T, 0)));
264*12c85518Srobert   }
265*12c85518Srobert 
266*12c85518Srobert   // If the base type is a TagType (struct/interface/union/class/enum), let's
267*12c85518Srobert   // get the underlying Decl for better names and USRs.
268*12c85518Srobert   if (const TagType *TagTy = dyn_cast<TagType>(Base)) {
269*12c85518Srobert     const TagDecl *Decl = TagTy->getDecl();
270*12c85518Srobert     // Anonymous decl, skip this fragment.
271*12c85518Srobert     if (Decl->getName().empty())
272*12c85518Srobert       return Fragments;
273*12c85518Srobert     SmallString<128> TagUSR;
274*12c85518Srobert     clang::index::generateUSRForDecl(Decl, TagUSR);
275*12c85518Srobert     return Fragments.append(Decl->getName(),
276*12c85518Srobert                             DeclarationFragments::FragmentKind::TypeIdentifier,
277*12c85518Srobert                             TagUSR, Decl);
278*12c85518Srobert   }
279*12c85518Srobert 
280*12c85518Srobert   // If the base type is an ObjCInterfaceType, use the underlying
281*12c85518Srobert   // ObjCInterfaceDecl for the true USR.
282*12c85518Srobert   if (const auto *ObjCIT = dyn_cast<ObjCInterfaceType>(Base)) {
283*12c85518Srobert     const auto *Decl = ObjCIT->getDecl();
284*12c85518Srobert     SmallString<128> USR;
285*12c85518Srobert     index::generateUSRForDecl(Decl, USR);
286*12c85518Srobert     return Fragments.append(Decl->getName(),
287*12c85518Srobert                             DeclarationFragments::FragmentKind::TypeIdentifier,
288*12c85518Srobert                             USR, Decl);
289*12c85518Srobert   }
290*12c85518Srobert 
291*12c85518Srobert   // Default fragment builder for other kinds of types (BuiltinType etc.)
292*12c85518Srobert   SmallString<128> USR;
293*12c85518Srobert   clang::index::generateUSRForType(Base, Context, USR);
294*12c85518Srobert   Fragments.append(Base.getAsString(),
295*12c85518Srobert                    DeclarationFragments::FragmentKind::TypeIdentifier, USR);
296*12c85518Srobert 
297*12c85518Srobert   return Fragments;
298*12c85518Srobert }
299*12c85518Srobert 
300*12c85518Srobert DeclarationFragments
getFragmentsForQualifiers(const Qualifiers Quals)301*12c85518Srobert DeclarationFragmentsBuilder::getFragmentsForQualifiers(const Qualifiers Quals) {
302*12c85518Srobert   DeclarationFragments Fragments;
303*12c85518Srobert   if (Quals.hasConst())
304*12c85518Srobert     Fragments.append("const", DeclarationFragments::FragmentKind::Keyword);
305*12c85518Srobert   if (Quals.hasVolatile())
306*12c85518Srobert     Fragments.append("volatile", DeclarationFragments::FragmentKind::Keyword);
307*12c85518Srobert   if (Quals.hasRestrict())
308*12c85518Srobert     Fragments.append("restrict", DeclarationFragments::FragmentKind::Keyword);
309*12c85518Srobert 
310*12c85518Srobert   return Fragments;
311*12c85518Srobert }
312*12c85518Srobert 
getFragmentsForType(const QualType QT,ASTContext & Context,DeclarationFragments & After)313*12c85518Srobert DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType(
314*12c85518Srobert     const QualType QT, ASTContext &Context, DeclarationFragments &After) {
315*12c85518Srobert   assert(!QT.isNull() && "invalid type");
316*12c85518Srobert 
317*12c85518Srobert   if (const ParenType *PT = dyn_cast<ParenType>(QT)) {
318*12c85518Srobert     After.append(")", DeclarationFragments::FragmentKind::Text);
319*12c85518Srobert     return getFragmentsForType(PT->getInnerType(), Context, After)
320*12c85518Srobert         .append("(", DeclarationFragments::FragmentKind::Text);
321*12c85518Srobert   }
322*12c85518Srobert 
323*12c85518Srobert   const SplitQualType SQT = QT.split();
324*12c85518Srobert   DeclarationFragments QualsFragments = getFragmentsForQualifiers(SQT.Quals),
325*12c85518Srobert                        TypeFragments =
326*12c85518Srobert                            getFragmentsForType(SQT.Ty, Context, After);
327*12c85518Srobert   if (QualsFragments.getFragments().empty())
328*12c85518Srobert     return TypeFragments;
329*12c85518Srobert 
330*12c85518Srobert   // Use east qualifier for pointer types
331*12c85518Srobert   // For example:
332*12c85518Srobert   // ```
333*12c85518Srobert   // int *   const
334*12c85518Srobert   // ^----   ^----
335*12c85518Srobert   //  type    qualifier
336*12c85518Srobert   // ^-----------------
337*12c85518Srobert   //  const pointer to int
338*12c85518Srobert   // ```
339*12c85518Srobert   // should not be reconstructed as
340*12c85518Srobert   // ```
341*12c85518Srobert   // const       int       *
342*12c85518Srobert   // ^----       ^--
343*12c85518Srobert   //  qualifier   type
344*12c85518Srobert   // ^----------------     ^
345*12c85518Srobert   //  pointer to const int
346*12c85518Srobert   // ```
347*12c85518Srobert   if (SQT.Ty->isAnyPointerType())
348*12c85518Srobert     return TypeFragments.appendSpace().append(std::move(QualsFragments));
349*12c85518Srobert 
350*12c85518Srobert   return QualsFragments.appendSpace().append(std::move(TypeFragments));
351*12c85518Srobert }
352*12c85518Srobert 
353*12c85518Srobert DeclarationFragments
getFragmentsForVar(const VarDecl * Var)354*12c85518Srobert DeclarationFragmentsBuilder::getFragmentsForVar(const VarDecl *Var) {
355*12c85518Srobert   DeclarationFragments Fragments;
356*12c85518Srobert   StorageClass SC = Var->getStorageClass();
357*12c85518Srobert   if (SC != SC_None)
358*12c85518Srobert     Fragments
359*12c85518Srobert         .append(VarDecl::getStorageClassSpecifierString(SC),
360*12c85518Srobert                 DeclarationFragments::FragmentKind::Keyword)
361*12c85518Srobert         .appendSpace();
362*12c85518Srobert   QualType T =
363*12c85518Srobert       Var->getTypeSourceInfo()
364*12c85518Srobert           ? Var->getTypeSourceInfo()->getType()
365*12c85518Srobert           : Var->getASTContext().getUnqualifiedObjCPointerType(Var->getType());
366*12c85518Srobert 
367*12c85518Srobert   // Capture potential fragments that needs to be placed after the variable name
368*12c85518Srobert   // ```
369*12c85518Srobert   // int nums[5];
370*12c85518Srobert   // char (*ptr_to_array)[6];
371*12c85518Srobert   // ```
372*12c85518Srobert   DeclarationFragments After;
373*12c85518Srobert   return Fragments.append(getFragmentsForType(T, Var->getASTContext(), After))
374*12c85518Srobert       .appendSpace()
375*12c85518Srobert       .append(Var->getName(), DeclarationFragments::FragmentKind::Identifier)
376*12c85518Srobert       .append(std::move(After));
377*12c85518Srobert }
378*12c85518Srobert 
379*12c85518Srobert DeclarationFragments
getFragmentsForParam(const ParmVarDecl * Param)380*12c85518Srobert DeclarationFragmentsBuilder::getFragmentsForParam(const ParmVarDecl *Param) {
381*12c85518Srobert   DeclarationFragments Fragments, After;
382*12c85518Srobert 
383*12c85518Srobert   QualType T = Param->getTypeSourceInfo()
384*12c85518Srobert                    ? Param->getTypeSourceInfo()->getType()
385*12c85518Srobert                    : Param->getASTContext().getUnqualifiedObjCPointerType(
386*12c85518Srobert                          Param->getType());
387*12c85518Srobert 
388*12c85518Srobert   DeclarationFragments TypeFragments =
389*12c85518Srobert       getFragmentsForType(T, Param->getASTContext(), After);
390*12c85518Srobert 
391*12c85518Srobert   if (Param->isObjCMethodParameter())
392*12c85518Srobert     Fragments.append("(", DeclarationFragments::FragmentKind::Text)
393*12c85518Srobert         .append(std::move(TypeFragments))
394*12c85518Srobert         .append(") ", DeclarationFragments::FragmentKind::Text);
395*12c85518Srobert   else
396*12c85518Srobert     Fragments.append(std::move(TypeFragments)).appendSpace();
397*12c85518Srobert 
398*12c85518Srobert   return Fragments
399*12c85518Srobert       .append(Param->getName(),
400*12c85518Srobert               DeclarationFragments::FragmentKind::InternalParam)
401*12c85518Srobert       .append(std::move(After));
402*12c85518Srobert }
403*12c85518Srobert 
404*12c85518Srobert DeclarationFragments
getFragmentsForFunction(const FunctionDecl * Func)405*12c85518Srobert DeclarationFragmentsBuilder::getFragmentsForFunction(const FunctionDecl *Func) {
406*12c85518Srobert   DeclarationFragments Fragments;
407*12c85518Srobert   // FIXME: Handle template specialization
408*12c85518Srobert   switch (Func->getStorageClass()) {
409*12c85518Srobert   case SC_None:
410*12c85518Srobert   case SC_PrivateExtern:
411*12c85518Srobert     break;
412*12c85518Srobert   case SC_Extern:
413*12c85518Srobert     Fragments.append("extern", DeclarationFragments::FragmentKind::Keyword)
414*12c85518Srobert         .appendSpace();
415*12c85518Srobert     break;
416*12c85518Srobert   case SC_Static:
417*12c85518Srobert     Fragments.append("static", DeclarationFragments::FragmentKind::Keyword)
418*12c85518Srobert         .appendSpace();
419*12c85518Srobert     break;
420*12c85518Srobert   case SC_Auto:
421*12c85518Srobert   case SC_Register:
422*12c85518Srobert     llvm_unreachable("invalid for functions");
423*12c85518Srobert   }
424*12c85518Srobert   // FIXME: Handle C++ function specifiers: constexpr, consteval, explicit, etc.
425*12c85518Srobert 
426*12c85518Srobert   // FIXME: Is `after` actually needed here?
427*12c85518Srobert   DeclarationFragments After;
428*12c85518Srobert   Fragments
429*12c85518Srobert       .append(getFragmentsForType(Func->getReturnType(), Func->getASTContext(),
430*12c85518Srobert                                   After))
431*12c85518Srobert       .appendSpace()
432*12c85518Srobert       .append(Func->getName(), DeclarationFragments::FragmentKind::Identifier)
433*12c85518Srobert       .append(std::move(After));
434*12c85518Srobert 
435*12c85518Srobert   Fragments.append("(", DeclarationFragments::FragmentKind::Text);
436*12c85518Srobert   for (unsigned i = 0, end = Func->getNumParams(); i != end; ++i) {
437*12c85518Srobert     if (i)
438*12c85518Srobert       Fragments.append(", ", DeclarationFragments::FragmentKind::Text);
439*12c85518Srobert     Fragments.append(getFragmentsForParam(Func->getParamDecl(i)));
440*12c85518Srobert   }
441*12c85518Srobert   Fragments.append(")", DeclarationFragments::FragmentKind::Text);
442*12c85518Srobert 
443*12c85518Srobert   // FIXME: Handle exception specifiers: throw, noexcept
444*12c85518Srobert   return Fragments;
445*12c85518Srobert }
446*12c85518Srobert 
getFragmentsForEnumConstant(const EnumConstantDecl * EnumConstDecl)447*12c85518Srobert DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForEnumConstant(
448*12c85518Srobert     const EnumConstantDecl *EnumConstDecl) {
449*12c85518Srobert   DeclarationFragments Fragments;
450*12c85518Srobert   return Fragments.append(EnumConstDecl->getName(),
451*12c85518Srobert                           DeclarationFragments::FragmentKind::Identifier);
452*12c85518Srobert }
453*12c85518Srobert 
454*12c85518Srobert DeclarationFragments
getFragmentsForEnum(const EnumDecl * EnumDecl)455*12c85518Srobert DeclarationFragmentsBuilder::getFragmentsForEnum(const EnumDecl *EnumDecl) {
456*12c85518Srobert   if (const auto *TypedefNameDecl = EnumDecl->getTypedefNameForAnonDecl())
457*12c85518Srobert     return getFragmentsForTypedef(TypedefNameDecl);
458*12c85518Srobert 
459*12c85518Srobert   DeclarationFragments Fragments, After;
460*12c85518Srobert   Fragments.append("enum", DeclarationFragments::FragmentKind::Keyword);
461*12c85518Srobert 
462*12c85518Srobert   if (!EnumDecl->getName().empty())
463*12c85518Srobert     Fragments.appendSpace().append(
464*12c85518Srobert         EnumDecl->getName(), DeclarationFragments::FragmentKind::Identifier);
465*12c85518Srobert 
466*12c85518Srobert   QualType IntegerType = EnumDecl->getIntegerType();
467*12c85518Srobert   if (!IntegerType.isNull())
468*12c85518Srobert     Fragments.append(": ", DeclarationFragments::FragmentKind::Text)
469*12c85518Srobert         .append(
470*12c85518Srobert             getFragmentsForType(IntegerType, EnumDecl->getASTContext(), After))
471*12c85518Srobert         .append(std::move(After));
472*12c85518Srobert 
473*12c85518Srobert   return Fragments;
474*12c85518Srobert }
475*12c85518Srobert 
476*12c85518Srobert DeclarationFragments
getFragmentsForField(const FieldDecl * Field)477*12c85518Srobert DeclarationFragmentsBuilder::getFragmentsForField(const FieldDecl *Field) {
478*12c85518Srobert   DeclarationFragments After;
479*12c85518Srobert   return getFragmentsForType(Field->getType(), Field->getASTContext(), After)
480*12c85518Srobert       .appendSpace()
481*12c85518Srobert       .append(Field->getName(), DeclarationFragments::FragmentKind::Identifier)
482*12c85518Srobert       .append(std::move(After));
483*12c85518Srobert }
484*12c85518Srobert 
485*12c85518Srobert DeclarationFragments
getFragmentsForStruct(const RecordDecl * Record)486*12c85518Srobert DeclarationFragmentsBuilder::getFragmentsForStruct(const RecordDecl *Record) {
487*12c85518Srobert   if (const auto *TypedefNameDecl = Record->getTypedefNameForAnonDecl())
488*12c85518Srobert     return getFragmentsForTypedef(TypedefNameDecl);
489*12c85518Srobert 
490*12c85518Srobert   DeclarationFragments Fragments;
491*12c85518Srobert   Fragments.append("struct", DeclarationFragments::FragmentKind::Keyword);
492*12c85518Srobert 
493*12c85518Srobert   if (!Record->getName().empty())
494*12c85518Srobert     Fragments.appendSpace().append(
495*12c85518Srobert         Record->getName(), DeclarationFragments::FragmentKind::Identifier);
496*12c85518Srobert   return Fragments;
497*12c85518Srobert }
498*12c85518Srobert 
499*12c85518Srobert DeclarationFragments
getFragmentsForMacro(StringRef Name,const MacroDirective * MD)500*12c85518Srobert DeclarationFragmentsBuilder::getFragmentsForMacro(StringRef Name,
501*12c85518Srobert                                                   const MacroDirective *MD) {
502*12c85518Srobert   DeclarationFragments Fragments;
503*12c85518Srobert   Fragments.append("#define", DeclarationFragments::FragmentKind::Keyword)
504*12c85518Srobert       .appendSpace();
505*12c85518Srobert   Fragments.append(Name, DeclarationFragments::FragmentKind::Identifier);
506*12c85518Srobert 
507*12c85518Srobert   auto *MI = MD->getMacroInfo();
508*12c85518Srobert 
509*12c85518Srobert   if (MI->isFunctionLike()) {
510*12c85518Srobert     Fragments.append("(", DeclarationFragments::FragmentKind::Text);
511*12c85518Srobert     unsigned numParameters = MI->getNumParams();
512*12c85518Srobert     if (MI->isC99Varargs())
513*12c85518Srobert       --numParameters;
514*12c85518Srobert     for (unsigned i = 0; i < numParameters; ++i) {
515*12c85518Srobert       if (i)
516*12c85518Srobert         Fragments.append(", ", DeclarationFragments::FragmentKind::Text);
517*12c85518Srobert       Fragments.append(MI->params()[i]->getName(),
518*12c85518Srobert                        DeclarationFragments::FragmentKind::InternalParam);
519*12c85518Srobert     }
520*12c85518Srobert     if (MI->isVariadic()) {
521*12c85518Srobert       if (numParameters && MI->isC99Varargs())
522*12c85518Srobert         Fragments.append(", ", DeclarationFragments::FragmentKind::Text);
523*12c85518Srobert       Fragments.append("...", DeclarationFragments::FragmentKind::Text);
524*12c85518Srobert     }
525*12c85518Srobert     Fragments.append(")", DeclarationFragments::FragmentKind::Text);
526*12c85518Srobert   }
527*12c85518Srobert   return Fragments;
528*12c85518Srobert }
529*12c85518Srobert 
getFragmentsForObjCCategory(const ObjCCategoryDecl * Category)530*12c85518Srobert DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCCategory(
531*12c85518Srobert     const ObjCCategoryDecl *Category) {
532*12c85518Srobert   DeclarationFragments Fragments;
533*12c85518Srobert 
534*12c85518Srobert   auto *Interface = Category->getClassInterface();
535*12c85518Srobert   SmallString<128> InterfaceUSR;
536*12c85518Srobert   index::generateUSRForDecl(Interface, InterfaceUSR);
537*12c85518Srobert 
538*12c85518Srobert   Fragments.append("@interface", DeclarationFragments::FragmentKind::Keyword)
539*12c85518Srobert       .appendSpace()
540*12c85518Srobert       .append(Category->getClassInterface()->getName(),
541*12c85518Srobert               DeclarationFragments::FragmentKind::TypeIdentifier, InterfaceUSR,
542*12c85518Srobert               Interface)
543*12c85518Srobert       .append(" (", DeclarationFragments::FragmentKind::Text)
544*12c85518Srobert       .append(Category->getName(),
545*12c85518Srobert               DeclarationFragments::FragmentKind::Identifier)
546*12c85518Srobert       .append(")", DeclarationFragments::FragmentKind::Text);
547*12c85518Srobert 
548*12c85518Srobert   return Fragments;
549*12c85518Srobert }
550*12c85518Srobert 
getFragmentsForObjCInterface(const ObjCInterfaceDecl * Interface)551*12c85518Srobert DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCInterface(
552*12c85518Srobert     const ObjCInterfaceDecl *Interface) {
553*12c85518Srobert   DeclarationFragments Fragments;
554*12c85518Srobert   // Build the base of the Objective-C interface declaration.
555*12c85518Srobert   Fragments.append("@interface", DeclarationFragments::FragmentKind::Keyword)
556*12c85518Srobert       .appendSpace()
557*12c85518Srobert       .append(Interface->getName(),
558*12c85518Srobert               DeclarationFragments::FragmentKind::Identifier);
559*12c85518Srobert 
560*12c85518Srobert   // Build the inheritance part of the declaration.
561*12c85518Srobert   if (const ObjCInterfaceDecl *SuperClass = Interface->getSuperClass()) {
562*12c85518Srobert     SmallString<128> SuperUSR;
563*12c85518Srobert     index::generateUSRForDecl(SuperClass, SuperUSR);
564*12c85518Srobert     Fragments.append(" : ", DeclarationFragments::FragmentKind::Text)
565*12c85518Srobert         .append(SuperClass->getName(),
566*12c85518Srobert                 DeclarationFragments::FragmentKind::TypeIdentifier, SuperUSR,
567*12c85518Srobert                 SuperClass);
568*12c85518Srobert   }
569*12c85518Srobert 
570*12c85518Srobert   return Fragments;
571*12c85518Srobert }
572*12c85518Srobert 
getFragmentsForObjCMethod(const ObjCMethodDecl * Method)573*12c85518Srobert DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCMethod(
574*12c85518Srobert     const ObjCMethodDecl *Method) {
575*12c85518Srobert   DeclarationFragments Fragments, After;
576*12c85518Srobert   // Build the instance/class method indicator.
577*12c85518Srobert   if (Method->isClassMethod())
578*12c85518Srobert     Fragments.append("+ ", DeclarationFragments::FragmentKind::Text);
579*12c85518Srobert   else if (Method->isInstanceMethod())
580*12c85518Srobert     Fragments.append("- ", DeclarationFragments::FragmentKind::Text);
581*12c85518Srobert 
582*12c85518Srobert   // Build the return type.
583*12c85518Srobert   Fragments.append("(", DeclarationFragments::FragmentKind::Text)
584*12c85518Srobert       .append(getFragmentsForType(Method->getReturnType(),
585*12c85518Srobert                                   Method->getASTContext(), After))
586*12c85518Srobert       .append(std::move(After))
587*12c85518Srobert       .append(")", DeclarationFragments::FragmentKind::Text);
588*12c85518Srobert 
589*12c85518Srobert   // Build the selector part.
590*12c85518Srobert   Selector Selector = Method->getSelector();
591*12c85518Srobert   if (Selector.getNumArgs() == 0)
592*12c85518Srobert     // For Objective-C methods that don't take arguments, the first (and only)
593*12c85518Srobert     // slot of the selector is the method name.
594*12c85518Srobert     Fragments.appendSpace().append(
595*12c85518Srobert         Selector.getNameForSlot(0),
596*12c85518Srobert         DeclarationFragments::FragmentKind::Identifier);
597*12c85518Srobert 
598*12c85518Srobert   // For Objective-C methods that take arguments, build the selector slots.
599*12c85518Srobert   for (unsigned i = 0, end = Method->param_size(); i != end; ++i) {
600*12c85518Srobert     // Objective-C method selector parts are considered as identifiers instead
601*12c85518Srobert     // of "external parameters" as in Swift. This is because Objective-C method
602*12c85518Srobert     // symbols are referenced with the entire selector, instead of just the
603*12c85518Srobert     // method name in Swift.
604*12c85518Srobert     SmallString<32> ParamID(Selector.getNameForSlot(i));
605*12c85518Srobert     ParamID.append(":");
606*12c85518Srobert     Fragments.appendSpace().append(
607*12c85518Srobert         ParamID, DeclarationFragments::FragmentKind::Identifier);
608*12c85518Srobert 
609*12c85518Srobert     // Build the internal parameter.
610*12c85518Srobert     const ParmVarDecl *Param = Method->getParamDecl(i);
611*12c85518Srobert     Fragments.append(getFragmentsForParam(Param));
612*12c85518Srobert   }
613*12c85518Srobert 
614*12c85518Srobert   return Fragments.append(";", DeclarationFragments::FragmentKind::Text);
615*12c85518Srobert }
616*12c85518Srobert 
getFragmentsForObjCProperty(const ObjCPropertyDecl * Property)617*12c85518Srobert DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProperty(
618*12c85518Srobert     const ObjCPropertyDecl *Property) {
619*12c85518Srobert   DeclarationFragments Fragments, After;
620*12c85518Srobert 
621*12c85518Srobert   // Build the Objective-C property keyword.
622*12c85518Srobert   Fragments.append("@property", DeclarationFragments::FragmentKind::Keyword);
623*12c85518Srobert 
624*12c85518Srobert   const auto Attributes = Property->getPropertyAttributes();
625*12c85518Srobert   // Build the attributes if there is any associated with the property.
626*12c85518Srobert   if (Attributes != ObjCPropertyAttribute::kind_noattr) {
627*12c85518Srobert     // No leading comma for the first attribute.
628*12c85518Srobert     bool First = true;
629*12c85518Srobert     Fragments.append(" (", DeclarationFragments::FragmentKind::Text);
630*12c85518Srobert     // Helper function to render the attribute.
631*12c85518Srobert     auto RenderAttribute =
632*12c85518Srobert         [&](ObjCPropertyAttribute::Kind Kind, StringRef Spelling,
633*12c85518Srobert             StringRef Arg = "",
634*12c85518Srobert             DeclarationFragments::FragmentKind ArgKind =
635*12c85518Srobert                 DeclarationFragments::FragmentKind::Identifier) {
636*12c85518Srobert           // Check if the `Kind` attribute is set for this property.
637*12c85518Srobert           if ((Attributes & Kind) && !Spelling.empty()) {
638*12c85518Srobert             // Add a leading comma if this is not the first attribute rendered.
639*12c85518Srobert             if (!First)
640*12c85518Srobert               Fragments.append(", ", DeclarationFragments::FragmentKind::Text);
641*12c85518Srobert             // Render the spelling of this attribute `Kind` as a keyword.
642*12c85518Srobert             Fragments.append(Spelling,
643*12c85518Srobert                              DeclarationFragments::FragmentKind::Keyword);
644*12c85518Srobert             // If this attribute takes in arguments (e.g. `getter=getterName`),
645*12c85518Srobert             // render the arguments.
646*12c85518Srobert             if (!Arg.empty())
647*12c85518Srobert               Fragments.append("=", DeclarationFragments::FragmentKind::Text)
648*12c85518Srobert                   .append(Arg, ArgKind);
649*12c85518Srobert             First = false;
650*12c85518Srobert           }
651*12c85518Srobert         };
652*12c85518Srobert 
653*12c85518Srobert     // Go through all possible Objective-C property attributes and render set
654*12c85518Srobert     // ones.
655*12c85518Srobert     RenderAttribute(ObjCPropertyAttribute::kind_class, "class");
656*12c85518Srobert     RenderAttribute(ObjCPropertyAttribute::kind_direct, "direct");
657*12c85518Srobert     RenderAttribute(ObjCPropertyAttribute::kind_nonatomic, "nonatomic");
658*12c85518Srobert     RenderAttribute(ObjCPropertyAttribute::kind_atomic, "atomic");
659*12c85518Srobert     RenderAttribute(ObjCPropertyAttribute::kind_assign, "assign");
660*12c85518Srobert     RenderAttribute(ObjCPropertyAttribute::kind_retain, "retain");
661*12c85518Srobert     RenderAttribute(ObjCPropertyAttribute::kind_strong, "strong");
662*12c85518Srobert     RenderAttribute(ObjCPropertyAttribute::kind_copy, "copy");
663*12c85518Srobert     RenderAttribute(ObjCPropertyAttribute::kind_weak, "weak");
664*12c85518Srobert     RenderAttribute(ObjCPropertyAttribute::kind_unsafe_unretained,
665*12c85518Srobert                     "unsafe_unretained");
666*12c85518Srobert     RenderAttribute(ObjCPropertyAttribute::kind_readwrite, "readwrite");
667*12c85518Srobert     RenderAttribute(ObjCPropertyAttribute::kind_readonly, "readonly");
668*12c85518Srobert     RenderAttribute(ObjCPropertyAttribute::kind_getter, "getter",
669*12c85518Srobert                     Property->getGetterName().getAsString());
670*12c85518Srobert     RenderAttribute(ObjCPropertyAttribute::kind_setter, "setter",
671*12c85518Srobert                     Property->getSetterName().getAsString());
672*12c85518Srobert 
673*12c85518Srobert     // Render nullability attributes.
674*12c85518Srobert     if (Attributes & ObjCPropertyAttribute::kind_nullability) {
675*12c85518Srobert       QualType Type = Property->getType();
676*12c85518Srobert       if (const auto Nullability =
677*12c85518Srobert               AttributedType::stripOuterNullability(Type)) {
678*12c85518Srobert         if (!First)
679*12c85518Srobert           Fragments.append(", ", DeclarationFragments::FragmentKind::Text);
680*12c85518Srobert         if (*Nullability == NullabilityKind::Unspecified &&
681*12c85518Srobert             (Attributes & ObjCPropertyAttribute::kind_null_resettable))
682*12c85518Srobert           Fragments.append("null_resettable",
683*12c85518Srobert                            DeclarationFragments::FragmentKind::Keyword);
684*12c85518Srobert         else
685*12c85518Srobert           Fragments.append(
686*12c85518Srobert               getNullabilitySpelling(*Nullability, /*isContextSensitive=*/true),
687*12c85518Srobert               DeclarationFragments::FragmentKind::Keyword);
688*12c85518Srobert         First = false;
689*12c85518Srobert       }
690*12c85518Srobert     }
691*12c85518Srobert 
692*12c85518Srobert     Fragments.append(")", DeclarationFragments::FragmentKind::Text);
693*12c85518Srobert   }
694*12c85518Srobert 
695*12c85518Srobert   // Build the property type and name, and return the completed fragments.
696*12c85518Srobert   return Fragments.appendSpace()
697*12c85518Srobert       .append(getFragmentsForType(Property->getType(),
698*12c85518Srobert                                   Property->getASTContext(), After))
699*12c85518Srobert       .appendSpace()
700*12c85518Srobert       .append(Property->getName(),
701*12c85518Srobert               DeclarationFragments::FragmentKind::Identifier)
702*12c85518Srobert       .append(std::move(After));
703*12c85518Srobert }
704*12c85518Srobert 
getFragmentsForObjCProtocol(const ObjCProtocolDecl * Protocol)705*12c85518Srobert DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProtocol(
706*12c85518Srobert     const ObjCProtocolDecl *Protocol) {
707*12c85518Srobert   DeclarationFragments Fragments;
708*12c85518Srobert   // Build basic protocol declaration.
709*12c85518Srobert   Fragments.append("@protocol", DeclarationFragments::FragmentKind::Keyword)
710*12c85518Srobert       .appendSpace()
711*12c85518Srobert       .append(Protocol->getName(),
712*12c85518Srobert               DeclarationFragments::FragmentKind::Identifier);
713*12c85518Srobert 
714*12c85518Srobert   // If this protocol conforms to other protocols, build the conformance list.
715*12c85518Srobert   if (!Protocol->protocols().empty()) {
716*12c85518Srobert     Fragments.append(" <", DeclarationFragments::FragmentKind::Text);
717*12c85518Srobert     for (ObjCProtocolDecl::protocol_iterator It = Protocol->protocol_begin();
718*12c85518Srobert          It != Protocol->protocol_end(); It++) {
719*12c85518Srobert       // Add a leading comma if this is not the first protocol rendered.
720*12c85518Srobert       if (It != Protocol->protocol_begin())
721*12c85518Srobert         Fragments.append(", ", DeclarationFragments::FragmentKind::Text);
722*12c85518Srobert 
723*12c85518Srobert       SmallString<128> USR;
724*12c85518Srobert       index::generateUSRForDecl(*It, USR);
725*12c85518Srobert       Fragments.append((*It)->getName(),
726*12c85518Srobert                        DeclarationFragments::FragmentKind::TypeIdentifier, USR,
727*12c85518Srobert                        *It);
728*12c85518Srobert     }
729*12c85518Srobert     Fragments.append(">", DeclarationFragments::FragmentKind::Text);
730*12c85518Srobert   }
731*12c85518Srobert 
732*12c85518Srobert   return Fragments;
733*12c85518Srobert }
734*12c85518Srobert 
getFragmentsForTypedef(const TypedefNameDecl * Decl)735*12c85518Srobert DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForTypedef(
736*12c85518Srobert     const TypedefNameDecl *Decl) {
737*12c85518Srobert   DeclarationFragments Fragments, After;
738*12c85518Srobert   Fragments.append("typedef", DeclarationFragments::FragmentKind::Keyword)
739*12c85518Srobert       .appendSpace()
740*12c85518Srobert       .append(getFragmentsForType(Decl->getUnderlyingType(),
741*12c85518Srobert                                   Decl->getASTContext(), After))
742*12c85518Srobert       .append(std::move(After))
743*12c85518Srobert       .appendSpace()
744*12c85518Srobert       .append(Decl->getName(), DeclarationFragments::FragmentKind::Identifier);
745*12c85518Srobert 
746*12c85518Srobert   return Fragments;
747*12c85518Srobert }
748*12c85518Srobert 
749*12c85518Srobert template <typename FunctionT>
750*12c85518Srobert FunctionSignature
getFunctionSignature(const FunctionT * Function)751*12c85518Srobert DeclarationFragmentsBuilder::getFunctionSignature(const FunctionT *Function) {
752*12c85518Srobert   FunctionSignature Signature;
753*12c85518Srobert 
754*12c85518Srobert   DeclarationFragments ReturnType, After;
755*12c85518Srobert   ReturnType
756*12c85518Srobert       .append(getFragmentsForType(Function->getReturnType(),
757*12c85518Srobert                                   Function->getASTContext(), After))
758*12c85518Srobert       .append(std::move(After));
759*12c85518Srobert   Signature.setReturnType(ReturnType);
760*12c85518Srobert 
761*12c85518Srobert   for (const auto *Param : Function->parameters())
762*12c85518Srobert     Signature.addParameter(Param->getName(), getFragmentsForParam(Param));
763*12c85518Srobert 
764*12c85518Srobert   return Signature;
765*12c85518Srobert }
766*12c85518Srobert 
767*12c85518Srobert // Instantiate template for FunctionDecl.
768*12c85518Srobert template FunctionSignature
769*12c85518Srobert DeclarationFragmentsBuilder::getFunctionSignature(const FunctionDecl *);
770*12c85518Srobert 
771*12c85518Srobert // Instantiate template for ObjCMethodDecl.
772*12c85518Srobert template FunctionSignature
773*12c85518Srobert DeclarationFragmentsBuilder::getFunctionSignature(const ObjCMethodDecl *);
774*12c85518Srobert 
775*12c85518Srobert // Subheading of a symbol defaults to its name.
776*12c85518Srobert DeclarationFragments
getSubHeading(const NamedDecl * Decl)777*12c85518Srobert DeclarationFragmentsBuilder::getSubHeading(const NamedDecl *Decl) {
778*12c85518Srobert   DeclarationFragments Fragments;
779*12c85518Srobert   if (!Decl->getName().empty())
780*12c85518Srobert     Fragments.append(Decl->getName(),
781*12c85518Srobert                      DeclarationFragments::FragmentKind::Identifier);
782*12c85518Srobert   return Fragments;
783*12c85518Srobert }
784*12c85518Srobert 
785*12c85518Srobert // Subheading of an Objective-C method is a `+` or `-` sign indicating whether
786*12c85518Srobert // it's a class method or an instance method, followed by the selector name.
787*12c85518Srobert DeclarationFragments
getSubHeading(const ObjCMethodDecl * Method)788*12c85518Srobert DeclarationFragmentsBuilder::getSubHeading(const ObjCMethodDecl *Method) {
789*12c85518Srobert   DeclarationFragments Fragments;
790*12c85518Srobert   if (Method->isClassMethod())
791*12c85518Srobert     Fragments.append("+ ", DeclarationFragments::FragmentKind::Text);
792*12c85518Srobert   else if (Method->isInstanceMethod())
793*12c85518Srobert     Fragments.append("- ", DeclarationFragments::FragmentKind::Text);
794*12c85518Srobert 
795*12c85518Srobert   return Fragments.append(Method->getNameAsString(),
796*12c85518Srobert                           DeclarationFragments::FragmentKind::Identifier);
797*12c85518Srobert }
798*12c85518Srobert 
799*12c85518Srobert // Subheading of a symbol defaults to its name.
800*12c85518Srobert DeclarationFragments
getSubHeadingForMacro(StringRef Name)801*12c85518Srobert DeclarationFragmentsBuilder::getSubHeadingForMacro(StringRef Name) {
802*12c85518Srobert   DeclarationFragments Fragments;
803*12c85518Srobert   Fragments.append(Name, DeclarationFragments::FragmentKind::Identifier);
804*12c85518Srobert   return Fragments;
805*12c85518Srobert }
806