llvm-project

Форк
0
/
TextNodeDumper.cpp 
2891 строка · 80.5 Кб
1
//===--- TextNodeDumper.cpp - Printing of AST nodes -----------------------===//
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
// This file implements AST dumping of components of individual AST nodes.
10
//
11
//===----------------------------------------------------------------------===//
12

13
#include "clang/AST/TextNodeDumper.h"
14
#include "clang/AST/APValue.h"
15
#include "clang/AST/DeclFriend.h"
16
#include "clang/AST/DeclOpenMP.h"
17
#include "clang/AST/DeclTemplate.h"
18
#include "clang/AST/LocInfoType.h"
19
#include "clang/AST/NestedNameSpecifier.h"
20
#include "clang/AST/Type.h"
21
#include "clang/AST/TypeLocVisitor.h"
22
#include "clang/Basic/Module.h"
23
#include "clang/Basic/SourceManager.h"
24
#include "clang/Basic/Specifiers.h"
25
#include "clang/Basic/TypeTraits.h"
26
#include "llvm/ADT/StringExtras.h"
27

28
#include <algorithm>
29
#include <utility>
30

31
using namespace clang;
32

33
static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {}
34

35
template <typename T>
36
static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) {
37
  const T *First = D->getFirstDecl();
38
  if (First != D)
39
    OS << " first " << First;
40
}
41

42
template <typename T>
43
static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) {
44
  const T *Prev = D->getPreviousDecl();
45
  if (Prev)
46
    OS << " prev " << Prev;
47
}
48

49
/// Dump the previous declaration in the redeclaration chain for a declaration,
50
/// if any.
51
static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) {
52
  switch (D->getKind()) {
53
#define DECL(DERIVED, BASE)                                                    \
54
  case Decl::DERIVED:                                                          \
55
    return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D));
56
#define ABSTRACT_DECL(DECL)
57
#include "clang/AST/DeclNodes.inc"
58
  }
59
  llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
60
}
61

62
TextNodeDumper::TextNodeDumper(raw_ostream &OS, const ASTContext &Context,
63
                               bool ShowColors)
64
    : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors),
65
      Context(&Context), SM(&Context.getSourceManager()),
66
      PrintPolicy(Context.getPrintingPolicy()),
67
      Traits(&Context.getCommentCommandTraits()) {}
68

69
TextNodeDumper::TextNodeDumper(raw_ostream &OS, bool ShowColors)
70
    : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors) {}
71

72
void TextNodeDumper::Visit(const comments::Comment *C,
73
                           const comments::FullComment *FC) {
74
  if (!C) {
75
    ColorScope Color(OS, ShowColors, NullColor);
76
    OS << "<<<NULL>>>";
77
    return;
78
  }
79

80
  {
81
    ColorScope Color(OS, ShowColors, CommentColor);
82
    OS << C->getCommentKindName();
83
  }
84
  dumpPointer(C);
85
  dumpSourceRange(C->getSourceRange());
86

87
  ConstCommentVisitor<TextNodeDumper, void,
88
                      const comments::FullComment *>::visit(C, FC);
89
}
90

91
void TextNodeDumper::Visit(const Attr *A) {
92
  {
93
    ColorScope Color(OS, ShowColors, AttrColor);
94

95
    switch (A->getKind()) {
96
#define ATTR(X)                                                                \
97
  case attr::X:                                                                \
98
    OS << #X;                                                                  \
99
    break;
100
#include "clang/Basic/AttrList.inc"
101
    }
102
    OS << "Attr";
103
  }
104
  dumpPointer(A);
105
  dumpSourceRange(A->getRange());
106
  if (A->isInherited())
107
    OS << " Inherited";
108
  if (A->isImplicit())
109
    OS << " Implicit";
110

111
  ConstAttrVisitor<TextNodeDumper>::Visit(A);
112
}
113

114
void TextNodeDumper::Visit(const TemplateArgument &TA, SourceRange R,
115
                           const Decl *From, StringRef Label) {
116
  OS << "TemplateArgument";
117
  if (R.isValid())
118
    dumpSourceRange(R);
119

120
  if (From)
121
    dumpDeclRef(From, Label);
122

123
  ConstTemplateArgumentVisitor<TextNodeDumper>::Visit(TA);
124
}
125

126
void TextNodeDumper::Visit(const Stmt *Node) {
127
  if (!Node) {
128
    ColorScope Color(OS, ShowColors, NullColor);
129
    OS << "<<<NULL>>>";
130
    return;
131
  }
132
  {
133
    ColorScope Color(OS, ShowColors, StmtColor);
134
    OS << Node->getStmtClassName();
135
  }
136
  dumpPointer(Node);
137
  dumpSourceRange(Node->getSourceRange());
138

139
  if (const auto *E = dyn_cast<Expr>(Node)) {
140
    dumpType(E->getType());
141

142
    if (E->containsErrors()) {
143
      ColorScope Color(OS, ShowColors, ErrorsColor);
144
      OS << " contains-errors";
145
    }
146

147
    {
148
      ColorScope Color(OS, ShowColors, ValueKindColor);
149
      switch (E->getValueKind()) {
150
      case VK_PRValue:
151
        break;
152
      case VK_LValue:
153
        OS << " lvalue";
154
        break;
155
      case VK_XValue:
156
        OS << " xvalue";
157
        break;
158
      }
159
    }
160

161
    {
162
      ColorScope Color(OS, ShowColors, ObjectKindColor);
163
      switch (E->getObjectKind()) {
164
      case OK_Ordinary:
165
        break;
166
      case OK_BitField:
167
        OS << " bitfield";
168
        break;
169
      case OK_ObjCProperty:
170
        OS << " objcproperty";
171
        break;
172
      case OK_ObjCSubscript:
173
        OS << " objcsubscript";
174
        break;
175
      case OK_VectorComponent:
176
        OS << " vectorcomponent";
177
        break;
178
      case OK_MatrixComponent:
179
        OS << " matrixcomponent";
180
        break;
181
      }
182
    }
183
  }
184

185
  ConstStmtVisitor<TextNodeDumper>::Visit(Node);
186
}
187

188
void TextNodeDumper::Visit(const Type *T) {
189
  if (!T) {
190
    ColorScope Color(OS, ShowColors, NullColor);
191
    OS << "<<<NULL>>>";
192
    return;
193
  }
194
  if (isa<LocInfoType>(T)) {
195
    {
196
      ColorScope Color(OS, ShowColors, TypeColor);
197
      OS << "LocInfo Type";
198
    }
199
    dumpPointer(T);
200
    return;
201
  }
202

203
  {
204
    ColorScope Color(OS, ShowColors, TypeColor);
205
    OS << T->getTypeClassName() << "Type";
206
  }
207
  dumpPointer(T);
208
  OS << " ";
209
  dumpBareType(QualType(T, 0), false);
210

211
  QualType SingleStepDesugar =
212
      T->getLocallyUnqualifiedSingleStepDesugaredType();
213
  if (SingleStepDesugar != QualType(T, 0))
214
    OS << " sugar";
215

216
  if (T->containsErrors()) {
217
    ColorScope Color(OS, ShowColors, ErrorsColor);
218
    OS << " contains-errors";
219
  }
220

221
  if (T->isDependentType())
222
    OS << " dependent";
223
  else if (T->isInstantiationDependentType())
224
    OS << " instantiation_dependent";
225

226
  if (T->isVariablyModifiedType())
227
    OS << " variably_modified";
228
  if (T->containsUnexpandedParameterPack())
229
    OS << " contains_unexpanded_pack";
230
  if (T->isFromAST())
231
    OS << " imported";
232

233
  TypeVisitor<TextNodeDumper>::Visit(T);
234
}
235

236
void TextNodeDumper::Visit(QualType T) {
237
  OS << "QualType";
238
  dumpPointer(T.getAsOpaquePtr());
239
  OS << " ";
240
  dumpBareType(T, false);
241
  OS << " " << T.split().Quals.getAsString();
242
}
243

244
void TextNodeDumper::Visit(TypeLoc TL) {
245
  if (!TL) {
246
    ColorScope Color(OS, ShowColors, NullColor);
247
    OS << "<<<NULL>>>";
248
    return;
249
  }
250

251
  {
252
    ColorScope Color(OS, ShowColors, TypeColor);
253
    OS << (TL.getTypeLocClass() == TypeLoc::Qualified
254
               ? "Qualified"
255
               : TL.getType()->getTypeClassName())
256
       << "TypeLoc";
257
  }
258
  dumpSourceRange(TL.getSourceRange());
259
  OS << ' ';
260
  dumpBareType(TL.getType(), /*Desugar=*/false);
261

262
  TypeLocVisitor<TextNodeDumper>::Visit(TL);
263
}
264

265
void TextNodeDumper::Visit(const Decl *D) {
266
  if (!D) {
267
    ColorScope Color(OS, ShowColors, NullColor);
268
    OS << "<<<NULL>>>";
269
    return;
270
  }
271

272
  {
273
    ColorScope Color(OS, ShowColors, DeclKindNameColor);
274
    OS << D->getDeclKindName() << "Decl";
275
  }
276
  dumpPointer(D);
277
  if (D->getLexicalDeclContext() != D->getDeclContext())
278
    OS << " parent " << cast<Decl>(D->getDeclContext());
279
  dumpPreviousDecl(OS, D);
280
  dumpSourceRange(D->getSourceRange());
281
  OS << ' ';
282
  dumpLocation(D->getLocation());
283
  if (D->isFromASTFile())
284
    OS << " imported";
285
  if (Module *M = D->getOwningModule())
286
    OS << " in " << M->getFullModuleName();
287
  if (auto *ND = dyn_cast<NamedDecl>(D))
288
    for (Module *M : D->getASTContext().getModulesWithMergedDefinition(
289
             const_cast<NamedDecl *>(ND)))
290
      AddChild([=] { OS << "also in " << M->getFullModuleName(); });
291
  if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
292
    if (!ND->isUnconditionallyVisible())
293
      OS << " hidden";
294
  if (D->isImplicit())
295
    OS << " implicit";
296

297
  if (D->isUsed())
298
    OS << " used";
299
  else if (D->isThisDeclarationReferenced())
300
    OS << " referenced";
301

302
  if (D->isInvalidDecl())
303
    OS << " invalid";
304
  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
305
    if (FD->isConstexprSpecified())
306
      OS << " constexpr";
307
    if (FD->isConsteval())
308
      OS << " consteval";
309
    else if (FD->isImmediateFunction())
310
      OS << " immediate";
311
    if (FD->isMultiVersion())
312
      OS << " multiversion";
313
  }
314

315
  if (!isa<FunctionDecl>(*D)) {
316
    const auto *MD = dyn_cast<ObjCMethodDecl>(D);
317
    if (!MD || !MD->isThisDeclarationADefinition()) {
318
      const auto *DC = dyn_cast<DeclContext>(D);
319
      if (DC && DC->hasExternalLexicalStorage()) {
320
        ColorScope Color(OS, ShowColors, UndeserializedColor);
321
        OS << " <undeserialized declarations>";
322
      }
323
    }
324
  }
325

326
  switch (D->getFriendObjectKind()) {
327
  case Decl::FOK_None:
328
    break;
329
  case Decl::FOK_Declared:
330
    OS << " friend";
331
    break;
332
  case Decl::FOK_Undeclared:
333
    OS << " friend_undeclared";
334
    break;
335
  }
336

337
  ConstDeclVisitor<TextNodeDumper>::Visit(D);
338
}
339

340
void TextNodeDumper::Visit(const CXXCtorInitializer *Init) {
341
  OS << "CXXCtorInitializer";
342
  if (Init->isAnyMemberInitializer()) {
343
    OS << ' ';
344
    dumpBareDeclRef(Init->getAnyMember());
345
  } else if (Init->isBaseInitializer()) {
346
    dumpType(QualType(Init->getBaseClass(), 0));
347
  } else if (Init->isDelegatingInitializer()) {
348
    dumpType(Init->getTypeSourceInfo()->getType());
349
  } else {
350
    llvm_unreachable("Unknown initializer type");
351
  }
352
}
353

354
void TextNodeDumper::Visit(const BlockDecl::Capture &C) {
355
  OS << "capture";
356
  if (C.isByRef())
357
    OS << " byref";
358
  if (C.isNested())
359
    OS << " nested";
360
  if (C.getVariable()) {
361
    OS << ' ';
362
    dumpBareDeclRef(C.getVariable());
363
  }
364
}
365

366
void TextNodeDumper::Visit(const OMPClause *C) {
367
  if (!C) {
368
    ColorScope Color(OS, ShowColors, NullColor);
369
    OS << "<<<NULL>>> OMPClause";
370
    return;
371
  }
372
  {
373
    ColorScope Color(OS, ShowColors, AttrColor);
374
    StringRef ClauseName(llvm::omp::getOpenMPClauseName(C->getClauseKind()));
375
    OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
376
       << ClauseName.drop_front() << "Clause";
377
  }
378
  dumpPointer(C);
379
  dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
380
  if (C->isImplicit())
381
    OS << " <implicit>";
382
}
383

384
void TextNodeDumper::Visit(const OpenACCClause *C) {
385
  if (!C) {
386
    ColorScope Color(OS, ShowColors, NullColor);
387
    OS << "<<<NULL>>> OpenACCClause";
388
    return;
389
  }
390
  {
391
    ColorScope Color(OS, ShowColors, AttrColor);
392
    OS << C->getClauseKind();
393

394
    // Handle clauses with parens for types that have no children, likely
395
    // because there is no sub expression.
396
    switch (C->getClauseKind()) {
397
    case OpenACCClauseKind::Default:
398
      OS << '(' << cast<OpenACCDefaultClause>(C)->getDefaultClauseKind() << ')';
399
      break;
400
    case OpenACCClauseKind::Async:
401
    case OpenACCClauseKind::Auto:
402
    case OpenACCClauseKind::Attach:
403
    case OpenACCClauseKind::Copy:
404
    case OpenACCClauseKind::PCopy:
405
    case OpenACCClauseKind::PresentOrCopy:
406
    case OpenACCClauseKind::If:
407
    case OpenACCClauseKind::Independent:
408
    case OpenACCClauseKind::DevicePtr:
409
    case OpenACCClauseKind::FirstPrivate:
410
    case OpenACCClauseKind::NoCreate:
411
    case OpenACCClauseKind::NumGangs:
412
    case OpenACCClauseKind::NumWorkers:
413
    case OpenACCClauseKind::Present:
414
    case OpenACCClauseKind::Private:
415
    case OpenACCClauseKind::Self:
416
    case OpenACCClauseKind::Seq:
417
    case OpenACCClauseKind::VectorLength:
418
      // The condition expression will be printed as a part of the 'children',
419
      // but print 'clause' here so it is clear what is happening from the dump.
420
      OS << " clause";
421
      break;
422
    case OpenACCClauseKind::CopyIn:
423
    case OpenACCClauseKind::PCopyIn:
424
    case OpenACCClauseKind::PresentOrCopyIn:
425
      OS << " clause";
426
      if (cast<OpenACCCopyInClause>(C)->isReadOnly())
427
        OS << " : readonly";
428
      break;
429
    case OpenACCClauseKind::CopyOut:
430
    case OpenACCClauseKind::PCopyOut:
431
    case OpenACCClauseKind::PresentOrCopyOut:
432
      OS << " clause";
433
      if (cast<OpenACCCopyOutClause>(C)->isZero())
434
        OS << " : zero";
435
      break;
436
    case OpenACCClauseKind::Create:
437
    case OpenACCClauseKind::PCreate:
438
    case OpenACCClauseKind::PresentOrCreate:
439
      OS << " clause";
440
      if (cast<OpenACCCreateClause>(C)->isZero())
441
        OS << " : zero";
442
      break;
443
    case OpenACCClauseKind::Wait:
444
      OS << " clause";
445
      if (cast<OpenACCWaitClause>(C)->hasDevNumExpr())
446
        OS << " has devnum";
447
      if (cast<OpenACCWaitClause>(C)->hasQueuesTag())
448
        OS << " has queues tag";
449
      break;
450
    case OpenACCClauseKind::DeviceType:
451
    case OpenACCClauseKind::DType:
452
      OS << "(";
453
      llvm::interleaveComma(
454
          cast<OpenACCDeviceTypeClause>(C)->getArchitectures(), OS,
455
          [&](const DeviceTypeArgument &Arch) {
456
            if (Arch.first == nullptr)
457
              OS << "*";
458
            else
459
              OS << Arch.first->getName();
460
          });
461
      OS << ")";
462
      break;
463
    case OpenACCClauseKind::Reduction:
464
      OS << " clause Operator: "
465
         << cast<OpenACCReductionClause>(C)->getReductionOp();
466
      break;
467
    default:
468
      // Nothing to do here.
469
      break;
470
    }
471
  }
472
  dumpPointer(C);
473
  dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
474
}
475

476
void TextNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) {
477
  const TypeSourceInfo *TSI = A.getTypeSourceInfo();
478
  if (TSI) {
479
    OS << "case ";
480
    dumpType(TSI->getType());
481
  } else {
482
    OS << "default";
483
  }
484

485
  if (A.isSelected())
486
    OS << " selected";
487
}
488

489
void TextNodeDumper::Visit(const ConceptReference *R) {
490
  if (!R) {
491
    ColorScope Color(OS, ShowColors, NullColor);
492
    OS << "<<<NULL>>> ConceptReference";
493
    return;
494
  }
495

496
  OS << "ConceptReference";
497
  dumpPointer(R);
498
  dumpSourceRange(R->getSourceRange());
499
  OS << ' ';
500
  dumpBareDeclRef(R->getNamedConcept());
501
}
502

503
void TextNodeDumper::Visit(const concepts::Requirement *R) {
504
  if (!R) {
505
    ColorScope Color(OS, ShowColors, NullColor);
506
    OS << "<<<NULL>>> Requirement";
507
    return;
508
  }
509

510
  {
511
    ColorScope Color(OS, ShowColors, StmtColor);
512
    switch (R->getKind()) {
513
    case concepts::Requirement::RK_Type:
514
      OS << "TypeRequirement";
515
      break;
516
    case concepts::Requirement::RK_Simple:
517
      OS << "SimpleRequirement";
518
      break;
519
    case concepts::Requirement::RK_Compound:
520
      OS << "CompoundRequirement";
521
      break;
522
    case concepts::Requirement::RK_Nested:
523
      OS << "NestedRequirement";
524
      break;
525
    }
526
  }
527

528
  dumpPointer(R);
529

530
  if (auto *ER = dyn_cast<concepts::ExprRequirement>(R)) {
531
    if (ER->hasNoexceptRequirement())
532
      OS << " noexcept";
533
  }
534

535
  if (R->isDependent())
536
    OS << " dependent";
537
  else
538
    OS << (R->isSatisfied() ? " satisfied" : " unsatisfied");
539
  if (R->containsUnexpandedParameterPack())
540
    OS << " contains_unexpanded_pack";
541
}
542

543
static double GetApproxValue(const llvm::APFloat &F) {
544
  llvm::APFloat V = F;
545
  bool ignored;
546
  V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven,
547
            &ignored);
548
  return V.convertToDouble();
549
}
550

551
/// True if the \p APValue \p Value can be folded onto the current line.
552
static bool isSimpleAPValue(const APValue &Value) {
553
  switch (Value.getKind()) {
554
  case APValue::None:
555
  case APValue::Indeterminate:
556
  case APValue::Int:
557
  case APValue::Float:
558
  case APValue::FixedPoint:
559
  case APValue::ComplexInt:
560
  case APValue::ComplexFloat:
561
  case APValue::LValue:
562
  case APValue::MemberPointer:
563
  case APValue::AddrLabelDiff:
564
    return true;
565
  case APValue::Vector:
566
  case APValue::Array:
567
  case APValue::Struct:
568
    return false;
569
  case APValue::Union:
570
    return isSimpleAPValue(Value.getUnionValue());
571
  }
572
  llvm_unreachable("unexpected APValue kind!");
573
}
574

575
/// Dump the children of the \p APValue \p Value.
576
///
577
/// \param[in] Value          The \p APValue to visit
578
/// \param[in] Ty             The \p QualType passed to \p Visit
579
///
580
/// \param[in] IdxToChildFun  A function mapping an \p APValue and an index
581
///                           to one of the child of the \p APValue
582
///
583
/// \param[in] NumChildren    \p IdxToChildFun will be called on \p Value with
584
///                           the indices in the range \p [0,NumChildren(
585
///
586
/// \param[in] LabelSingular  The label to use on a line with a single child
587
/// \param[in] LabelPlurial   The label to use on a line with multiple children
588
void TextNodeDumper::dumpAPValueChildren(
589
    const APValue &Value, QualType Ty,
590
    const APValue &(*IdxToChildFun)(const APValue &, unsigned),
591
    unsigned NumChildren, StringRef LabelSingular, StringRef LabelPlurial) {
592
  // To save some vertical space we print up to MaxChildrenPerLine APValues
593
  // considered to be simple (by isSimpleAPValue) on a single line.
594
  constexpr unsigned MaxChildrenPerLine = 4;
595
  unsigned I = 0;
596
  while (I < NumChildren) {
597
    unsigned J = I;
598
    while (J < NumChildren) {
599
      if (isSimpleAPValue(IdxToChildFun(Value, J)) &&
600
          (J - I < MaxChildrenPerLine)) {
601
        ++J;
602
        continue;
603
      }
604
      break;
605
    }
606

607
    J = std::max(I + 1, J);
608

609
    // Print [I,J) on a single line.
610
    AddChild(J - I > 1 ? LabelPlurial : LabelSingular, [=]() {
611
      for (unsigned X = I; X < J; ++X) {
612
        Visit(IdxToChildFun(Value, X), Ty);
613
        if (X + 1 != J)
614
          OS << ", ";
615
      }
616
    });
617
    I = J;
618
  }
619
}
620

621
void TextNodeDumper::Visit(const APValue &Value, QualType Ty) {
622
  ColorScope Color(OS, ShowColors, ValueKindColor);
623
  switch (Value.getKind()) {
624
  case APValue::None:
625
    OS << "None";
626
    return;
627
  case APValue::Indeterminate:
628
    OS << "Indeterminate";
629
    return;
630
  case APValue::Int:
631
    OS << "Int ";
632
    {
633
      ColorScope Color(OS, ShowColors, ValueColor);
634
      OS << Value.getInt();
635
    }
636
    return;
637
  case APValue::Float:
638
    OS << "Float ";
639
    {
640
      ColorScope Color(OS, ShowColors, ValueColor);
641
      OS << GetApproxValue(Value.getFloat());
642
    }
643
    return;
644
  case APValue::FixedPoint:
645
    OS << "FixedPoint ";
646
    {
647
      ColorScope Color(OS, ShowColors, ValueColor);
648
      OS << Value.getFixedPoint();
649
    }
650
    return;
651
  case APValue::Vector: {
652
    unsigned VectorLength = Value.getVectorLength();
653
    OS << "Vector length=" << VectorLength;
654

655
    dumpAPValueChildren(
656
        Value, Ty,
657
        [](const APValue &Value, unsigned Index) -> const APValue & {
658
          return Value.getVectorElt(Index);
659
        },
660
        VectorLength, "element", "elements");
661
    return;
662
  }
663
  case APValue::ComplexInt:
664
    OS << "ComplexInt ";
665
    {
666
      ColorScope Color(OS, ShowColors, ValueColor);
667
      OS << Value.getComplexIntReal() << " + " << Value.getComplexIntImag()
668
         << 'i';
669
    }
670
    return;
671
  case APValue::ComplexFloat:
672
    OS << "ComplexFloat ";
673
    {
674
      ColorScope Color(OS, ShowColors, ValueColor);
675
      OS << GetApproxValue(Value.getComplexFloatReal()) << " + "
676
         << GetApproxValue(Value.getComplexFloatImag()) << 'i';
677
    }
678
    return;
679
  case APValue::LValue:
680
    (void)Context;
681
    OS << "LValue <todo>";
682
    return;
683
  case APValue::Array: {
684
    unsigned ArraySize = Value.getArraySize();
685
    unsigned NumInitializedElements = Value.getArrayInitializedElts();
686
    OS << "Array size=" << ArraySize;
687

688
    dumpAPValueChildren(
689
        Value, Ty,
690
        [](const APValue &Value, unsigned Index) -> const APValue & {
691
          return Value.getArrayInitializedElt(Index);
692
        },
693
        NumInitializedElements, "element", "elements");
694

695
    if (Value.hasArrayFiller()) {
696
      AddChild("filler", [=] {
697
        {
698
          ColorScope Color(OS, ShowColors, ValueColor);
699
          OS << ArraySize - NumInitializedElements << " x ";
700
        }
701
        Visit(Value.getArrayFiller(), Ty);
702
      });
703
    }
704

705
    return;
706
  }
707
  case APValue::Struct: {
708
    OS << "Struct";
709

710
    dumpAPValueChildren(
711
        Value, Ty,
712
        [](const APValue &Value, unsigned Index) -> const APValue & {
713
          return Value.getStructBase(Index);
714
        },
715
        Value.getStructNumBases(), "base", "bases");
716

717
    dumpAPValueChildren(
718
        Value, Ty,
719
        [](const APValue &Value, unsigned Index) -> const APValue & {
720
          return Value.getStructField(Index);
721
        },
722
        Value.getStructNumFields(), "field", "fields");
723

724
    return;
725
  }
726
  case APValue::Union: {
727
    OS << "Union";
728
    {
729
      ColorScope Color(OS, ShowColors, ValueColor);
730
      if (const FieldDecl *FD = Value.getUnionField())
731
        OS << " ." << *cast<NamedDecl>(FD);
732
    }
733
    // If the union value is considered to be simple, fold it into the
734
    // current line to save some vertical space.
735
    const APValue &UnionValue = Value.getUnionValue();
736
    if (isSimpleAPValue(UnionValue)) {
737
      OS << ' ';
738
      Visit(UnionValue, Ty);
739
    } else {
740
      AddChild([=] { Visit(UnionValue, Ty); });
741
    }
742

743
    return;
744
  }
745
  case APValue::MemberPointer:
746
    OS << "MemberPointer <todo>";
747
    return;
748
  case APValue::AddrLabelDiff:
749
    OS << "AddrLabelDiff <todo>";
750
    return;
751
  }
752
  llvm_unreachable("Unknown APValue kind!");
753
}
754

755
void TextNodeDumper::dumpPointer(const void *Ptr) {
756
  ColorScope Color(OS, ShowColors, AddressColor);
757
  OS << ' ' << Ptr;
758
}
759

760
void TextNodeDumper::dumpLocation(SourceLocation Loc) {
761
  if (!SM)
762
    return;
763

764
  ColorScope Color(OS, ShowColors, LocationColor);
765
  SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
766

767
  // The general format we print out is filename:line:col, but we drop pieces
768
  // that haven't changed since the last loc printed.
769
  PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
770

771
  if (PLoc.isInvalid()) {
772
    OS << "<invalid sloc>";
773
    return;
774
  }
775

776
  if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
777
    OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':'
778
       << PLoc.getColumn();
779
    LastLocFilename = PLoc.getFilename();
780
    LastLocLine = PLoc.getLine();
781
  } else if (PLoc.getLine() != LastLocLine) {
782
    OS << "line" << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
783
    LastLocLine = PLoc.getLine();
784
  } else {
785
    OS << "col" << ':' << PLoc.getColumn();
786
  }
787
}
788

789
void TextNodeDumper::dumpSourceRange(SourceRange R) {
790
  // Can't translate locations if a SourceManager isn't available.
791
  if (!SM)
792
    return;
793

794
  OS << " <";
795
  dumpLocation(R.getBegin());
796
  if (R.getBegin() != R.getEnd()) {
797
    OS << ", ";
798
    dumpLocation(R.getEnd());
799
  }
800
  OS << ">";
801

802
  // <t2.c:123:421[blah], t2.c:412:321>
803
}
804

805
void TextNodeDumper::dumpBareType(QualType T, bool Desugar) {
806
  ColorScope Color(OS, ShowColors, TypeColor);
807

808
  SplitQualType T_split = T.split();
809
  std::string T_str = QualType::getAsString(T_split, PrintPolicy);
810
  OS << "'" << T_str << "'";
811

812
  if (Desugar && !T.isNull()) {
813
    // If the type is sugared, also dump a (shallow) desugared type when
814
    // it is visibly different.
815
    SplitQualType D_split = T.getSplitDesugaredType();
816
    if (T_split != D_split) {
817
      std::string D_str = QualType::getAsString(D_split, PrintPolicy);
818
      if (T_str != D_str)
819
        OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'";
820
    }
821
  }
822
}
823

824
void TextNodeDumper::dumpType(QualType T) {
825
  OS << ' ';
826
  dumpBareType(T);
827
}
828

829
void TextNodeDumper::dumpBareDeclRef(const Decl *D) {
830
  if (!D) {
831
    ColorScope Color(OS, ShowColors, NullColor);
832
    OS << "<<<NULL>>>";
833
    return;
834
  }
835

836
  {
837
    ColorScope Color(OS, ShowColors, DeclKindNameColor);
838
    OS << D->getDeclKindName();
839
  }
840
  dumpPointer(D);
841

842
  if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
843
    ColorScope Color(OS, ShowColors, DeclNameColor);
844
    OS << " '" << ND->getDeclName() << '\'';
845
  }
846

847
  if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
848
    dumpType(VD->getType());
849
}
850

851
void TextNodeDumper::dumpName(const NamedDecl *ND) {
852
  if (ND->getDeclName()) {
853
    ColorScope Color(OS, ShowColors, DeclNameColor);
854
    OS << ' ' << ND->getDeclName();
855
  }
856
}
857

858
void TextNodeDumper::dumpAccessSpecifier(AccessSpecifier AS) {
859
  const auto AccessSpelling = getAccessSpelling(AS);
860
  if (AccessSpelling.empty())
861
    return;
862
  OS << AccessSpelling;
863
}
864

865
void TextNodeDumper::dumpCleanupObject(
866
    const ExprWithCleanups::CleanupObject &C) {
867
  if (auto *BD = C.dyn_cast<BlockDecl *>())
868
    dumpDeclRef(BD, "cleanup");
869
  else if (auto *CLE = C.dyn_cast<CompoundLiteralExpr *>())
870
    AddChild([=] {
871
      OS << "cleanup ";
872
      {
873
        ColorScope Color(OS, ShowColors, StmtColor);
874
        OS << CLE->getStmtClassName();
875
      }
876
      dumpPointer(CLE);
877
    });
878
  else
879
    llvm_unreachable("unexpected cleanup type");
880
}
881

882
void clang::TextNodeDumper::dumpTemplateSpecializationKind(
883
    TemplateSpecializationKind TSK) {
884
  switch (TSK) {
885
  case TSK_Undeclared:
886
    break;
887
  case TSK_ImplicitInstantiation:
888
    OS << " implicit_instantiation";
889
    break;
890
  case TSK_ExplicitSpecialization:
891
    OS << " explicit_specialization";
892
    break;
893
  case TSK_ExplicitInstantiationDeclaration:
894
    OS << " explicit_instantiation_declaration";
895
    break;
896
  case TSK_ExplicitInstantiationDefinition:
897
    OS << " explicit_instantiation_definition";
898
    break;
899
  }
900
}
901

902
void clang::TextNodeDumper::dumpNestedNameSpecifier(const NestedNameSpecifier *NNS) {
903
  if (!NNS)
904
    return;
905

906
  AddChild([=] {
907
    OS << "NestedNameSpecifier";
908

909
    switch (NNS->getKind()) {
910
    case NestedNameSpecifier::Identifier:
911
      OS << " Identifier";
912
      OS << " '" << NNS->getAsIdentifier()->getName() << "'";
913
      break;
914
    case NestedNameSpecifier::Namespace:
915
      OS << " "; // "Namespace" is printed as the decl kind.
916
      dumpBareDeclRef(NNS->getAsNamespace());
917
      break;
918
    case NestedNameSpecifier::NamespaceAlias:
919
      OS << " "; // "NamespaceAlias" is printed as the decl kind.
920
      dumpBareDeclRef(NNS->getAsNamespaceAlias());
921
      break;
922
    case NestedNameSpecifier::TypeSpec:
923
      OS << " TypeSpec";
924
      dumpType(QualType(NNS->getAsType(), 0));
925
      break;
926
    case NestedNameSpecifier::TypeSpecWithTemplate:
927
      OS << " TypeSpecWithTemplate";
928
      dumpType(QualType(NNS->getAsType(), 0));
929
      break;
930
    case NestedNameSpecifier::Global:
931
      OS << " Global";
932
      break;
933
    case NestedNameSpecifier::Super:
934
      OS << " Super";
935
      break;
936
    }
937

938
    dumpNestedNameSpecifier(NNS->getPrefix());
939
  });
940
}
941

942
void TextNodeDumper::dumpDeclRef(const Decl *D, StringRef Label) {
943
  if (!D)
944
    return;
945

946
  AddChild([=] {
947
    if (!Label.empty())
948
      OS << Label << ' ';
949
    dumpBareDeclRef(D);
950
  });
951
}
952

953
void TextNodeDumper::dumpTemplateArgument(const TemplateArgument &TA) {
954
  llvm::SmallString<128> Str;
955
  {
956
    llvm::raw_svector_ostream SS(Str);
957
    TA.print(PrintPolicy, SS, /*IncludeType=*/true);
958
  }
959
  OS << " '" << Str << "'";
960

961
  if (!Context)
962
    return;
963

964
  if (TemplateArgument CanonTA = Context->getCanonicalTemplateArgument(TA);
965
      !CanonTA.structurallyEquals(TA)) {
966
    llvm::SmallString<128> CanonStr;
967
    {
968
      llvm::raw_svector_ostream SS(CanonStr);
969
      CanonTA.print(PrintPolicy, SS, /*IncludeType=*/true);
970
    }
971
    if (CanonStr != Str)
972
      OS << ":'" << CanonStr << "'";
973
  }
974
}
975

976
const char *TextNodeDumper::getCommandName(unsigned CommandID) {
977
  if (Traits)
978
    return Traits->getCommandInfo(CommandID)->Name;
979
  const comments::CommandInfo *Info =
980
      comments::CommandTraits::getBuiltinCommandInfo(CommandID);
981
  if (Info)
982
    return Info->Name;
983
  return "<not a builtin command>";
984
}
985

986
void TextNodeDumper::printFPOptions(FPOptionsOverride FPO) {
987
#define OPTION(NAME, TYPE, WIDTH, PREVIOUS)                                    \
988
  if (FPO.has##NAME##Override())                                               \
989
    OS << " " #NAME "=" << FPO.get##NAME##Override();
990
#include "clang/Basic/FPOptions.def"
991
}
992

993
void TextNodeDumper::visitTextComment(const comments::TextComment *C,
994
                                      const comments::FullComment *) {
995
  OS << " Text=\"" << C->getText() << "\"";
996
}
997

998
void TextNodeDumper::visitInlineCommandComment(
999
    const comments::InlineCommandComment *C, const comments::FullComment *) {
1000
  OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
1001
  switch (C->getRenderKind()) {
1002
  case comments::InlineCommandRenderKind::Normal:
1003
    OS << " RenderNormal";
1004
    break;
1005
  case comments::InlineCommandRenderKind::Bold:
1006
    OS << " RenderBold";
1007
    break;
1008
  case comments::InlineCommandRenderKind::Monospaced:
1009
    OS << " RenderMonospaced";
1010
    break;
1011
  case comments::InlineCommandRenderKind::Emphasized:
1012
    OS << " RenderEmphasized";
1013
    break;
1014
  case comments::InlineCommandRenderKind::Anchor:
1015
    OS << " RenderAnchor";
1016
    break;
1017
  }
1018

1019
  for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
1020
    OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
1021
}
1022

1023
void TextNodeDumper::visitHTMLStartTagComment(
1024
    const comments::HTMLStartTagComment *C, const comments::FullComment *) {
1025
  OS << " Name=\"" << C->getTagName() << "\"";
1026
  if (C->getNumAttrs() != 0) {
1027
    OS << " Attrs: ";
1028
    for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
1029
      const comments::HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
1030
      OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
1031
    }
1032
  }
1033
  if (C->isSelfClosing())
1034
    OS << " SelfClosing";
1035
}
1036

1037
void TextNodeDumper::visitHTMLEndTagComment(
1038
    const comments::HTMLEndTagComment *C, const comments::FullComment *) {
1039
  OS << " Name=\"" << C->getTagName() << "\"";
1040
}
1041

1042
void TextNodeDumper::visitBlockCommandComment(
1043
    const comments::BlockCommandComment *C, const comments::FullComment *) {
1044
  OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
1045
  for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
1046
    OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
1047
}
1048

1049
void TextNodeDumper::visitParamCommandComment(
1050
    const comments::ParamCommandComment *C, const comments::FullComment *FC) {
1051
  OS << " "
1052
     << comments::ParamCommandComment::getDirectionAsString(C->getDirection());
1053

1054
  if (C->isDirectionExplicit())
1055
    OS << " explicitly";
1056
  else
1057
    OS << " implicitly";
1058

1059
  if (C->hasParamName()) {
1060
    if (C->isParamIndexValid())
1061
      OS << " Param=\"" << C->getParamName(FC) << "\"";
1062
    else
1063
      OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
1064
  }
1065

1066
  if (C->isParamIndexValid() && !C->isVarArgParam())
1067
    OS << " ParamIndex=" << C->getParamIndex();
1068
}
1069

1070
void TextNodeDumper::visitTParamCommandComment(
1071
    const comments::TParamCommandComment *C, const comments::FullComment *FC) {
1072
  if (C->hasParamName()) {
1073
    if (C->isPositionValid())
1074
      OS << " Param=\"" << C->getParamName(FC) << "\"";
1075
    else
1076
      OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
1077
  }
1078

1079
  if (C->isPositionValid()) {
1080
    OS << " Position=<";
1081
    for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
1082
      OS << C->getIndex(i);
1083
      if (i != e - 1)
1084
        OS << ", ";
1085
    }
1086
    OS << ">";
1087
  }
1088
}
1089

1090
void TextNodeDumper::visitVerbatimBlockComment(
1091
    const comments::VerbatimBlockComment *C, const comments::FullComment *) {
1092
  OS << " Name=\"" << getCommandName(C->getCommandID())
1093
     << "\""
1094
        " CloseName=\""
1095
     << C->getCloseName() << "\"";
1096
}
1097

1098
void TextNodeDumper::visitVerbatimBlockLineComment(
1099
    const comments::VerbatimBlockLineComment *C,
1100
    const comments::FullComment *) {
1101
  OS << " Text=\"" << C->getText() << "\"";
1102
}
1103

1104
void TextNodeDumper::visitVerbatimLineComment(
1105
    const comments::VerbatimLineComment *C, const comments::FullComment *) {
1106
  OS << " Text=\"" << C->getText() << "\"";
1107
}
1108

1109
void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument &) {
1110
  OS << " null";
1111
}
1112

1113
void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) {
1114
  OS << " type";
1115
  dumpTemplateArgument(TA);
1116
}
1117

1118
void TextNodeDumper::VisitDeclarationTemplateArgument(
1119
    const TemplateArgument &TA) {
1120
  OS << " decl";
1121
  dumpTemplateArgument(TA);
1122
  dumpDeclRef(TA.getAsDecl());
1123
}
1124

1125
void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &TA) {
1126
  OS << " nullptr";
1127
  dumpTemplateArgument(TA);
1128
}
1129

1130
void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) {
1131
  OS << " integral";
1132
  dumpTemplateArgument(TA);
1133
}
1134

1135
void TextNodeDumper::dumpTemplateName(TemplateName TN, StringRef Label) {
1136
  AddChild(Label, [=] {
1137
    {
1138
      llvm::SmallString<128> Str;
1139
      {
1140
        llvm::raw_svector_ostream SS(Str);
1141
        TN.print(SS, PrintPolicy);
1142
      }
1143
      OS << "'" << Str << "'";
1144

1145
      if (Context) {
1146
        if (TemplateName CanonTN = Context->getCanonicalTemplateName(TN);
1147
            CanonTN != TN) {
1148
          llvm::SmallString<128> CanonStr;
1149
          {
1150
            llvm::raw_svector_ostream SS(CanonStr);
1151
            CanonTN.print(SS, PrintPolicy);
1152
          }
1153
          if (CanonStr != Str)
1154
            OS << ":'" << CanonStr << "'";
1155
        }
1156
      }
1157
    }
1158
    dumpBareTemplateName(TN);
1159
  });
1160
}
1161

1162
void TextNodeDumper::dumpBareTemplateName(TemplateName TN) {
1163
  switch (TN.getKind()) {
1164
  case TemplateName::Template:
1165
    AddChild([=] { Visit(TN.getAsTemplateDecl()); });
1166
    return;
1167
  case TemplateName::UsingTemplate: {
1168
    const UsingShadowDecl *USD = TN.getAsUsingShadowDecl();
1169
    AddChild([=] { Visit(USD); });
1170
    AddChild("target", [=] { Visit(USD->getTargetDecl()); });
1171
    return;
1172
  }
1173
  case TemplateName::QualifiedTemplate: {
1174
    OS << " qualified";
1175
    const QualifiedTemplateName *QTN = TN.getAsQualifiedTemplateName();
1176
    if (QTN->hasTemplateKeyword())
1177
      OS << " keyword";
1178
    dumpNestedNameSpecifier(QTN->getQualifier());
1179
    dumpBareTemplateName(QTN->getUnderlyingTemplate());
1180
    return;
1181
  }
1182
  case TemplateName::DependentTemplate: {
1183
    OS << " dependent";
1184
    const DependentTemplateName *DTN = TN.getAsDependentTemplateName();
1185
    dumpNestedNameSpecifier(DTN->getQualifier());
1186
    return;
1187
  }
1188
  case TemplateName::SubstTemplateTemplateParm: {
1189
    OS << " subst";
1190
    const SubstTemplateTemplateParmStorage *STS =
1191
        TN.getAsSubstTemplateTemplateParm();
1192
    OS << " index " << STS->getIndex();
1193
    if (std::optional<unsigned int> PackIndex = STS->getPackIndex())
1194
      OS << " pack_index " << *PackIndex;
1195
    if (const TemplateTemplateParmDecl *P = STS->getParameter())
1196
      AddChild("parameter", [=] { Visit(P); });
1197
    dumpDeclRef(STS->getAssociatedDecl(), "associated");
1198
    dumpTemplateName(STS->getReplacement(), "replacement");
1199
    return;
1200
  }
1201
  // FIXME: Implement these.
1202
  case TemplateName::OverloadedTemplate:
1203
    OS << " overloaded";
1204
    return;
1205
  case TemplateName::AssumedTemplate:
1206
    OS << " assumed";
1207
    return;
1208
  case TemplateName::SubstTemplateTemplateParmPack:
1209
    OS << " subst_pack";
1210
    return;
1211
  }
1212
  llvm_unreachable("Unexpected TemplateName Kind");
1213
}
1214

1215
void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) {
1216
  OS << " template";
1217
  dumpTemplateArgument(TA);
1218
  dumpBareTemplateName(TA.getAsTemplate());
1219
}
1220

1221
void TextNodeDumper::VisitTemplateExpansionTemplateArgument(
1222
    const TemplateArgument &TA) {
1223
  OS << " template expansion";
1224
  dumpTemplateArgument(TA);
1225
  dumpBareTemplateName(TA.getAsTemplateOrTemplatePattern());
1226
}
1227

1228
void TextNodeDumper::VisitExpressionTemplateArgument(
1229
    const TemplateArgument &TA) {
1230
  OS << " expr";
1231
  dumpTemplateArgument(TA);
1232
}
1233

1234
void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &TA) {
1235
  OS << " pack";
1236
  dumpTemplateArgument(TA);
1237
}
1238

1239
static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
1240
  if (Node->path_empty())
1241
    return;
1242

1243
  OS << " (";
1244
  bool First = true;
1245
  for (CastExpr::path_const_iterator I = Node->path_begin(),
1246
                                     E = Node->path_end();
1247
       I != E; ++I) {
1248
    const CXXBaseSpecifier *Base = *I;
1249
    if (!First)
1250
      OS << " -> ";
1251

1252
    const auto *RD =
1253
        cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl());
1254

1255
    if (Base->isVirtual())
1256
      OS << "virtual ";
1257
    OS << RD->getName();
1258
    First = false;
1259
  }
1260

1261
  OS << ')';
1262
}
1263

1264
void TextNodeDumper::VisitIfStmt(const IfStmt *Node) {
1265
  if (Node->hasInitStorage())
1266
    OS << " has_init";
1267
  if (Node->hasVarStorage())
1268
    OS << " has_var";
1269
  if (Node->hasElseStorage())
1270
    OS << " has_else";
1271
  if (Node->isConstexpr())
1272
    OS << " constexpr";
1273
  if (Node->isConsteval()) {
1274
    OS << " ";
1275
    if (Node->isNegatedConsteval())
1276
      OS << "!";
1277
    OS << "consteval";
1278
  }
1279
}
1280

1281
void TextNodeDumper::VisitSwitchStmt(const SwitchStmt *Node) {
1282
  if (Node->hasInitStorage())
1283
    OS << " has_init";
1284
  if (Node->hasVarStorage())
1285
    OS << " has_var";
1286
}
1287

1288
void TextNodeDumper::VisitWhileStmt(const WhileStmt *Node) {
1289
  if (Node->hasVarStorage())
1290
    OS << " has_var";
1291
}
1292

1293
void TextNodeDumper::VisitLabelStmt(const LabelStmt *Node) {
1294
  OS << " '" << Node->getName() << "'";
1295
  if (Node->isSideEntry())
1296
    OS << " side_entry";
1297
}
1298

1299
void TextNodeDumper::VisitGotoStmt(const GotoStmt *Node) {
1300
  OS << " '" << Node->getLabel()->getName() << "'";
1301
  dumpPointer(Node->getLabel());
1302
}
1303

1304
void TextNodeDumper::VisitCaseStmt(const CaseStmt *Node) {
1305
  if (Node->caseStmtIsGNURange())
1306
    OS << " gnu_range";
1307
}
1308

1309
void clang::TextNodeDumper::VisitReturnStmt(const ReturnStmt *Node) {
1310
  if (const VarDecl *Cand = Node->getNRVOCandidate()) {
1311
    OS << " nrvo_candidate(";
1312
    dumpBareDeclRef(Cand);
1313
    OS << ")";
1314
  }
1315
}
1316

1317
void clang::TextNodeDumper::VisitCoawaitExpr(const CoawaitExpr *Node) {
1318
  if (Node->isImplicit())
1319
    OS << " implicit";
1320
}
1321

1322
void clang::TextNodeDumper::VisitCoreturnStmt(const CoreturnStmt *Node) {
1323
  if (Node->isImplicit())
1324
    OS << " implicit";
1325
}
1326

1327
void TextNodeDumper::VisitConstantExpr(const ConstantExpr *Node) {
1328
  if (Node->hasAPValueResult())
1329
    AddChild("value",
1330
             [=] { Visit(Node->getAPValueResult(), Node->getType()); });
1331
}
1332

1333
void TextNodeDumper::VisitCallExpr(const CallExpr *Node) {
1334
  if (Node->usesADL())
1335
    OS << " adl";
1336
  if (Node->hasStoredFPFeatures())
1337
    printFPOptions(Node->getFPFeatures());
1338
}
1339

1340
void TextNodeDumper::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *Node) {
1341
  const char *OperatorSpelling = clang::getOperatorSpelling(Node->getOperator());
1342
  if (OperatorSpelling)
1343
    OS << " '" << OperatorSpelling << "'";
1344

1345
  VisitCallExpr(Node);
1346
}
1347

1348
void TextNodeDumper::VisitCastExpr(const CastExpr *Node) {
1349
  OS << " <";
1350
  {
1351
    ColorScope Color(OS, ShowColors, CastColor);
1352
    OS << Node->getCastKindName();
1353
  }
1354
  dumpBasePath(OS, Node);
1355
  OS << ">";
1356
  if (Node->hasStoredFPFeatures())
1357
    printFPOptions(Node->getFPFeatures());
1358
}
1359

1360
void TextNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) {
1361
  VisitCastExpr(Node);
1362
  if (Node->isPartOfExplicitCast())
1363
    OS << " part_of_explicit_cast";
1364
}
1365

1366
void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
1367
  OS << " ";
1368
  dumpBareDeclRef(Node->getDecl());
1369
  dumpNestedNameSpecifier(Node->getQualifier());
1370
  if (Node->getDecl() != Node->getFoundDecl()) {
1371
    OS << " (";
1372
    dumpBareDeclRef(Node->getFoundDecl());
1373
    OS << ")";
1374
  }
1375
  switch (Node->isNonOdrUse()) {
1376
  case NOUR_None: break;
1377
  case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break;
1378
  case NOUR_Constant: OS << " non_odr_use_constant"; break;
1379
  case NOUR_Discarded: OS << " non_odr_use_discarded"; break;
1380
  }
1381
  if (Node->isCapturedByCopyInLambdaWithExplicitObjectParameter())
1382
    OS << " dependent_capture";
1383
  else if (Node->refersToEnclosingVariableOrCapture())
1384
    OS << " refers_to_enclosing_variable_or_capture";
1385

1386
  if (Node->isImmediateEscalating())
1387
    OS << " immediate-escalating";
1388
}
1389

1390
void clang::TextNodeDumper::VisitDependentScopeDeclRefExpr(
1391
    const DependentScopeDeclRefExpr *Node) {
1392

1393
  dumpNestedNameSpecifier(Node->getQualifier());
1394
}
1395

1396
void TextNodeDumper::VisitUnresolvedLookupExpr(
1397
    const UnresolvedLookupExpr *Node) {
1398
  OS << " (";
1399
  if (!Node->requiresADL())
1400
    OS << "no ";
1401
  OS << "ADL) = '" << Node->getName() << '\'';
1402

1403
  UnresolvedLookupExpr::decls_iterator I = Node->decls_begin(),
1404
                                       E = Node->decls_end();
1405
  if (I == E)
1406
    OS << " empty";
1407
  for (; I != E; ++I)
1408
    dumpPointer(*I);
1409
}
1410

1411
void TextNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) {
1412
  {
1413
    ColorScope Color(OS, ShowColors, DeclKindNameColor);
1414
    OS << " " << Node->getDecl()->getDeclKindName() << "Decl";
1415
  }
1416
  OS << "='" << *Node->getDecl() << "'";
1417
  dumpPointer(Node->getDecl());
1418
  if (Node->isFreeIvar())
1419
    OS << " isFreeIvar";
1420
}
1421

1422
void TextNodeDumper::VisitSYCLUniqueStableNameExpr(
1423
    const SYCLUniqueStableNameExpr *Node) {
1424
  dumpType(Node->getTypeSourceInfo()->getType());
1425
}
1426

1427
void TextNodeDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
1428
  OS << " " << PredefinedExpr::getIdentKindName(Node->getIdentKind());
1429
}
1430

1431
void TextNodeDumper::VisitCharacterLiteral(const CharacterLiteral *Node) {
1432
  ColorScope Color(OS, ShowColors, ValueColor);
1433
  OS << " " << Node->getValue();
1434
}
1435

1436
void TextNodeDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
1437
  bool isSigned = Node->getType()->isSignedIntegerType();
1438
  ColorScope Color(OS, ShowColors, ValueColor);
1439
  OS << " " << toString(Node->getValue(), 10, isSigned);
1440
}
1441

1442
void TextNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *Node) {
1443
  ColorScope Color(OS, ShowColors, ValueColor);
1444
  OS << " " << Node->getValueAsString(/*Radix=*/10);
1445
}
1446

1447
void TextNodeDumper::VisitFloatingLiteral(const FloatingLiteral *Node) {
1448
  ColorScope Color(OS, ShowColors, ValueColor);
1449
  OS << " " << Node->getValueAsApproximateDouble();
1450
}
1451

1452
void TextNodeDumper::VisitStringLiteral(const StringLiteral *Str) {
1453
  ColorScope Color(OS, ShowColors, ValueColor);
1454
  OS << " ";
1455
  Str->outputString(OS);
1456
}
1457

1458
void TextNodeDumper::VisitInitListExpr(const InitListExpr *ILE) {
1459
  if (auto *Field = ILE->getInitializedFieldInUnion()) {
1460
    OS << " field ";
1461
    dumpBareDeclRef(Field);
1462
  }
1463
}
1464

1465
void TextNodeDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
1466
  if (E->isResultDependent())
1467
    OS << " result_dependent";
1468
}
1469

1470
void TextNodeDumper::VisitUnaryOperator(const UnaryOperator *Node) {
1471
  OS << " " << (Node->isPostfix() ? "postfix" : "prefix") << " '"
1472
     << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1473
  if (!Node->canOverflow())
1474
    OS << " cannot overflow";
1475
  if (Node->hasStoredFPFeatures())
1476
    printFPOptions(Node->getStoredFPFeatures());
1477
}
1478

1479
void TextNodeDumper::VisitUnaryExprOrTypeTraitExpr(
1480
    const UnaryExprOrTypeTraitExpr *Node) {
1481
  OS << " " << getTraitSpelling(Node->getKind());
1482

1483
  if (Node->isArgumentType())
1484
    dumpType(Node->getArgumentType());
1485
}
1486

1487
void TextNodeDumper::VisitMemberExpr(const MemberExpr *Node) {
1488
  OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl();
1489
  dumpPointer(Node->getMemberDecl());
1490
  dumpNestedNameSpecifier(Node->getQualifier());
1491
  switch (Node->isNonOdrUse()) {
1492
  case NOUR_None: break;
1493
  case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break;
1494
  case NOUR_Constant: OS << " non_odr_use_constant"; break;
1495
  case NOUR_Discarded: OS << " non_odr_use_discarded"; break;
1496
  }
1497
}
1498

1499
void TextNodeDumper::VisitExtVectorElementExpr(
1500
    const ExtVectorElementExpr *Node) {
1501
  OS << " " << Node->getAccessor().getNameStart();
1502
}
1503

1504
void TextNodeDumper::VisitBinaryOperator(const BinaryOperator *Node) {
1505
  OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1506
  if (Node->hasStoredFPFeatures())
1507
    printFPOptions(Node->getStoredFPFeatures());
1508
}
1509

1510
void TextNodeDumper::VisitCompoundAssignOperator(
1511
    const CompoundAssignOperator *Node) {
1512
  OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
1513
     << "' ComputeLHSTy=";
1514
  dumpBareType(Node->getComputationLHSType());
1515
  OS << " ComputeResultTy=";
1516
  dumpBareType(Node->getComputationResultType());
1517
  if (Node->hasStoredFPFeatures())
1518
    printFPOptions(Node->getStoredFPFeatures());
1519
}
1520

1521
void TextNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) {
1522
  OS << " " << Node->getLabel()->getName();
1523
  dumpPointer(Node->getLabel());
1524
}
1525

1526
void TextNodeDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) {
1527
  OS << " " << Node->getCastName() << "<"
1528
     << Node->getTypeAsWritten().getAsString() << ">"
1529
     << " <" << Node->getCastKindName();
1530
  dumpBasePath(OS, Node);
1531
  OS << ">";
1532
}
1533

1534
void TextNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
1535
  OS << " " << (Node->getValue() ? "true" : "false");
1536
}
1537

1538
void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
1539
  if (Node->isImplicit())
1540
    OS << " implicit";
1541
  if (Node->isCapturedByCopyInLambdaWithExplicitObjectParameter())
1542
    OS << " dependent_capture";
1543
  OS << " this";
1544
}
1545

1546
void TextNodeDumper::VisitCXXFunctionalCastExpr(
1547
    const CXXFunctionalCastExpr *Node) {
1548
  OS << " functional cast to " << Node->getTypeAsWritten().getAsString() << " <"
1549
     << Node->getCastKindName() << ">";
1550
  if (Node->hasStoredFPFeatures())
1551
    printFPOptions(Node->getFPFeatures());
1552
}
1553

1554
void TextNodeDumper::VisitCXXStaticCastExpr(const CXXStaticCastExpr *Node) {
1555
  VisitCXXNamedCastExpr(Node);
1556
  if (Node->hasStoredFPFeatures())
1557
    printFPOptions(Node->getFPFeatures());
1558
}
1559

1560
void TextNodeDumper::VisitCXXUnresolvedConstructExpr(
1561
    const CXXUnresolvedConstructExpr *Node) {
1562
  dumpType(Node->getTypeAsWritten());
1563
  if (Node->isListInitialization())
1564
    OS << " list";
1565
}
1566

1567
void TextNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
1568
  CXXConstructorDecl *Ctor = Node->getConstructor();
1569
  dumpType(Ctor->getType());
1570
  if (Node->isElidable())
1571
    OS << " elidable";
1572
  if (Node->isListInitialization())
1573
    OS << " list";
1574
  if (Node->isStdInitListInitialization())
1575
    OS << " std::initializer_list";
1576
  if (Node->requiresZeroInitialization())
1577
    OS << " zeroing";
1578
  if (Node->isImmediateEscalating())
1579
    OS << " immediate-escalating";
1580
}
1581

1582
void TextNodeDumper::VisitCXXBindTemporaryExpr(
1583
    const CXXBindTemporaryExpr *Node) {
1584
  OS << " (CXXTemporary";
1585
  dumpPointer(Node);
1586
  OS << ")";
1587
}
1588

1589
void TextNodeDumper::VisitCXXNewExpr(const CXXNewExpr *Node) {
1590
  if (Node->isGlobalNew())
1591
    OS << " global";
1592
  if (Node->isArray())
1593
    OS << " array";
1594
  if (Node->getOperatorNew()) {
1595
    OS << ' ';
1596
    dumpBareDeclRef(Node->getOperatorNew());
1597
  }
1598
  // We could dump the deallocation function used in case of error, but it's
1599
  // usually not that interesting.
1600
}
1601

1602
void TextNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *Node) {
1603
  if (Node->isGlobalDelete())
1604
    OS << " global";
1605
  if (Node->isArrayForm())
1606
    OS << " array";
1607
  if (Node->getOperatorDelete()) {
1608
    OS << ' ';
1609
    dumpBareDeclRef(Node->getOperatorDelete());
1610
  }
1611
}
1612

1613
void TextNodeDumper::VisitTypeTraitExpr(const TypeTraitExpr *Node) {
1614
  OS << " " << getTraitSpelling(Node->getTrait());
1615
}
1616

1617
void TextNodeDumper::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *Node) {
1618
  OS << " " << getTraitSpelling(Node->getTrait());
1619
}
1620

1621
void TextNodeDumper::VisitExpressionTraitExpr(const ExpressionTraitExpr *Node) {
1622
  OS << " " << getTraitSpelling(Node->getTrait());
1623
}
1624

1625
void TextNodeDumper::VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *Node) {
1626
  if (Node->hasRewrittenInit())
1627
    OS << " has rewritten init";
1628
}
1629

1630
void TextNodeDumper::VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *Node) {
1631
  if (Node->hasRewrittenInit())
1632
    OS << " has rewritten init";
1633
}
1634

1635
void TextNodeDumper::VisitMaterializeTemporaryExpr(
1636
    const MaterializeTemporaryExpr *Node) {
1637
  if (const ValueDecl *VD = Node->getExtendingDecl()) {
1638
    OS << " extended by ";
1639
    dumpBareDeclRef(VD);
1640
  }
1641
}
1642

1643
void TextNodeDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) {
1644
  for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
1645
    dumpCleanupObject(Node->getObject(i));
1646
}
1647

1648
void TextNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
1649
  dumpPointer(Node->getPack());
1650
  dumpName(Node->getPack());
1651
}
1652

1653
void TextNodeDumper::VisitCXXDependentScopeMemberExpr(
1654
    const CXXDependentScopeMemberExpr *Node) {
1655
  OS << " " << (Node->isArrow() ? "->" : ".") << Node->getMember();
1656
}
1657

1658
void TextNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
1659
  OS << " selector=";
1660
  Node->getSelector().print(OS);
1661
  switch (Node->getReceiverKind()) {
1662
  case ObjCMessageExpr::Instance:
1663
    break;
1664

1665
  case ObjCMessageExpr::Class:
1666
    OS << " class=";
1667
    dumpBareType(Node->getClassReceiver());
1668
    break;
1669

1670
  case ObjCMessageExpr::SuperInstance:
1671
    OS << " super (instance)";
1672
    break;
1673

1674
  case ObjCMessageExpr::SuperClass:
1675
    OS << " super (class)";
1676
    break;
1677
  }
1678
}
1679

1680
void TextNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
1681
  if (auto *BoxingMethod = Node->getBoxingMethod()) {
1682
    OS << " selector=";
1683
    BoxingMethod->getSelector().print(OS);
1684
  }
1685
}
1686

1687
void TextNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
1688
  if (!Node->getCatchParamDecl())
1689
    OS << " catch all";
1690
}
1691

1692
void TextNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
1693
  dumpType(Node->getEncodedType());
1694
}
1695

1696
void TextNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
1697
  OS << " ";
1698
  Node->getSelector().print(OS);
1699
}
1700

1701
void TextNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
1702
  OS << ' ' << *Node->getProtocol();
1703
}
1704

1705
void TextNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) {
1706
  if (Node->isImplicitProperty()) {
1707
    OS << " Kind=MethodRef Getter=\"";
1708
    if (Node->getImplicitPropertyGetter())
1709
      Node->getImplicitPropertyGetter()->getSelector().print(OS);
1710
    else
1711
      OS << "(null)";
1712

1713
    OS << "\" Setter=\"";
1714
    if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
1715
      Setter->getSelector().print(OS);
1716
    else
1717
      OS << "(null)";
1718
    OS << "\"";
1719
  } else {
1720
    OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty()
1721
       << '"';
1722
  }
1723

1724
  if (Node->isSuperReceiver())
1725
    OS << " super";
1726

1727
  OS << " Messaging=";
1728
  if (Node->isMessagingGetter() && Node->isMessagingSetter())
1729
    OS << "Getter&Setter";
1730
  else if (Node->isMessagingGetter())
1731
    OS << "Getter";
1732
  else if (Node->isMessagingSetter())
1733
    OS << "Setter";
1734
}
1735

1736
void TextNodeDumper::VisitObjCSubscriptRefExpr(
1737
    const ObjCSubscriptRefExpr *Node) {
1738
  if (Node->isArraySubscriptRefExpr())
1739
    OS << " Kind=ArraySubscript GetterForArray=\"";
1740
  else
1741
    OS << " Kind=DictionarySubscript GetterForDictionary=\"";
1742
  if (Node->getAtIndexMethodDecl())
1743
    Node->getAtIndexMethodDecl()->getSelector().print(OS);
1744
  else
1745
    OS << "(null)";
1746

1747
  if (Node->isArraySubscriptRefExpr())
1748
    OS << "\" SetterForArray=\"";
1749
  else
1750
    OS << "\" SetterForDictionary=\"";
1751
  if (Node->setAtIndexMethodDecl())
1752
    Node->setAtIndexMethodDecl()->getSelector().print(OS);
1753
  else
1754
    OS << "(null)";
1755
}
1756

1757
void TextNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) {
1758
  OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
1759
}
1760

1761
void TextNodeDumper::VisitOMPIteratorExpr(const OMPIteratorExpr *Node) {
1762
  OS << " ";
1763
  for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) {
1764
    Visit(Node->getIteratorDecl(I));
1765
    OS << " = ";
1766
    const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I);
1767
    OS << " begin ";
1768
    Visit(Range.Begin);
1769
    OS << " end ";
1770
    Visit(Range.End);
1771
    if (Range.Step) {
1772
      OS << " step ";
1773
      Visit(Range.Step);
1774
    }
1775
  }
1776
}
1777

1778
void TextNodeDumper::VisitConceptSpecializationExpr(
1779
    const ConceptSpecializationExpr *Node) {
1780
  OS << " ";
1781
  dumpBareDeclRef(Node->getFoundDecl());
1782
}
1783

1784
void TextNodeDumper::VisitRequiresExpr(
1785
    const RequiresExpr *Node) {
1786
  if (!Node->isValueDependent())
1787
    OS << (Node->isSatisfied() ? " satisfied" : " unsatisfied");
1788
}
1789

1790
void TextNodeDumper::VisitRValueReferenceType(const ReferenceType *T) {
1791
  if (T->isSpelledAsLValue())
1792
    OS << " written as lvalue reference";
1793
}
1794

1795
void TextNodeDumper::VisitArrayType(const ArrayType *T) {
1796
  switch (T->getSizeModifier()) {
1797
  case ArraySizeModifier::Normal:
1798
    break;
1799
  case ArraySizeModifier::Static:
1800
    OS << " static";
1801
    break;
1802
  case ArraySizeModifier::Star:
1803
    OS << " *";
1804
    break;
1805
  }
1806
  OS << " " << T->getIndexTypeQualifiers().getAsString();
1807
}
1808

1809
void TextNodeDumper::VisitConstantArrayType(const ConstantArrayType *T) {
1810
  OS << " " << T->getSize();
1811
  VisitArrayType(T);
1812
}
1813

1814
void TextNodeDumper::VisitVariableArrayType(const VariableArrayType *T) {
1815
  OS << " ";
1816
  dumpSourceRange(T->getBracketsRange());
1817
  VisitArrayType(T);
1818
}
1819

1820
void TextNodeDumper::VisitDependentSizedArrayType(
1821
    const DependentSizedArrayType *T) {
1822
  VisitArrayType(T);
1823
  OS << " ";
1824
  dumpSourceRange(T->getBracketsRange());
1825
}
1826

1827
void TextNodeDumper::VisitDependentSizedExtVectorType(
1828
    const DependentSizedExtVectorType *T) {
1829
  OS << " ";
1830
  dumpLocation(T->getAttributeLoc());
1831
}
1832

1833
void TextNodeDumper::VisitVectorType(const VectorType *T) {
1834
  switch (T->getVectorKind()) {
1835
  case VectorKind::Generic:
1836
    break;
1837
  case VectorKind::AltiVecVector:
1838
    OS << " altivec";
1839
    break;
1840
  case VectorKind::AltiVecPixel:
1841
    OS << " altivec pixel";
1842
    break;
1843
  case VectorKind::AltiVecBool:
1844
    OS << " altivec bool";
1845
    break;
1846
  case VectorKind::Neon:
1847
    OS << " neon";
1848
    break;
1849
  case VectorKind::NeonPoly:
1850
    OS << " neon poly";
1851
    break;
1852
  case VectorKind::SveFixedLengthData:
1853
    OS << " fixed-length sve data vector";
1854
    break;
1855
  case VectorKind::SveFixedLengthPredicate:
1856
    OS << " fixed-length sve predicate vector";
1857
    break;
1858
  case VectorKind::RVVFixedLengthData:
1859
    OS << " fixed-length rvv data vector";
1860
    break;
1861
  case VectorKind::RVVFixedLengthMask:
1862
    OS << " fixed-length rvv mask vector";
1863
    break;
1864
  }
1865
  OS << " " << T->getNumElements();
1866
}
1867

1868
void TextNodeDumper::VisitFunctionType(const FunctionType *T) {
1869
  auto EI = T->getExtInfo();
1870
  if (EI.getNoReturn())
1871
    OS << " noreturn";
1872
  if (EI.getProducesResult())
1873
    OS << " produces_result";
1874
  if (EI.getHasRegParm())
1875
    OS << " regparm " << EI.getRegParm();
1876
  OS << " " << FunctionType::getNameForCallConv(EI.getCC());
1877
}
1878

1879
void TextNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) {
1880
  auto EPI = T->getExtProtoInfo();
1881
  if (EPI.HasTrailingReturn)
1882
    OS << " trailing_return";
1883
  if (T->isConst())
1884
    OS << " const";
1885
  if (T->isVolatile())
1886
    OS << " volatile";
1887
  if (T->isRestrict())
1888
    OS << " restrict";
1889
  if (T->getExtProtoInfo().Variadic)
1890
    OS << " variadic";
1891
  switch (EPI.RefQualifier) {
1892
  case RQ_None:
1893
    break;
1894
  case RQ_LValue:
1895
    OS << " &";
1896
    break;
1897
  case RQ_RValue:
1898
    OS << " &&";
1899
    break;
1900
  }
1901

1902
  switch (EPI.ExceptionSpec.Type) {
1903
  case EST_None:
1904
    break;
1905
  case EST_DynamicNone:
1906
    OS << " exceptionspec_dynamic_none";
1907
    break;
1908
  case EST_Dynamic:
1909
    OS << " exceptionspec_dynamic";
1910
    break;
1911
  case EST_MSAny:
1912
    OS << " exceptionspec_ms_any";
1913
    break;
1914
  case EST_NoThrow:
1915
    OS << " exceptionspec_nothrow";
1916
    break;
1917
  case EST_BasicNoexcept:
1918
    OS << " exceptionspec_basic_noexcept";
1919
    break;
1920
  case EST_DependentNoexcept:
1921
    OS << " exceptionspec_dependent_noexcept";
1922
    break;
1923
  case EST_NoexceptFalse:
1924
    OS << " exceptionspec_noexcept_false";
1925
    break;
1926
  case EST_NoexceptTrue:
1927
    OS << " exceptionspec_noexcept_true";
1928
    break;
1929
  case EST_Unevaluated:
1930
    OS << " exceptionspec_unevaluated";
1931
    break;
1932
  case EST_Uninstantiated:
1933
    OS << " exceptionspec_uninstantiated";
1934
    break;
1935
  case EST_Unparsed:
1936
    OS << " exceptionspec_unparsed";
1937
    break;
1938
  }
1939
  if (!EPI.ExceptionSpec.Exceptions.empty()) {
1940
    AddChild([=] {
1941
      OS << "Exceptions:";
1942
      for (unsigned I = 0, N = EPI.ExceptionSpec.Exceptions.size(); I != N;
1943
           ++I) {
1944
        if (I)
1945
          OS << ",";
1946
        dumpType(EPI.ExceptionSpec.Exceptions[I]);
1947
      }
1948
    });
1949
  }
1950
  if (EPI.ExceptionSpec.NoexceptExpr) {
1951
    AddChild([=] {
1952
      OS << "NoexceptExpr: ";
1953
      Visit(EPI.ExceptionSpec.NoexceptExpr);
1954
    });
1955
  }
1956
  dumpDeclRef(EPI.ExceptionSpec.SourceDecl, "ExceptionSourceDecl");
1957
  dumpDeclRef(EPI.ExceptionSpec.SourceTemplate, "ExceptionSourceTemplate");
1958

1959
  // FIXME: Consumed parameters.
1960
  VisitFunctionType(T);
1961
}
1962

1963
void TextNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
1964
  dumpDeclRef(T->getDecl());
1965
}
1966

1967
void TextNodeDumper::VisitUsingType(const UsingType *T) {
1968
  dumpDeclRef(T->getFoundDecl());
1969
  if (!T->typeMatchesDecl())
1970
    OS << " divergent";
1971
}
1972

1973
void TextNodeDumper::VisitTypedefType(const TypedefType *T) {
1974
  dumpDeclRef(T->getDecl());
1975
  if (!T->typeMatchesDecl())
1976
    OS << " divergent";
1977
}
1978

1979
void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType *T) {
1980
  switch (T->getUTTKind()) {
1981
#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait)                                  \
1982
  case UnaryTransformType::Enum:                                               \
1983
    OS << " " #Trait;                                                          \
1984
    break;
1985
#include "clang/Basic/TransformTypeTraits.def"
1986
  }
1987
}
1988

1989
void TextNodeDumper::VisitTagType(const TagType *T) {
1990
  dumpDeclRef(T->getDecl());
1991
}
1992

1993
void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
1994
  OS << " depth " << T->getDepth() << " index " << T->getIndex();
1995
  if (T->isParameterPack())
1996
    OS << " pack";
1997
  dumpDeclRef(T->getDecl());
1998
}
1999

2000
void TextNodeDumper::VisitSubstTemplateTypeParmType(
2001
    const SubstTemplateTypeParmType *T) {
2002
  dumpDeclRef(T->getAssociatedDecl());
2003
  VisitTemplateTypeParmDecl(T->getReplacedParameter());
2004
  if (auto PackIndex = T->getPackIndex())
2005
    OS << " pack_index " << *PackIndex;
2006
}
2007

2008
void TextNodeDumper::VisitSubstTemplateTypeParmPackType(
2009
    const SubstTemplateTypeParmPackType *T) {
2010
  dumpDeclRef(T->getAssociatedDecl());
2011
  VisitTemplateTypeParmDecl(T->getReplacedParameter());
2012
}
2013

2014
void TextNodeDumper::VisitAutoType(const AutoType *T) {
2015
  if (T->isDecltypeAuto())
2016
    OS << " decltype(auto)";
2017
  if (!T->isDeduced())
2018
    OS << " undeduced";
2019
  if (T->isConstrained())
2020
    dumpDeclRef(T->getTypeConstraintConcept());
2021
}
2022

2023
void TextNodeDumper::VisitDeducedTemplateSpecializationType(
2024
    const DeducedTemplateSpecializationType *T) {
2025
  dumpTemplateName(T->getTemplateName(), "name");
2026
}
2027

2028
void TextNodeDumper::VisitTemplateSpecializationType(
2029
    const TemplateSpecializationType *T) {
2030
  if (T->isTypeAlias())
2031
    OS << " alias";
2032
  dumpTemplateName(T->getTemplateName(), "name");
2033
}
2034

2035
void TextNodeDumper::VisitInjectedClassNameType(
2036
    const InjectedClassNameType *T) {
2037
  dumpDeclRef(T->getDecl());
2038
}
2039

2040
void TextNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
2041
  dumpDeclRef(T->getDecl());
2042
}
2043

2044
void TextNodeDumper::VisitPackExpansionType(const PackExpansionType *T) {
2045
  if (auto N = T->getNumExpansions())
2046
    OS << " expansions " << *N;
2047
}
2048

2049
void TextNodeDumper::VisitTypeLoc(TypeLoc TL) {
2050
  // By default, add extra Type details with no extra loc info.
2051
  TypeVisitor<TextNodeDumper>::Visit(TL.getTypePtr());
2052
}
2053
// FIXME: override behavior for TypeLocs that have interesting location
2054
// information, such as the qualifier in ElaboratedTypeLoc.
2055

2056
void TextNodeDumper::VisitLabelDecl(const LabelDecl *D) { dumpName(D); }
2057

2058
void TextNodeDumper::VisitTypedefDecl(const TypedefDecl *D) {
2059
  dumpName(D);
2060
  dumpType(D->getUnderlyingType());
2061
  if (D->isModulePrivate())
2062
    OS << " __module_private__";
2063
}
2064

2065
void TextNodeDumper::VisitEnumDecl(const EnumDecl *D) {
2066
  if (D->isScoped()) {
2067
    if (D->isScopedUsingClassTag())
2068
      OS << " class";
2069
    else
2070
      OS << " struct";
2071
  }
2072
  dumpName(D);
2073
  if (D->isModulePrivate())
2074
    OS << " __module_private__";
2075
  if (D->isFixed())
2076
    dumpType(D->getIntegerType());
2077
}
2078

2079
void TextNodeDumper::VisitRecordDecl(const RecordDecl *D) {
2080
  OS << ' ' << D->getKindName();
2081
  dumpName(D);
2082
  if (D->isModulePrivate())
2083
    OS << " __module_private__";
2084
  if (D->isCompleteDefinition())
2085
    OS << " definition";
2086
}
2087

2088
void TextNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
2089
  dumpName(D);
2090
  dumpType(D->getType());
2091
}
2092

2093
void TextNodeDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
2094
  dumpName(D);
2095
  dumpType(D->getType());
2096

2097
  for (const auto *Child : D->chain())
2098
    dumpDeclRef(Child);
2099
}
2100

2101
void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) {
2102
  dumpName(D);
2103
  dumpType(D->getType());
2104
  dumpTemplateSpecializationKind(D->getTemplateSpecializationKind());
2105

2106
  StorageClass SC = D->getStorageClass();
2107
  if (SC != SC_None)
2108
    OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
2109
  if (D->isInlineSpecified())
2110
    OS << " inline";
2111
  if (D->isVirtualAsWritten())
2112
    OS << " virtual";
2113
  if (D->isModulePrivate())
2114
    OS << " __module_private__";
2115

2116
  if (D->isPureVirtual())
2117
    OS << " pure";
2118
  if (D->isDefaulted()) {
2119
    OS << " default";
2120
    if (D->isDeleted())
2121
      OS << "_delete";
2122
  }
2123
  if (D->isDeletedAsWritten())
2124
    OS << " delete";
2125
  if (D->isTrivial())
2126
    OS << " trivial";
2127

2128
  if (const StringLiteral *M = D->getDeletedMessage())
2129
    AddChild("delete message", [=] { Visit(M); });
2130

2131
  if (D->isIneligibleOrNotSelected())
2132
    OS << (isa<CXXDestructorDecl>(D) ? " not_selected" : " ineligible");
2133

2134
  if (const auto *FPT = D->getType()->getAs<FunctionProtoType>()) {
2135
    FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
2136
    switch (EPI.ExceptionSpec.Type) {
2137
    default:
2138
      break;
2139
    case EST_Unevaluated:
2140
      OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl;
2141
      break;
2142
    case EST_Uninstantiated:
2143
      OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate;
2144
      break;
2145
    }
2146
  }
2147

2148
  if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
2149
    if (MD->size_overridden_methods() != 0) {
2150
      auto dumpOverride = [=](const CXXMethodDecl *D) {
2151
        SplitQualType T_split = D->getType().split();
2152
        OS << D << " " << D->getParent()->getName() << "::" << D->getDeclName()
2153
           << " '" << QualType::getAsString(T_split, PrintPolicy) << "'";
2154
      };
2155

2156
      AddChild([=] {
2157
        auto Overrides = MD->overridden_methods();
2158
        OS << "Overrides: [ ";
2159
        dumpOverride(*Overrides.begin());
2160
        for (const auto *Override : llvm::drop_begin(Overrides)) {
2161
          OS << ", ";
2162
          dumpOverride(Override);
2163
        }
2164
        OS << " ]";
2165
      });
2166
    }
2167
  }
2168

2169
  if (!D->isInlineSpecified() && D->isInlined()) {
2170
    OS << " implicit-inline";
2171
  }
2172
  // Since NumParams comes from the FunctionProtoType of the FunctionDecl and
2173
  // the Params are set later, it is possible for a dump during debugging to
2174
  // encounter a FunctionDecl that has been created but hasn't been assigned
2175
  // ParmVarDecls yet.
2176
  if (!D->param_empty() && !D->param_begin())
2177
    OS << " <<<NULL params x " << D->getNumParams() << ">>>";
2178

2179
  if (const auto *Instance = D->getInstantiatedFromMemberFunction()) {
2180
    OS << " instantiated_from";
2181
    dumpPointer(Instance);
2182
  }
2183
}
2184

2185
void TextNodeDumper::VisitCXXDeductionGuideDecl(
2186
    const CXXDeductionGuideDecl *D) {
2187
  VisitFunctionDecl(D);
2188
  switch (D->getDeductionCandidateKind()) {
2189
  case DeductionCandidate::Normal:
2190
  case DeductionCandidate::Copy:
2191
    return;
2192
  case DeductionCandidate::Aggregate:
2193
    OS << " aggregate ";
2194
    break;
2195
  }
2196
}
2197

2198
void TextNodeDumper::VisitLifetimeExtendedTemporaryDecl(
2199
    const LifetimeExtendedTemporaryDecl *D) {
2200
  OS << " extended by ";
2201
  dumpBareDeclRef(D->getExtendingDecl());
2202
  OS << " mangling ";
2203
  {
2204
    ColorScope Color(OS, ShowColors, ValueColor);
2205
    OS << D->getManglingNumber();
2206
  }
2207
}
2208

2209
void TextNodeDumper::VisitFieldDecl(const FieldDecl *D) {
2210
  dumpName(D);
2211
  dumpType(D->getType());
2212
  if (D->isMutable())
2213
    OS << " mutable";
2214
  if (D->isModulePrivate())
2215
    OS << " __module_private__";
2216
}
2217

2218
void TextNodeDumper::VisitVarDecl(const VarDecl *D) {
2219
  dumpNestedNameSpecifier(D->getQualifier());
2220
  dumpName(D);
2221
  if (const auto *P = dyn_cast<ParmVarDecl>(D);
2222
      P && P->isExplicitObjectParameter())
2223
    OS << " this";
2224

2225
  dumpType(D->getType());
2226
  dumpTemplateSpecializationKind(D->getTemplateSpecializationKind());
2227
  StorageClass SC = D->getStorageClass();
2228
  if (SC != SC_None)
2229
    OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
2230
  switch (D->getTLSKind()) {
2231
  case VarDecl::TLS_None:
2232
    break;
2233
  case VarDecl::TLS_Static:
2234
    OS << " tls";
2235
    break;
2236
  case VarDecl::TLS_Dynamic:
2237
    OS << " tls_dynamic";
2238
    break;
2239
  }
2240
  if (D->isModulePrivate())
2241
    OS << " __module_private__";
2242
  if (D->isNRVOVariable())
2243
    OS << " nrvo";
2244
  if (D->isInline())
2245
    OS << " inline";
2246
  if (D->isConstexpr())
2247
    OS << " constexpr";
2248
  if (D->hasInit()) {
2249
    switch (D->getInitStyle()) {
2250
    case VarDecl::CInit:
2251
      OS << " cinit";
2252
      break;
2253
    case VarDecl::CallInit:
2254
      OS << " callinit";
2255
      break;
2256
    case VarDecl::ListInit:
2257
      OS << " listinit";
2258
      break;
2259
    case VarDecl::ParenListInit:
2260
      OS << " parenlistinit";
2261
    }
2262
  }
2263
  if (D->needsDestruction(D->getASTContext()))
2264
    OS << " destroyed";
2265
  if (D->isParameterPack())
2266
    OS << " pack";
2267

2268
  if (D->hasInit()) {
2269
    const Expr *E = D->getInit();
2270
    // Only dump the value of constexpr VarDecls for now.
2271
    if (E && !E->isValueDependent() && D->isConstexpr() &&
2272
        !D->getType()->isDependentType()) {
2273
      const APValue *Value = D->evaluateValue();
2274
      if (Value)
2275
        AddChild("value", [=] { Visit(*Value, E->getType()); });
2276
    }
2277
  }
2278
}
2279

2280
void TextNodeDumper::VisitBindingDecl(const BindingDecl *D) {
2281
  dumpName(D);
2282
  dumpType(D->getType());
2283
}
2284

2285
void TextNodeDumper::VisitCapturedDecl(const CapturedDecl *D) {
2286
  if (D->isNothrow())
2287
    OS << " nothrow";
2288
}
2289

2290
void TextNodeDumper::VisitImportDecl(const ImportDecl *D) {
2291
  OS << ' ' << D->getImportedModule()->getFullModuleName();
2292

2293
  for (Decl *InitD :
2294
       D->getASTContext().getModuleInitializers(D->getImportedModule()))
2295
    dumpDeclRef(InitD, "initializer");
2296
}
2297

2298
void TextNodeDumper::VisitPragmaCommentDecl(const PragmaCommentDecl *D) {
2299
  OS << ' ';
2300
  switch (D->getCommentKind()) {
2301
  case PCK_Unknown:
2302
    llvm_unreachable("unexpected pragma comment kind");
2303
  case PCK_Compiler:
2304
    OS << "compiler";
2305
    break;
2306
  case PCK_ExeStr:
2307
    OS << "exestr";
2308
    break;
2309
  case PCK_Lib:
2310
    OS << "lib";
2311
    break;
2312
  case PCK_Linker:
2313
    OS << "linker";
2314
    break;
2315
  case PCK_User:
2316
    OS << "user";
2317
    break;
2318
  }
2319
  StringRef Arg = D->getArg();
2320
  if (!Arg.empty())
2321
    OS << " \"" << Arg << "\"";
2322
}
2323

2324
void TextNodeDumper::VisitPragmaDetectMismatchDecl(
2325
    const PragmaDetectMismatchDecl *D) {
2326
  OS << " \"" << D->getName() << "\" \"" << D->getValue() << "\"";
2327
}
2328

2329
void TextNodeDumper::VisitOMPExecutableDirective(
2330
    const OMPExecutableDirective *D) {
2331
  if (D->isStandaloneDirective())
2332
    OS << " openmp_standalone_directive";
2333
}
2334

2335
void TextNodeDumper::VisitOMPDeclareReductionDecl(
2336
    const OMPDeclareReductionDecl *D) {
2337
  dumpName(D);
2338
  dumpType(D->getType());
2339
  OS << " combiner";
2340
  dumpPointer(D->getCombiner());
2341
  if (const auto *Initializer = D->getInitializer()) {
2342
    OS << " initializer";
2343
    dumpPointer(Initializer);
2344
    switch (D->getInitializerKind()) {
2345
    case OMPDeclareReductionInitKind::Direct:
2346
      OS << " omp_priv = ";
2347
      break;
2348
    case OMPDeclareReductionInitKind::Copy:
2349
      OS << " omp_priv ()";
2350
      break;
2351
    case OMPDeclareReductionInitKind::Call:
2352
      break;
2353
    }
2354
  }
2355
}
2356

2357
void TextNodeDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) {
2358
  for (const auto *C : D->clauselists()) {
2359
    AddChild([=] {
2360
      if (!C) {
2361
        ColorScope Color(OS, ShowColors, NullColor);
2362
        OS << "<<<NULL>>> OMPClause";
2363
        return;
2364
      }
2365
      {
2366
        ColorScope Color(OS, ShowColors, AttrColor);
2367
        StringRef ClauseName(
2368
            llvm::omp::getOpenMPClauseName(C->getClauseKind()));
2369
        OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
2370
           << ClauseName.drop_front() << "Clause";
2371
      }
2372
      dumpPointer(C);
2373
      dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
2374
    });
2375
  }
2376
}
2377

2378
void TextNodeDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
2379
  dumpName(D);
2380
  dumpType(D->getType());
2381
}
2382

2383
void TextNodeDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
2384
  dumpName(D);
2385
  if (D->isInline())
2386
    OS << " inline";
2387
  if (D->isNested())
2388
    OS << " nested";
2389
  if (!D->isOriginalNamespace())
2390
    dumpDeclRef(D->getOriginalNamespace(), "original");
2391
}
2392

2393
void TextNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
2394
  OS << ' ';
2395
  dumpBareDeclRef(D->getNominatedNamespace());
2396
}
2397

2398
void TextNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
2399
  dumpName(D);
2400
  dumpDeclRef(D->getAliasedNamespace());
2401
}
2402

2403
void TextNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
2404
  dumpName(D);
2405
  dumpType(D->getUnderlyingType());
2406
}
2407

2408
void TextNodeDumper::VisitTypeAliasTemplateDecl(
2409
    const TypeAliasTemplateDecl *D) {
2410
  dumpName(D);
2411
}
2412

2413
void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
2414
  VisitRecordDecl(D);
2415
  if (const auto *Instance = D->getInstantiatedFromMemberClass()) {
2416
    OS << " instantiated_from";
2417
    dumpPointer(Instance);
2418
  }
2419
  if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D))
2420
    dumpTemplateSpecializationKind(CTSD->getSpecializationKind());
2421

2422
  dumpNestedNameSpecifier(D->getQualifier());
2423

2424
  if (!D->isCompleteDefinition())
2425
    return;
2426

2427
  AddChild([=] {
2428
    {
2429
      ColorScope Color(OS, ShowColors, DeclKindNameColor);
2430
      OS << "DefinitionData";
2431
    }
2432
#define FLAG(fn, name)                                                         \
2433
  if (D->fn())                                                                 \
2434
    OS << " " #name;
2435
    FLAG(isParsingBaseSpecifiers, parsing_base_specifiers);
2436

2437
    FLAG(isGenericLambda, generic);
2438
    FLAG(isLambda, lambda);
2439

2440
    FLAG(isAnonymousStructOrUnion, is_anonymous);
2441
    FLAG(canPassInRegisters, pass_in_registers);
2442
    FLAG(isEmpty, empty);
2443
    FLAG(isAggregate, aggregate);
2444
    FLAG(isStandardLayout, standard_layout);
2445
    FLAG(isTriviallyCopyable, trivially_copyable);
2446
    FLAG(isPOD, pod);
2447
    FLAG(isTrivial, trivial);
2448
    FLAG(isPolymorphic, polymorphic);
2449
    FLAG(isAbstract, abstract);
2450
    FLAG(isLiteral, literal);
2451

2452
    FLAG(hasUserDeclaredConstructor, has_user_declared_ctor);
2453
    FLAG(hasConstexprNonCopyMoveConstructor, has_constexpr_non_copy_move_ctor);
2454
    FLAG(hasMutableFields, has_mutable_fields);
2455
    FLAG(hasVariantMembers, has_variant_members);
2456
    FLAG(allowConstDefaultInit, can_const_default_init);
2457

2458
    AddChild([=] {
2459
      {
2460
        ColorScope Color(OS, ShowColors, DeclKindNameColor);
2461
        OS << "DefaultConstructor";
2462
      }
2463
      FLAG(hasDefaultConstructor, exists);
2464
      FLAG(hasTrivialDefaultConstructor, trivial);
2465
      FLAG(hasNonTrivialDefaultConstructor, non_trivial);
2466
      FLAG(hasUserProvidedDefaultConstructor, user_provided);
2467
      FLAG(hasConstexprDefaultConstructor, constexpr);
2468
      FLAG(needsImplicitDefaultConstructor, needs_implicit);
2469
      FLAG(defaultedDefaultConstructorIsConstexpr, defaulted_is_constexpr);
2470
    });
2471

2472
    AddChild([=] {
2473
      {
2474
        ColorScope Color(OS, ShowColors, DeclKindNameColor);
2475
        OS << "CopyConstructor";
2476
      }
2477
      FLAG(hasSimpleCopyConstructor, simple);
2478
      FLAG(hasTrivialCopyConstructor, trivial);
2479
      FLAG(hasNonTrivialCopyConstructor, non_trivial);
2480
      FLAG(hasUserDeclaredCopyConstructor, user_declared);
2481
      FLAG(hasCopyConstructorWithConstParam, has_const_param);
2482
      FLAG(needsImplicitCopyConstructor, needs_implicit);
2483
      FLAG(needsOverloadResolutionForCopyConstructor,
2484
           needs_overload_resolution);
2485
      if (!D->needsOverloadResolutionForCopyConstructor())
2486
        FLAG(defaultedCopyConstructorIsDeleted, defaulted_is_deleted);
2487
      FLAG(implicitCopyConstructorHasConstParam, implicit_has_const_param);
2488
    });
2489

2490
    AddChild([=] {
2491
      {
2492
        ColorScope Color(OS, ShowColors, DeclKindNameColor);
2493
        OS << "MoveConstructor";
2494
      }
2495
      FLAG(hasMoveConstructor, exists);
2496
      FLAG(hasSimpleMoveConstructor, simple);
2497
      FLAG(hasTrivialMoveConstructor, trivial);
2498
      FLAG(hasNonTrivialMoveConstructor, non_trivial);
2499
      FLAG(hasUserDeclaredMoveConstructor, user_declared);
2500
      FLAG(needsImplicitMoveConstructor, needs_implicit);
2501
      FLAG(needsOverloadResolutionForMoveConstructor,
2502
           needs_overload_resolution);
2503
      if (!D->needsOverloadResolutionForMoveConstructor())
2504
        FLAG(defaultedMoveConstructorIsDeleted, defaulted_is_deleted);
2505
    });
2506

2507
    AddChild([=] {
2508
      {
2509
        ColorScope Color(OS, ShowColors, DeclKindNameColor);
2510
        OS << "CopyAssignment";
2511
      }
2512
      FLAG(hasSimpleCopyAssignment, simple);
2513
      FLAG(hasTrivialCopyAssignment, trivial);
2514
      FLAG(hasNonTrivialCopyAssignment, non_trivial);
2515
      FLAG(hasCopyAssignmentWithConstParam, has_const_param);
2516
      FLAG(hasUserDeclaredCopyAssignment, user_declared);
2517
      FLAG(needsImplicitCopyAssignment, needs_implicit);
2518
      FLAG(needsOverloadResolutionForCopyAssignment, needs_overload_resolution);
2519
      FLAG(implicitCopyAssignmentHasConstParam, implicit_has_const_param);
2520
    });
2521

2522
    AddChild([=] {
2523
      {
2524
        ColorScope Color(OS, ShowColors, DeclKindNameColor);
2525
        OS << "MoveAssignment";
2526
      }
2527
      FLAG(hasMoveAssignment, exists);
2528
      FLAG(hasSimpleMoveAssignment, simple);
2529
      FLAG(hasTrivialMoveAssignment, trivial);
2530
      FLAG(hasNonTrivialMoveAssignment, non_trivial);
2531
      FLAG(hasUserDeclaredMoveAssignment, user_declared);
2532
      FLAG(needsImplicitMoveAssignment, needs_implicit);
2533
      FLAG(needsOverloadResolutionForMoveAssignment, needs_overload_resolution);
2534
    });
2535

2536
    AddChild([=] {
2537
      {
2538
        ColorScope Color(OS, ShowColors, DeclKindNameColor);
2539
        OS << "Destructor";
2540
      }
2541
      FLAG(hasSimpleDestructor, simple);
2542
      FLAG(hasIrrelevantDestructor, irrelevant);
2543
      FLAG(hasTrivialDestructor, trivial);
2544
      FLAG(hasNonTrivialDestructor, non_trivial);
2545
      FLAG(hasUserDeclaredDestructor, user_declared);
2546
      FLAG(hasConstexprDestructor, constexpr);
2547
      FLAG(needsImplicitDestructor, needs_implicit);
2548
      FLAG(needsOverloadResolutionForDestructor, needs_overload_resolution);
2549
      if (!D->needsOverloadResolutionForDestructor())
2550
        FLAG(defaultedDestructorIsDeleted, defaulted_is_deleted);
2551
    });
2552
  });
2553

2554
  for (const auto &I : D->bases()) {
2555
    AddChild([=] {
2556
      if (I.isVirtual())
2557
        OS << "virtual ";
2558
      dumpAccessSpecifier(I.getAccessSpecifier());
2559
      dumpType(I.getType());
2560
      if (I.isPackExpansion())
2561
        OS << "...";
2562
    });
2563
  }
2564
}
2565

2566
void TextNodeDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
2567
  dumpName(D);
2568
}
2569

2570
void TextNodeDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
2571
  dumpName(D);
2572
}
2573

2574
void TextNodeDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
2575
  dumpName(D);
2576
}
2577

2578
void TextNodeDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
2579
  dumpName(D);
2580
}
2581

2582
void TextNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
2583
  if (const auto *TC = D->getTypeConstraint()) {
2584
    OS << " ";
2585
    dumpBareDeclRef(TC->getNamedConcept());
2586
    if (TC->getNamedConcept() != TC->getFoundDecl()) {
2587
      OS << " (";
2588
      dumpBareDeclRef(TC->getFoundDecl());
2589
      OS << ")";
2590
    }
2591
  } else if (D->wasDeclaredWithTypename())
2592
    OS << " typename";
2593
  else
2594
    OS << " class";
2595
  OS << " depth " << D->getDepth() << " index " << D->getIndex();
2596
  if (D->isParameterPack())
2597
    OS << " ...";
2598
  dumpName(D);
2599
}
2600

2601
void TextNodeDumper::VisitNonTypeTemplateParmDecl(
2602
    const NonTypeTemplateParmDecl *D) {
2603
  dumpType(D->getType());
2604
  OS << " depth " << D->getDepth() << " index " << D->getIndex();
2605
  if (D->isParameterPack())
2606
    OS << " ...";
2607
  dumpName(D);
2608
}
2609

2610
void TextNodeDumper::VisitTemplateTemplateParmDecl(
2611
    const TemplateTemplateParmDecl *D) {
2612
  OS << " depth " << D->getDepth() << " index " << D->getIndex();
2613
  if (D->isParameterPack())
2614
    OS << " ...";
2615
  dumpName(D);
2616
}
2617

2618
void TextNodeDumper::VisitUsingDecl(const UsingDecl *D) {
2619
  OS << ' ';
2620
  if (D->getQualifier())
2621
    D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2622
  OS << D->getDeclName();
2623
  dumpNestedNameSpecifier(D->getQualifier());
2624
}
2625

2626
void TextNodeDumper::VisitUsingEnumDecl(const UsingEnumDecl *D) {
2627
  OS << ' ';
2628
  dumpBareDeclRef(D->getEnumDecl());
2629
}
2630

2631
void TextNodeDumper::VisitUnresolvedUsingTypenameDecl(
2632
    const UnresolvedUsingTypenameDecl *D) {
2633
  OS << ' ';
2634
  if (D->getQualifier())
2635
    D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2636
  OS << D->getDeclName();
2637
}
2638

2639
void TextNodeDumper::VisitUnresolvedUsingValueDecl(
2640
    const UnresolvedUsingValueDecl *D) {
2641
  OS << ' ';
2642
  if (D->getQualifier())
2643
    D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2644
  OS << D->getDeclName();
2645
  dumpType(D->getType());
2646
}
2647

2648
void TextNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
2649
  OS << ' ';
2650
  dumpBareDeclRef(D->getTargetDecl());
2651
}
2652

2653
void TextNodeDumper::VisitConstructorUsingShadowDecl(
2654
    const ConstructorUsingShadowDecl *D) {
2655
  if (D->constructsVirtualBase())
2656
    OS << " virtual";
2657

2658
  AddChild([=] {
2659
    OS << "target ";
2660
    dumpBareDeclRef(D->getTargetDecl());
2661
  });
2662

2663
  AddChild([=] {
2664
    OS << "nominated ";
2665
    dumpBareDeclRef(D->getNominatedBaseClass());
2666
    OS << ' ';
2667
    dumpBareDeclRef(D->getNominatedBaseClassShadowDecl());
2668
  });
2669

2670
  AddChild([=] {
2671
    OS << "constructed ";
2672
    dumpBareDeclRef(D->getConstructedBaseClass());
2673
    OS << ' ';
2674
    dumpBareDeclRef(D->getConstructedBaseClassShadowDecl());
2675
  });
2676
}
2677

2678
void TextNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
2679
  switch (D->getLanguage()) {
2680
  case LinkageSpecLanguageIDs::C:
2681
    OS << " C";
2682
    break;
2683
  case LinkageSpecLanguageIDs::CXX:
2684
    OS << " C++";
2685
    break;
2686
  }
2687
}
2688

2689
void TextNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
2690
  OS << ' ';
2691
  dumpAccessSpecifier(D->getAccess());
2692
}
2693

2694
void TextNodeDumper::VisitFriendDecl(const FriendDecl *D) {
2695
  if (TypeSourceInfo *T = D->getFriendType())
2696
    dumpType(T->getType());
2697
}
2698

2699
void TextNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
2700
  dumpName(D);
2701
  dumpType(D->getType());
2702
  if (D->getSynthesize())
2703
    OS << " synthesize";
2704

2705
  switch (D->getAccessControl()) {
2706
  case ObjCIvarDecl::None:
2707
    OS << " none";
2708
    break;
2709
  case ObjCIvarDecl::Private:
2710
    OS << " private";
2711
    break;
2712
  case ObjCIvarDecl::Protected:
2713
    OS << " protected";
2714
    break;
2715
  case ObjCIvarDecl::Public:
2716
    OS << " public";
2717
    break;
2718
  case ObjCIvarDecl::Package:
2719
    OS << " package";
2720
    break;
2721
  }
2722
}
2723

2724
void TextNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
2725
  if (D->isInstanceMethod())
2726
    OS << " -";
2727
  else
2728
    OS << " +";
2729
  dumpName(D);
2730
  dumpType(D->getReturnType());
2731

2732
  if (D->isVariadic())
2733
    OS << " variadic";
2734
}
2735

2736
void TextNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
2737
  dumpName(D);
2738
  switch (D->getVariance()) {
2739
  case ObjCTypeParamVariance::Invariant:
2740
    break;
2741

2742
  case ObjCTypeParamVariance::Covariant:
2743
    OS << " covariant";
2744
    break;
2745

2746
  case ObjCTypeParamVariance::Contravariant:
2747
    OS << " contravariant";
2748
    break;
2749
  }
2750

2751
  if (D->hasExplicitBound())
2752
    OS << " bounded";
2753
  dumpType(D->getUnderlyingType());
2754
}
2755

2756
void TextNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
2757
  dumpName(D);
2758
  dumpDeclRef(D->getClassInterface());
2759
  dumpDeclRef(D->getImplementation());
2760
  for (const auto *P : D->protocols())
2761
    dumpDeclRef(P);
2762
}
2763

2764
void TextNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
2765
  dumpName(D);
2766
  dumpDeclRef(D->getClassInterface());
2767
  dumpDeclRef(D->getCategoryDecl());
2768
}
2769

2770
void TextNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
2771
  dumpName(D);
2772

2773
  for (const auto *Child : D->protocols())
2774
    dumpDeclRef(Child);
2775
}
2776

2777
void TextNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
2778
  dumpName(D);
2779
  dumpDeclRef(D->getSuperClass(), "super");
2780

2781
  dumpDeclRef(D->getImplementation());
2782
  for (const auto *Child : D->protocols())
2783
    dumpDeclRef(Child);
2784
}
2785

2786
void TextNodeDumper::VisitObjCImplementationDecl(
2787
    const ObjCImplementationDecl *D) {
2788
  dumpName(D);
2789
  dumpDeclRef(D->getSuperClass(), "super");
2790
  dumpDeclRef(D->getClassInterface());
2791
}
2792

2793
void TextNodeDumper::VisitObjCCompatibleAliasDecl(
2794
    const ObjCCompatibleAliasDecl *D) {
2795
  dumpName(D);
2796
  dumpDeclRef(D->getClassInterface());
2797
}
2798

2799
void TextNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
2800
  dumpName(D);
2801
  dumpType(D->getType());
2802

2803
  if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
2804
    OS << " required";
2805
  else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
2806
    OS << " optional";
2807

2808
  ObjCPropertyAttribute::Kind Attrs = D->getPropertyAttributes();
2809
  if (Attrs != ObjCPropertyAttribute::kind_noattr) {
2810
    if (Attrs & ObjCPropertyAttribute::kind_readonly)
2811
      OS << " readonly";
2812
    if (Attrs & ObjCPropertyAttribute::kind_assign)
2813
      OS << " assign";
2814
    if (Attrs & ObjCPropertyAttribute::kind_readwrite)
2815
      OS << " readwrite";
2816
    if (Attrs & ObjCPropertyAttribute::kind_retain)
2817
      OS << " retain";
2818
    if (Attrs & ObjCPropertyAttribute::kind_copy)
2819
      OS << " copy";
2820
    if (Attrs & ObjCPropertyAttribute::kind_nonatomic)
2821
      OS << " nonatomic";
2822
    if (Attrs & ObjCPropertyAttribute::kind_atomic)
2823
      OS << " atomic";
2824
    if (Attrs & ObjCPropertyAttribute::kind_weak)
2825
      OS << " weak";
2826
    if (Attrs & ObjCPropertyAttribute::kind_strong)
2827
      OS << " strong";
2828
    if (Attrs & ObjCPropertyAttribute::kind_unsafe_unretained)
2829
      OS << " unsafe_unretained";
2830
    if (Attrs & ObjCPropertyAttribute::kind_class)
2831
      OS << " class";
2832
    if (Attrs & ObjCPropertyAttribute::kind_direct)
2833
      OS << " direct";
2834
    if (Attrs & ObjCPropertyAttribute::kind_getter)
2835
      dumpDeclRef(D->getGetterMethodDecl(), "getter");
2836
    if (Attrs & ObjCPropertyAttribute::kind_setter)
2837
      dumpDeclRef(D->getSetterMethodDecl(), "setter");
2838
  }
2839
}
2840

2841
void TextNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
2842
  dumpName(D->getPropertyDecl());
2843
  if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
2844
    OS << " synthesize";
2845
  else
2846
    OS << " dynamic";
2847
  dumpDeclRef(D->getPropertyDecl());
2848
  dumpDeclRef(D->getPropertyIvarDecl());
2849
}
2850

2851
void TextNodeDumper::VisitBlockDecl(const BlockDecl *D) {
2852
  if (D->isVariadic())
2853
    OS << " variadic";
2854

2855
  if (D->capturesCXXThis())
2856
    OS << " captures_this";
2857
}
2858

2859
void TextNodeDumper::VisitConceptDecl(const ConceptDecl *D) {
2860
  dumpName(D);
2861
}
2862

2863
void TextNodeDumper::VisitCompoundStmt(const CompoundStmt *S) {
2864
  VisitStmt(S);
2865
  if (S->hasStoredFPFeatures())
2866
    printFPOptions(S->getStoredFPFeatures());
2867
}
2868

2869
void TextNodeDumper::VisitHLSLBufferDecl(const HLSLBufferDecl *D) {
2870
  if (D->isCBuffer())
2871
    OS << " cbuffer";
2872
  else
2873
    OS << " tbuffer";
2874
  dumpName(D);
2875
}
2876

2877
void TextNodeDumper::VisitOpenACCConstructStmt(const OpenACCConstructStmt *S) {
2878
  OS << " " << S->getDirectiveKind();
2879
}
2880
void TextNodeDumper::VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *S) {
2881

2882
  if (S->isOrphanedLoopConstruct())
2883
    OS << " <orphan>";
2884
  else
2885
    OS << " parent: " << S->getParentComputeConstruct();
2886
}
2887

2888
void TextNodeDumper::VisitEmbedExpr(const EmbedExpr *S) {
2889
  AddChild("begin", [=] { OS << S->getStartingElementPos(); });
2890
  AddChild("number of elements", [=] { OS << S->getDataElementCount(); });
2891
}
2892

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.