Coverage Report

Created: 2023-09-30 09:22

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