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