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