Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/clang/lib/AST/TextNodeDumper.cpp
Line
Count
Source (jump to first uncovered line)
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/Basic/Module.h"
22
#include "clang/Basic/SourceManager.h"
23
#include "clang/Basic/Specifiers.h"
24
#include "clang/Basic/TypeTraits.h"
25
#include "llvm/ADT/StringExtras.h"
26
27
#include <algorithm>
28
#include <utility>
29
30
using namespace clang;
31
32
0
static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {}
33
34
template <typename T>
35
0
static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) {
36
0
  const T *First = D->getFirstDecl();
37
0
  if (First != D)
38
0
    OS << " first " << First;
39
0
}
Unexecuted instantiation: TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::UnresolvedUsingValueDecl>(llvm::raw_ostream&, clang::Mergeable<clang::UnresolvedUsingValueDecl> const*)
Unexecuted instantiation: TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::UnnamedGlobalConstantDecl>(llvm::raw_ostream&, clang::Mergeable<clang::UnnamedGlobalConstantDecl> const*)
Unexecuted instantiation: TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::TemplateParamObjectDecl>(llvm::raw_ostream&, clang::Mergeable<clang::TemplateParamObjectDecl> const*)
Unexecuted instantiation: TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::MSGuidDecl>(llvm::raw_ostream&, clang::Mergeable<clang::MSGuidDecl> const*)
Unexecuted instantiation: TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::IndirectFieldDecl>(llvm::raw_ostream&, clang::Mergeable<clang::IndirectFieldDecl> const*)
Unexecuted instantiation: TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::EnumConstantDecl>(llvm::raw_ostream&, clang::Mergeable<clang::EnumConstantDecl> const*)
Unexecuted instantiation: TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::FieldDecl>(llvm::raw_ostream&, clang::Mergeable<clang::FieldDecl> const*)
Unexecuted instantiation: TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::UsingPackDecl>(llvm::raw_ostream&, clang::Mergeable<clang::UsingPackDecl> const*)
Unexecuted instantiation: TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::UnresolvedUsingTypenameDecl>(llvm::raw_ostream&, clang::Mergeable<clang::UnresolvedUsingTypenameDecl> const*)
Unexecuted instantiation: TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::ConceptDecl>(llvm::raw_ostream&, clang::Mergeable<clang::ConceptDecl> const*)
Unexecuted instantiation: TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::UsingEnumDecl>(llvm::raw_ostream&, clang::Mergeable<clang::UsingEnumDecl> const*)
Unexecuted instantiation: TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::UsingDecl>(llvm::raw_ostream&, clang::Mergeable<clang::UsingDecl> const*)
Unexecuted instantiation: TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::LifetimeExtendedTemporaryDecl>(llvm::raw_ostream&, clang::Mergeable<clang::LifetimeExtendedTemporaryDecl> const*)
40
41
template <typename T>
42
0
static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) {
43
0
  const T *Prev = D->getPreviousDecl();
44
0
  if (Prev)
45
0
    OS << " prev " << Prev;
46
0
}
Unexecuted instantiation: TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::TranslationUnitDecl>(llvm::raw_ostream&, clang::Redeclarable<clang::TranslationUnitDecl> const*)
Unexecuted instantiation: TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::ObjCProtocolDecl>(llvm::raw_ostream&, clang::Redeclarable<clang::ObjCProtocolDecl> const*)
Unexecuted instantiation: TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::ObjCInterfaceDecl>(llvm::raw_ostream&, clang::Redeclarable<clang::ObjCInterfaceDecl> const*)
Unexecuted instantiation: TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::NamespaceDecl>(llvm::raw_ostream&, clang::Redeclarable<clang::NamespaceDecl> const*)
Unexecuted instantiation: TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::FunctionDecl>(llvm::raw_ostream&, clang::Redeclarable<clang::FunctionDecl> const*)
Unexecuted instantiation: TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::VarDecl>(llvm::raw_ostream&, clang::Redeclarable<clang::VarDecl> const*)
Unexecuted instantiation: TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::UsingShadowDecl>(llvm::raw_ostream&, clang::Redeclarable<clang::UsingShadowDecl> const*)
Unexecuted instantiation: TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::TagDecl>(llvm::raw_ostream&, clang::Redeclarable<clang::TagDecl> const*)
Unexecuted instantiation: TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::TypedefNameDecl>(llvm::raw_ostream&, clang::Redeclarable<clang::TypedefNameDecl> const*)
Unexecuted instantiation: TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::RedeclarableTemplateDecl>(llvm::raw_ostream&, clang::Redeclarable<clang::RedeclarableTemplateDecl> const*)
Unexecuted instantiation: TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::NamespaceAliasDecl>(llvm::raw_ostream&, clang::Redeclarable<clang::NamespaceAliasDecl> const*)
47
48
/// Dump the previous declaration in the redeclaration chain for a declaration,
49
/// if any.
50
0
static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) {
51
0
  switch (D->getKind()) {
52
0
#define DECL(DERIVED, BASE)                                                    \
53
0
  case Decl::DERIVED:                                                          \
54
0
    return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D));
55
0
#define ABSTRACT_DECL(DECL)
56
0
#include "clang/AST/DeclNodes.inc"
57
0
  }
58
0
  llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
59
0
}
60
61
TextNodeDumper::TextNodeDumper(raw_ostream &OS, const ASTContext &Context,
62
                               bool ShowColors)
63
    : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors),
64
      Context(&Context), SM(&Context.getSourceManager()),
65
      PrintPolicy(Context.getPrintingPolicy()),
66
0
      Traits(&Context.getCommentCommandTraits()) {}
67
68
TextNodeDumper::TextNodeDumper(raw_ostream &OS, bool ShowColors)
69
0
    : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors) {}
70
71
void TextNodeDumper::Visit(const comments::Comment *C,
72
0
                           const comments::FullComment *FC) {
73
0
  if (!C) {
74
0
    ColorScope Color(OS, ShowColors, NullColor);
75
0
    OS << "<<<NULL>>>";
76
0
    return;
77
0
  }
78
79
0
  {
80
0
    ColorScope Color(OS, ShowColors, CommentColor);
81
0
    OS << C->getCommentKindName();
82
0
  }
83
0
  dumpPointer(C);
84
0
  dumpSourceRange(C->getSourceRange());
85
86
0
  ConstCommentVisitor<TextNodeDumper, void,
87
0
                      const comments::FullComment *>::visit(C, FC);
88
0
}
89
90
0
void TextNodeDumper::Visit(const Attr *A) {
91
0
  {
92
0
    ColorScope Color(OS, ShowColors, AttrColor);
93
94
0
    switch (A->getKind()) {
95
0
#define ATTR(X)                                                                \
96
0
  case attr::X:                                                                \
97
0
    OS << #X;                                                                  \
98
0
    break;
99
0
#include "clang/Basic/AttrList.inc"
100
0
    }
101
0
    OS << "Attr";
102
0
  }
103
0
  dumpPointer(A);
104
0
  dumpSourceRange(A->getRange());
105
0
  if (A->isInherited())
106
0
    OS << " Inherited";
107
0
  if (A->isImplicit())
108
0
    OS << " Implicit";
109
110
0
  ConstAttrVisitor<TextNodeDumper>::Visit(A);
111
0
}
112
113
void TextNodeDumper::Visit(const TemplateArgument &TA, SourceRange R,
114
0
                           const Decl *From, StringRef Label) {
115
0
  OS << "TemplateArgument";
116
0
  if (R.isValid())
117
0
    dumpSourceRange(R);
118
119
0
  if (From)
120
0
    dumpDeclRef(From, Label);
121
122
0
  ConstTemplateArgumentVisitor<TextNodeDumper>::Visit(TA);
123
0
}
124
125
0
void TextNodeDumper::Visit(const Stmt *Node) {
126
0
  if (!Node) {
127
0
    ColorScope Color(OS, ShowColors, NullColor);
128
0
    OS << "<<<NULL>>>";
129
0
    return;
130
0
  }
131
0
  {
132
0
    ColorScope Color(OS, ShowColors, StmtColor);
133
0
    OS << Node->getStmtClassName();
134
0
  }
135
0
  dumpPointer(Node);
136
0
  dumpSourceRange(Node->getSourceRange());
137
138
0
  if (const auto *E = dyn_cast<Expr>(Node)) {
139
0
    dumpType(E->getType());
140
141
0
    if (E->containsErrors()) {
142
0
      ColorScope Color(OS, ShowColors, ErrorsColor);
143
0
      OS << " contains-errors";
144
0
    }
145
146
0
    {
147
0
      ColorScope Color(OS, ShowColors, ValueKindColor);
148
0
      switch (E->getValueKind()) {
149
0
      case VK_PRValue:
150
0
        break;
151
0
      case VK_LValue:
152
0
        OS << " lvalue";
153
0
        break;
154
0
      case VK_XValue:
155
0
        OS << " xvalue";
156
0
        break;
157
0
      }
158
0
    }
159
160
0
    {
161
0
      ColorScope Color(OS, ShowColors, ObjectKindColor);
162
0
      switch (E->getObjectKind()) {
163
0
      case OK_Ordinary:
164
0
        break;
165
0
      case OK_BitField:
166
0
        OS << " bitfield";
167
0
        break;
168
0
      case OK_ObjCProperty:
169
0
        OS << " objcproperty";
170
0
        break;
171
0
      case OK_ObjCSubscript:
172
0
        OS << " objcsubscript";
173
0
        break;
174
0
      case OK_VectorComponent:
175
0
        OS << " vectorcomponent";
176
0
        break;
177
0
      case OK_MatrixComponent:
178
0
        OS << " matrixcomponent";
179
0
        break;
180
0
      }
181
0
    }
182
0
  }
183
184
0
  ConstStmtVisitor<TextNodeDumper>::Visit(Node);
185
0
}
186
187
0
void TextNodeDumper::Visit(const Type *T) {
188
0
  if (!T) {
189
0
    ColorScope Color(OS, ShowColors, NullColor);
190
0
    OS << "<<<NULL>>>";
191
0
    return;
192
0
  }
193
0
  if (isa<LocInfoType>(T)) {
194
0
    {
195
0
      ColorScope Color(OS, ShowColors, TypeColor);
196
0
      OS << "LocInfo Type";
197
0
    }
198
0
    dumpPointer(T);
199
0
    return;
200
0
  }
201
202
0
  {
203
0
    ColorScope Color(OS, ShowColors, TypeColor);
204
0
    OS << T->getTypeClassName() << "Type";
205
0
  }
206
0
  dumpPointer(T);
207
0
  OS << " ";
208
0
  dumpBareType(QualType(T, 0), false);
209
210
0
  QualType SingleStepDesugar =
211
0
      T->getLocallyUnqualifiedSingleStepDesugaredType();
212
0
  if (SingleStepDesugar != QualType(T, 0))
213
0
    OS << " sugar";
214
215
0
  if (T->containsErrors()) {
216
0
    ColorScope Color(OS, ShowColors, ErrorsColor);
217
0
    OS << " contains-errors";
218
0
  }
219
220
0
  if (T->isDependentType())
221
0
    OS << " dependent";
222
0
  else if (T->isInstantiationDependentType())
223
0
    OS << " instantiation_dependent";
224
225
0
  if (T->isVariablyModifiedType())
226
0
    OS << " variably_modified";
227
0
  if (T->containsUnexpandedParameterPack())
228
0
    OS << " contains_unexpanded_pack";
229
0
  if (T->isFromAST())
230
0
    OS << " imported";
231
232
0
  TypeVisitor<TextNodeDumper>::Visit(T);
233
0
}
234
235
0
void TextNodeDumper::Visit(QualType T) {
236
0
  OS << "QualType";
237
0
  dumpPointer(T.getAsOpaquePtr());
238
0
  OS << " ";
239
0
  dumpBareType(T, false);
240
0
  OS << " " << T.split().Quals.getAsString();
241
0
}
242
243
0
void TextNodeDumper::Visit(const Decl *D) {
244
0
  if (!D) {
245
0
    ColorScope Color(OS, ShowColors, NullColor);
246
0
    OS << "<<<NULL>>>";
247
0
    return;
248
0
  }
249
250
0
  {
251
0
    ColorScope Color(OS, ShowColors, DeclKindNameColor);
252
0
    OS << D->getDeclKindName() << "Decl";
253
0
  }
254
0
  dumpPointer(D);
255
0
  if (D->getLexicalDeclContext() != D->getDeclContext())
256
0
    OS << " parent " << cast<Decl>(D->getDeclContext());
257
0
  dumpPreviousDecl(OS, D);
258
0
  dumpSourceRange(D->getSourceRange());
259
0
  OS << ' ';
260
0
  dumpLocation(D->getLocation());
261
0
  if (D->isFromASTFile())
262
0
    OS << " imported";
263
0
  if (Module *M = D->getOwningModule())
264
0
    OS << " in " << M->getFullModuleName();
265
0
  if (auto *ND = dyn_cast<NamedDecl>(D))
266
0
    for (Module *M : D->getASTContext().getModulesWithMergedDefinition(
267
0
             const_cast<NamedDecl *>(ND)))
268
0
      AddChild([=] { OS << "also in " << M->getFullModuleName(); });
269
0
  if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
270
0
    if (!ND->isUnconditionallyVisible())
271
0
      OS << " hidden";
272
0
  if (D->isImplicit())
273
0
    OS << " implicit";
274
275
0
  if (D->isUsed())
276
0
    OS << " used";
277
0
  else if (D->isThisDeclarationReferenced())
278
0
    OS << " referenced";
279
280
0
  if (D->isInvalidDecl())
281
0
    OS << " invalid";
282
0
  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
283
0
    if (FD->isConstexprSpecified())
284
0
      OS << " constexpr";
285
0
    if (FD->isConsteval())
286
0
      OS << " consteval";
287
0
    else if (FD->isImmediateFunction())
288
0
      OS << " immediate";
289
0
    if (FD->isMultiVersion())
290
0
      OS << " multiversion";
291
0
  }
292
293
0
  if (!isa<FunctionDecl>(*D)) {
294
0
    const auto *MD = dyn_cast<ObjCMethodDecl>(D);
295
0
    if (!MD || !MD->isThisDeclarationADefinition()) {
296
0
      const auto *DC = dyn_cast<DeclContext>(D);
297
0
      if (DC && DC->hasExternalLexicalStorage()) {
298
0
        ColorScope Color(OS, ShowColors, UndeserializedColor);
299
0
        OS << " <undeserialized declarations>";
300
0
      }
301
0
    }
302
0
  }
303
304
0
  switch (D->getFriendObjectKind()) {
305
0
  case Decl::FOK_None:
306
0
    break;
307
0
  case Decl::FOK_Declared:
308
0
    OS << " friend";
309
0
    break;
310
0
  case Decl::FOK_Undeclared:
311
0
    OS << " friend_undeclared";
312
0
    break;
313
0
  }
314
315
0
  ConstDeclVisitor<TextNodeDumper>::Visit(D);
316
0
}
317
318
0
void TextNodeDumper::Visit(const CXXCtorInitializer *Init) {
319
0
  OS << "CXXCtorInitializer";
320
0
  if (Init->isAnyMemberInitializer()) {
321
0
    OS << ' ';
322
0
    dumpBareDeclRef(Init->getAnyMember());
323
0
  } else if (Init->isBaseInitializer()) {
324
0
    dumpType(QualType(Init->getBaseClass(), 0));
325
0
  } else if (Init->isDelegatingInitializer()) {
326
0
    dumpType(Init->getTypeSourceInfo()->getType());
327
0
  } else {
328
0
    llvm_unreachable("Unknown initializer type");
329
0
  }
330
0
}
331
332
0
void TextNodeDumper::Visit(const BlockDecl::Capture &C) {
333
0
  OS << "capture";
334
0
  if (C.isByRef())
335
0
    OS << " byref";
336
0
  if (C.isNested())
337
0
    OS << " nested";
338
0
  if (C.getVariable()) {
339
0
    OS << ' ';
340
0
    dumpBareDeclRef(C.getVariable());
341
0
  }
342
0
}
343
344
0
void TextNodeDumper::Visit(const OMPClause *C) {
345
0
  if (!C) {
346
0
    ColorScope Color(OS, ShowColors, NullColor);
347
0
    OS << "<<<NULL>>> OMPClause";
348
0
    return;
349
0
  }
350
0
  {
351
0
    ColorScope Color(OS, ShowColors, AttrColor);
352
0
    StringRef ClauseName(llvm::omp::getOpenMPClauseName(C->getClauseKind()));
353
0
    OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
354
0
       << ClauseName.drop_front() << "Clause";
355
0
  }
356
0
  dumpPointer(C);
357
0
  dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
358
0
  if (C->isImplicit())
359
0
    OS << " <implicit>";
360
0
}
361
362
0
void TextNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) {
363
0
  const TypeSourceInfo *TSI = A.getTypeSourceInfo();
364
0
  if (TSI) {
365
0
    OS << "case ";
366
0
    dumpType(TSI->getType());
367
0
  } else {
368
0
    OS << "default";
369
0
  }
370
371
0
  if (A.isSelected())
372
0
    OS << " selected";
373
0
}
374
375
0
void TextNodeDumper::Visit(const ConceptReference *R) {
376
0
  if (!R) {
377
0
    ColorScope Color(OS, ShowColors, NullColor);
378
0
    OS << "<<<NULL>>> ConceptReference";
379
0
    return;
380
0
  }
381
382
0
  OS << "ConceptReference";
383
0
  dumpPointer(R);
384
0
  dumpSourceRange(R->getSourceRange());
385
0
  OS << ' ';
386
0
  dumpBareDeclRef(R->getNamedConcept());
387
0
}
388
389
0
void TextNodeDumper::Visit(const concepts::Requirement *R) {
390
0
  if (!R) {
391
0
    ColorScope Color(OS, ShowColors, NullColor);
392
0
    OS << "<<<NULL>>> Requirement";
393
0
    return;
394
0
  }
395
396
0
  {
397
0
    ColorScope Color(OS, ShowColors, StmtColor);
398
0
    switch (R->getKind()) {
399
0
    case concepts::Requirement::RK_Type:
400
0
      OS << "TypeRequirement";
401
0
      break;
402
0
    case concepts::Requirement::RK_Simple:
403
0
      OS << "SimpleRequirement";
404
0
      break;
405
0
    case concepts::Requirement::RK_Compound:
406
0
      OS << "CompoundRequirement";
407
0
      break;
408
0
    case concepts::Requirement::RK_Nested:
409
0
      OS << "NestedRequirement";
410
0
      break;
411
0
    }
412
0
  }
413
414
0
  dumpPointer(R);
415
416
0
  if (auto *ER = dyn_cast<concepts::ExprRequirement>(R)) {
417
0
    if (ER->hasNoexceptRequirement())
418
0
      OS << " noexcept";
419
0
  }
420
421
0
  if (R->isDependent())
422
0
    OS << " dependent";
423
0
  else
424
0
    OS << (R->isSatisfied() ? " satisfied" : " unsatisfied");
425
0
  if (R->containsUnexpandedParameterPack())
426
0
    OS << " contains_unexpanded_pack";
427
0
}
428
429
0
static double GetApproxValue(const llvm::APFloat &F) {
430
0
  llvm::APFloat V = F;
431
0
  bool ignored;
432
0
  V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven,
433
0
            &ignored);
434
0
  return V.convertToDouble();
435
0
}
436
437
/// True if the \p APValue \p Value can be folded onto the current line.
438
0
static bool isSimpleAPValue(const APValue &Value) {
439
0
  switch (Value.getKind()) {
440
0
  case APValue::None:
441
0
  case APValue::Indeterminate:
442
0
  case APValue::Int:
443
0
  case APValue::Float:
444
0
  case APValue::FixedPoint:
445
0
  case APValue::ComplexInt:
446
0
  case APValue::ComplexFloat:
447
0
  case APValue::LValue:
448
0
  case APValue::MemberPointer:
449
0
  case APValue::AddrLabelDiff:
450
0
    return true;
451
0
  case APValue::Vector:
452
0
  case APValue::Array:
453
0
  case APValue::Struct:
454
0
    return false;
455
0
  case APValue::Union:
456
0
    return isSimpleAPValue(Value.getUnionValue());
457
0
  }
458
0
  llvm_unreachable("unexpected APValue kind!");
459
0
}
460
461
/// Dump the children of the \p APValue \p Value.
462
///
463
/// \param[in] Value          The \p APValue to visit
464
/// \param[in] Ty             The \p QualType passed to \p Visit
465
///
466
/// \param[in] IdxToChildFun  A function mapping an \p APValue and an index
467
///                           to one of the child of the \p APValue
468
///
469
/// \param[in] NumChildren    \p IdxToChildFun will be called on \p Value with
470
///                           the indices in the range \p [0,NumChildren(
471
///
472
/// \param[in] LabelSingular  The label to use on a line with a single child
473
/// \param[in] LabelPlurial   The label to use on a line with multiple children
474
void TextNodeDumper::dumpAPValueChildren(
475
    const APValue &Value, QualType Ty,
476
    const APValue &(*IdxToChildFun)(const APValue &, unsigned),
477
0
    unsigned NumChildren, StringRef LabelSingular, StringRef LabelPlurial) {
478
  // To save some vertical space we print up to MaxChildrenPerLine APValues
479
  // considered to be simple (by isSimpleAPValue) on a single line.
480
0
  constexpr unsigned MaxChildrenPerLine = 4;
481
0
  unsigned I = 0;
482
0
  while (I < NumChildren) {
483
0
    unsigned J = I;
484
0
    while (J < NumChildren) {
485
0
      if (isSimpleAPValue(IdxToChildFun(Value, J)) &&
486
0
          (J - I < MaxChildrenPerLine)) {
487
0
        ++J;
488
0
        continue;
489
0
      }
490
0
      break;
491
0
    }
492
493
0
    J = std::max(I + 1, J);
494
495
    // Print [I,J) on a single line.
496
0
    AddChild(J - I > 1 ? LabelPlurial : LabelSingular, [=]() {
497
0
      for (unsigned X = I; X < J; ++X) {
498
0
        Visit(IdxToChildFun(Value, X), Ty);
499
0
        if (X + 1 != J)
500
0
          OS << ", ";
501
0
      }
502
0
    });
503
0
    I = J;
504
0
  }
505
0
}
506
507
0
void TextNodeDumper::Visit(const APValue &Value, QualType Ty) {
508
0
  ColorScope Color(OS, ShowColors, ValueKindColor);
509
0
  switch (Value.getKind()) {
510
0
  case APValue::None:
511
0
    OS << "None";
512
0
    return;
513
0
  case APValue::Indeterminate:
514
0
    OS << "Indeterminate";
515
0
    return;
516
0
  case APValue::Int:
517
0
    OS << "Int ";
518
0
    {
519
0
      ColorScope Color(OS, ShowColors, ValueColor);
520
0
      OS << Value.getInt();
521
0
    }
522
0
    return;
523
0
  case APValue::Float:
524
0
    OS << "Float ";
525
0
    {
526
0
      ColorScope Color(OS, ShowColors, ValueColor);
527
0
      OS << GetApproxValue(Value.getFloat());
528
0
    }
529
0
    return;
530
0
  case APValue::FixedPoint:
531
0
    OS << "FixedPoint ";
532
0
    {
533
0
      ColorScope Color(OS, ShowColors, ValueColor);
534
0
      OS << Value.getFixedPoint();
535
0
    }
536
0
    return;
537
0
  case APValue::Vector: {
538
0
    unsigned VectorLength = Value.getVectorLength();
539
0
    OS << "Vector length=" << VectorLength;
540
541
0
    dumpAPValueChildren(
542
0
        Value, Ty,
543
0
        [](const APValue &Value, unsigned Index) -> const APValue & {
544
0
          return Value.getVectorElt(Index);
545
0
        },
546
0
        VectorLength, "element", "elements");
547
0
    return;
548
0
  }
549
0
  case APValue::ComplexInt:
550
0
    OS << "ComplexInt ";
551
0
    {
552
0
      ColorScope Color(OS, ShowColors, ValueColor);
553
0
      OS << Value.getComplexIntReal() << " + " << Value.getComplexIntImag()
554
0
         << 'i';
555
0
    }
556
0
    return;
557
0
  case APValue::ComplexFloat:
558
0
    OS << "ComplexFloat ";
559
0
    {
560
0
      ColorScope Color(OS, ShowColors, ValueColor);
561
0
      OS << GetApproxValue(Value.getComplexFloatReal()) << " + "
562
0
         << GetApproxValue(Value.getComplexFloatImag()) << 'i';
563
0
    }
564
0
    return;
565
0
  case APValue::LValue:
566
0
    (void)Context;
567
0
    OS << "LValue <todo>";
568
0
    return;
569
0
  case APValue::Array: {
570
0
    unsigned ArraySize = Value.getArraySize();
571
0
    unsigned NumInitializedElements = Value.getArrayInitializedElts();
572
0
    OS << "Array size=" << ArraySize;
573
574
0
    dumpAPValueChildren(
575
0
        Value, Ty,
576
0
        [](const APValue &Value, unsigned Index) -> const APValue & {
577
0
          return Value.getArrayInitializedElt(Index);
578
0
        },
579
0
        NumInitializedElements, "element", "elements");
580
581
0
    if (Value.hasArrayFiller()) {
582
0
      AddChild("filler", [=] {
583
0
        {
584
0
          ColorScope Color(OS, ShowColors, ValueColor);
585
0
          OS << ArraySize - NumInitializedElements << " x ";
586
0
        }
587
0
        Visit(Value.getArrayFiller(), Ty);
588
0
      });
589
0
    }
590
591
0
    return;
592
0
  }
593
0
  case APValue::Struct: {
594
0
    OS << "Struct";
595
596
0
    dumpAPValueChildren(
597
0
        Value, Ty,
598
0
        [](const APValue &Value, unsigned Index) -> const APValue & {
599
0
          return Value.getStructBase(Index);
600
0
        },
601
0
        Value.getStructNumBases(), "base", "bases");
602
603
0
    dumpAPValueChildren(
604
0
        Value, Ty,
605
0
        [](const APValue &Value, unsigned Index) -> const APValue & {
606
0
          return Value.getStructField(Index);
607
0
        },
608
0
        Value.getStructNumFields(), "field", "fields");
609
610
0
    return;
611
0
  }
612
0
  case APValue::Union: {
613
0
    OS << "Union";
614
0
    {
615
0
      ColorScope Color(OS, ShowColors, ValueColor);
616
0
      if (const FieldDecl *FD = Value.getUnionField())
617
0
        OS << " ." << *cast<NamedDecl>(FD);
618
0
    }
619
    // If the union value is considered to be simple, fold it into the
620
    // current line to save some vertical space.
621
0
    const APValue &UnionValue = Value.getUnionValue();
622
0
    if (isSimpleAPValue(UnionValue)) {
623
0
      OS << ' ';
624
0
      Visit(UnionValue, Ty);
625
0
    } else {
626
0
      AddChild([=] { Visit(UnionValue, Ty); });
627
0
    }
628
629
0
    return;
630
0
  }
631
0
  case APValue::MemberPointer:
632
0
    OS << "MemberPointer <todo>";
633
0
    return;
634
0
  case APValue::AddrLabelDiff:
635
0
    OS << "AddrLabelDiff <todo>";
636
0
    return;
637
0
  }
638
0
  llvm_unreachable("Unknown APValue kind!");
639
0
}
640
641
0
void TextNodeDumper::dumpPointer(const void *Ptr) {
642
0
  ColorScope Color(OS, ShowColors, AddressColor);
643
0
  OS << ' ' << Ptr;
644
0
}
645
646
0
void TextNodeDumper::dumpLocation(SourceLocation Loc) {
647
0
  if (!SM)
648
0
    return;
649
650
0
  ColorScope Color(OS, ShowColors, LocationColor);
651
0
  SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
652
653
  // The general format we print out is filename:line:col, but we drop pieces
654
  // that haven't changed since the last loc printed.
655
0
  PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
656
657
0
  if (PLoc.isInvalid()) {
658
0
    OS << "<invalid sloc>";
659
0
    return;
660
0
  }
661
662
0
  if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
663
0
    OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':'
664
0
       << PLoc.getColumn();
665
0
    LastLocFilename = PLoc.getFilename();
666
0
    LastLocLine = PLoc.getLine();
667
0
  } else if (PLoc.getLine() != LastLocLine) {
668
0
    OS << "line" << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
669
0
    LastLocLine = PLoc.getLine();
670
0
  } else {
671
0
    OS << "col" << ':' << PLoc.getColumn();
672
0
  }
673
0
}
674
675
0
void TextNodeDumper::dumpSourceRange(SourceRange R) {
676
  // Can't translate locations if a SourceManager isn't available.
677
0
  if (!SM)
678
0
    return;
679
680
0
  OS << " <";
681
0
  dumpLocation(R.getBegin());
682
0
  if (R.getBegin() != R.getEnd()) {
683
0
    OS << ", ";
684
0
    dumpLocation(R.getEnd());
685
0
  }
686
0
  OS << ">";
687
688
  // <t2.c:123:421[blah], t2.c:412:321>
689
0
}
690
691
0
void TextNodeDumper::dumpBareType(QualType T, bool Desugar) {
692
0
  ColorScope Color(OS, ShowColors, TypeColor);
693
694
0
  SplitQualType T_split = T.split();
695
0
  std::string T_str = QualType::getAsString(T_split, PrintPolicy);
696
0
  OS << "'" << T_str << "'";
697
698
0
  if (Desugar && !T.isNull()) {
699
    // If the type is sugared, also dump a (shallow) desugared type when
700
    // it is visibly different.
701
0
    SplitQualType D_split = T.getSplitDesugaredType();
702
0
    if (T_split != D_split) {
703
0
      std::string D_str = QualType::getAsString(D_split, PrintPolicy);
704
0
      if (T_str != D_str)
705
0
        OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'";
706
0
    }
707
0
  }
708
0
}
709
710
0
void TextNodeDumper::dumpType(QualType T) {
711
0
  OS << ' ';
712
0
  dumpBareType(T);
713
0
}
714
715
0
void TextNodeDumper::dumpBareDeclRef(const Decl *D) {
716
0
  if (!D) {
717
0
    ColorScope Color(OS, ShowColors, NullColor);
718
0
    OS << "<<<NULL>>>";
719
0
    return;
720
0
  }
721
722
0
  {
723
0
    ColorScope Color(OS, ShowColors, DeclKindNameColor);
724
0
    OS << D->getDeclKindName();
725
0
  }
726
0
  dumpPointer(D);
727
728
0
  if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
729
0
    ColorScope Color(OS, ShowColors, DeclNameColor);
730
0
    OS << " '" << ND->getDeclName() << '\'';
731
0
  }
732
733
0
  if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
734
0
    dumpType(VD->getType());
735
0
}
736
737
0
void TextNodeDumper::dumpName(const NamedDecl *ND) {
738
0
  if (ND->getDeclName()) {
739
0
    ColorScope Color(OS, ShowColors, DeclNameColor);
740
0
    OS << ' ' << ND->getDeclName();
741
0
  }
742
0
}
743
744
0
void TextNodeDumper::dumpAccessSpecifier(AccessSpecifier AS) {
745
0
  const auto AccessSpelling = getAccessSpelling(AS);
746
0
  if (AccessSpelling.empty())
747
0
    return;
748
0
  OS << AccessSpelling;
749
0
}
750
751
void TextNodeDumper::dumpCleanupObject(
752
0
    const ExprWithCleanups::CleanupObject &C) {
753
0
  if (auto *BD = C.dyn_cast<BlockDecl *>())
754
0
    dumpDeclRef(BD, "cleanup");
755
0
  else if (auto *CLE = C.dyn_cast<CompoundLiteralExpr *>())
756
0
    AddChild([=] {
757
0
      OS << "cleanup ";
758
0
      {
759
0
        ColorScope Color(OS, ShowColors, StmtColor);
760
0
        OS << CLE->getStmtClassName();
761
0
      }
762
0
      dumpPointer(CLE);
763
0
    });
764
0
  else
765
0
    llvm_unreachable("unexpected cleanup type");
766
0
}
767
768
void clang::TextNodeDumper::dumpTemplateSpecializationKind(
769
0
    TemplateSpecializationKind TSK) {
770
0
  switch (TSK) {
771
0
  case TSK_Undeclared:
772
0
    break;
773
0
  case TSK_ImplicitInstantiation:
774
0
    OS << " implicit_instantiation";
775
0
    break;
776
0
  case TSK_ExplicitSpecialization:
777
0
    OS << " explicit_specialization";
778
0
    break;
779
0
  case TSK_ExplicitInstantiationDeclaration:
780
0
    OS << " explicit_instantiation_declaration";
781
0
    break;
782
0
  case TSK_ExplicitInstantiationDefinition:
783
0
    OS << " explicit_instantiation_definition";
784
0
    break;
785
0
  }
786
0
}
787
788
0
void clang::TextNodeDumper::dumpNestedNameSpecifier(const NestedNameSpecifier *NNS) {
789
0
  if (!NNS)
790
0
    return;
791
792
0
  AddChild([=] {
793
0
    OS << "NestedNameSpecifier";
794
795
0
    switch (NNS->getKind()) {
796
0
    case NestedNameSpecifier::Identifier:
797
0
      OS << " Identifier";
798
0
      OS << " '" << NNS->getAsIdentifier()->getName() << "'";
799
0
      break;
800
0
    case NestedNameSpecifier::Namespace:
801
0
      OS << " "; // "Namespace" is printed as the decl kind.
802
0
      dumpBareDeclRef(NNS->getAsNamespace());
803
0
      break;
804
0
    case NestedNameSpecifier::NamespaceAlias:
805
0
      OS << " "; // "NamespaceAlias" is printed as the decl kind.
806
0
      dumpBareDeclRef(NNS->getAsNamespaceAlias());
807
0
      break;
808
0
    case NestedNameSpecifier::TypeSpec:
809
0
      OS << " TypeSpec";
810
0
      dumpType(QualType(NNS->getAsType(), 0));
811
0
      break;
812
0
    case NestedNameSpecifier::TypeSpecWithTemplate:
813
0
      OS << " TypeSpecWithTemplate";
814
0
      dumpType(QualType(NNS->getAsType(), 0));
815
0
      break;
816
0
    case NestedNameSpecifier::Global:
817
0
      OS << " Global";
818
0
      break;
819
0
    case NestedNameSpecifier::Super:
820
0
      OS << " Super";
821
0
      break;
822
0
    }
823
824
0
    dumpNestedNameSpecifier(NNS->getPrefix());
825
0
  });
826
0
}
827
828
0
void TextNodeDumper::dumpDeclRef(const Decl *D, StringRef Label) {
829
0
  if (!D)
830
0
    return;
831
832
0
  AddChild([=] {
833
0
    if (!Label.empty())
834
0
      OS << Label << ' ';
835
0
    dumpBareDeclRef(D);
836
0
  });
837
0
}
838
839
0
const char *TextNodeDumper::getCommandName(unsigned CommandID) {
840
0
  if (Traits)
841
0
    return Traits->getCommandInfo(CommandID)->Name;
842
0
  const comments::CommandInfo *Info =
843
0
      comments::CommandTraits::getBuiltinCommandInfo(CommandID);
844
0
  if (Info)
845
0
    return Info->Name;
846
0
  return "<not a builtin command>";
847
0
}
848
849
0
void TextNodeDumper::printFPOptions(FPOptionsOverride FPO) {
850
0
#define OPTION(NAME, TYPE, WIDTH, PREVIOUS)                                    \
851
0
  if (FPO.has##NAME##Override())                                               \
852
0
    OS << " " #NAME "=" << FPO.get##NAME##Override();
853
0
#include "clang/Basic/FPOptions.def"
854
0
}
855
856
void TextNodeDumper::visitTextComment(const comments::TextComment *C,
857
0
                                      const comments::FullComment *) {
858
0
  OS << " Text=\"" << C->getText() << "\"";
859
0
}
860
861
void TextNodeDumper::visitInlineCommandComment(
862
0
    const comments::InlineCommandComment *C, const comments::FullComment *) {
863
0
  OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
864
0
  switch (C->getRenderKind()) {
865
0
  case comments::InlineCommandRenderKind::Normal:
866
0
    OS << " RenderNormal";
867
0
    break;
868
0
  case comments::InlineCommandRenderKind::Bold:
869
0
    OS << " RenderBold";
870
0
    break;
871
0
  case comments::InlineCommandRenderKind::Monospaced:
872
0
    OS << " RenderMonospaced";
873
0
    break;
874
0
  case comments::InlineCommandRenderKind::Emphasized:
875
0
    OS << " RenderEmphasized";
876
0
    break;
877
0
  case comments::InlineCommandRenderKind::Anchor:
878
0
    OS << " RenderAnchor";
879
0
    break;
880
0
  }
881
882
0
  for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
883
0
    OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
884
0
}
885
886
void TextNodeDumper::visitHTMLStartTagComment(
887
0
    const comments::HTMLStartTagComment *C, const comments::FullComment *) {
888
0
  OS << " Name=\"" << C->getTagName() << "\"";
889
0
  if (C->getNumAttrs() != 0) {
890
0
    OS << " Attrs: ";
891
0
    for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
892
0
      const comments::HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
893
0
      OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
894
0
    }
895
0
  }
896
0
  if (C->isSelfClosing())
897
0
    OS << " SelfClosing";
898
0
}
899
900
void TextNodeDumper::visitHTMLEndTagComment(
901
0
    const comments::HTMLEndTagComment *C, const comments::FullComment *) {
902
0
  OS << " Name=\"" << C->getTagName() << "\"";
903
0
}
904
905
void TextNodeDumper::visitBlockCommandComment(
906
0
    const comments::BlockCommandComment *C, const comments::FullComment *) {
907
0
  OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
908
0
  for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
909
0
    OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
910
0
}
911
912
void TextNodeDumper::visitParamCommandComment(
913
0
    const comments::ParamCommandComment *C, const comments::FullComment *FC) {
914
0
  OS << " "
915
0
     << comments::ParamCommandComment::getDirectionAsString(C->getDirection());
916
917
0
  if (C->isDirectionExplicit())
918
0
    OS << " explicitly";
919
0
  else
920
0
    OS << " implicitly";
921
922
0
  if (C->hasParamName()) {
923
0
    if (C->isParamIndexValid())
924
0
      OS << " Param=\"" << C->getParamName(FC) << "\"";
925
0
    else
926
0
      OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
927
0
  }
928
929
0
  if (C->isParamIndexValid() && !C->isVarArgParam())
930
0
    OS << " ParamIndex=" << C->getParamIndex();
931
0
}
932
933
void TextNodeDumper::visitTParamCommandComment(
934
0
    const comments::TParamCommandComment *C, const comments::FullComment *FC) {
935
0
  if (C->hasParamName()) {
936
0
    if (C->isPositionValid())
937
0
      OS << " Param=\"" << C->getParamName(FC) << "\"";
938
0
    else
939
0
      OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
940
0
  }
941
942
0
  if (C->isPositionValid()) {
943
0
    OS << " Position=<";
944
0
    for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
945
0
      OS << C->getIndex(i);
946
0
      if (i != e - 1)
947
0
        OS << ", ";
948
0
    }
949
0
    OS << ">";
950
0
  }
951
0
}
952
953
void TextNodeDumper::visitVerbatimBlockComment(
954
0
    const comments::VerbatimBlockComment *C, const comments::FullComment *) {
955
0
  OS << " Name=\"" << getCommandName(C->getCommandID())
956
0
     << "\""
957
0
        " CloseName=\""
958
0
     << C->getCloseName() << "\"";
959
0
}
960
961
void TextNodeDumper::visitVerbatimBlockLineComment(
962
    const comments::VerbatimBlockLineComment *C,
963
0
    const comments::FullComment *) {
964
0
  OS << " Text=\"" << C->getText() << "\"";
965
0
}
966
967
void TextNodeDumper::visitVerbatimLineComment(
968
0
    const comments::VerbatimLineComment *C, const comments::FullComment *) {
969
0
  OS << " Text=\"" << C->getText() << "\"";
970
0
}
971
972
0
void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument &) {
973
0
  OS << " null";
974
0
}
975
976
0
void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) {
977
0
  OS << " type";
978
0
  dumpType(TA.getAsType());
979
0
}
980
981
void TextNodeDumper::VisitDeclarationTemplateArgument(
982
0
    const TemplateArgument &TA) {
983
0
  OS << " decl";
984
0
  dumpDeclRef(TA.getAsDecl());
985
0
}
986
987
0
void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &) {
988
0
  OS << " nullptr";
989
0
}
990
991
0
void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) {
992
0
  OS << " integral " << TA.getAsIntegral();
993
0
}
994
995
0
void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) {
996
0
  if (TA.getAsTemplate().getKind() == TemplateName::UsingTemplate)
997
0
    OS << " using";
998
0
  OS << " template ";
999
0
  TA.getAsTemplate().dump(OS);
1000
0
}
1001
1002
void TextNodeDumper::VisitTemplateExpansionTemplateArgument(
1003
0
    const TemplateArgument &TA) {
1004
0
  if (TA.getAsTemplateOrTemplatePattern().getKind() ==
1005
0
      TemplateName::UsingTemplate)
1006
0
    OS << " using";
1007
0
  OS << " template expansion ";
1008
0
  TA.getAsTemplateOrTemplatePattern().dump(OS);
1009
0
}
1010
1011
0
void TextNodeDumper::VisitExpressionTemplateArgument(const TemplateArgument &) {
1012
0
  OS << " expr";
1013
0
}
1014
1015
0
void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &) {
1016
0
  OS << " pack";
1017
0
}
1018
1019
0
static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
1020
0
  if (Node->path_empty())
1021
0
    return;
1022
1023
0
  OS << " (";
1024
0
  bool First = true;
1025
0
  for (CastExpr::path_const_iterator I = Node->path_begin(),
1026
0
                                     E = Node->path_end();
1027
0
       I != E; ++I) {
1028
0
    const CXXBaseSpecifier *Base = *I;
1029
0
    if (!First)
1030
0
      OS << " -> ";
1031
1032
0
    const auto *RD =
1033
0
        cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl());
1034
1035
0
    if (Base->isVirtual())
1036
0
      OS << "virtual ";
1037
0
    OS << RD->getName();
1038
0
    First = false;
1039
0
  }
1040
1041
0
  OS << ')';
1042
0
}
1043
1044
0
void TextNodeDumper::VisitIfStmt(const IfStmt *Node) {
1045
0
  if (Node->hasInitStorage())
1046
0
    OS << " has_init";
1047
0
  if (Node->hasVarStorage())
1048
0
    OS << " has_var";
1049
0
  if (Node->hasElseStorage())
1050
0
    OS << " has_else";
1051
0
  if (Node->isConstexpr())
1052
0
    OS << " constexpr";
1053
0
  if (Node->isConsteval()) {
1054
0
    OS << " ";
1055
0
    if (Node->isNegatedConsteval())
1056
0
      OS << "!";
1057
0
    OS << "consteval";
1058
0
  }
1059
0
}
1060
1061
0
void TextNodeDumper::VisitSwitchStmt(const SwitchStmt *Node) {
1062
0
  if (Node->hasInitStorage())
1063
0
    OS << " has_init";
1064
0
  if (Node->hasVarStorage())
1065
0
    OS << " has_var";
1066
0
}
1067
1068
0
void TextNodeDumper::VisitWhileStmt(const WhileStmt *Node) {
1069
0
  if (Node->hasVarStorage())
1070
0
    OS << " has_var";
1071
0
}
1072
1073
0
void TextNodeDumper::VisitLabelStmt(const LabelStmt *Node) {
1074
0
  OS << " '" << Node->getName() << "'";
1075
0
  if (Node->isSideEntry())
1076
0
    OS << " side_entry";
1077
0
}
1078
1079
0
void TextNodeDumper::VisitGotoStmt(const GotoStmt *Node) {
1080
0
  OS << " '" << Node->getLabel()->getName() << "'";
1081
0
  dumpPointer(Node->getLabel());
1082
0
}
1083
1084
0
void TextNodeDumper::VisitCaseStmt(const CaseStmt *Node) {
1085
0
  if (Node->caseStmtIsGNURange())
1086
0
    OS << " gnu_range";
1087
0
}
1088
1089
0
void clang::TextNodeDumper::VisitReturnStmt(const ReturnStmt *Node) {
1090
0
  if (const VarDecl *Cand = Node->getNRVOCandidate()) {
1091
0
    OS << " nrvo_candidate(";
1092
0
    dumpBareDeclRef(Cand);
1093
0
    OS << ")";
1094
0
  }
1095
0
}
1096
1097
0
void clang::TextNodeDumper::VisitCoawaitExpr(const CoawaitExpr *Node) {
1098
0
  if (Node->isImplicit())
1099
0
    OS << " implicit";
1100
0
}
1101
1102
0
void clang::TextNodeDumper::VisitCoreturnStmt(const CoreturnStmt *Node) {
1103
0
  if (Node->isImplicit())
1104
0
    OS << " implicit";
1105
0
}
1106
1107
0
void TextNodeDumper::VisitConstantExpr(const ConstantExpr *Node) {
1108
0
  if (Node->hasAPValueResult())
1109
0
    AddChild("value",
1110
0
             [=] { Visit(Node->getAPValueResult(), Node->getType()); });
1111
0
}
1112
1113
0
void TextNodeDumper::VisitCallExpr(const CallExpr *Node) {
1114
0
  if (Node->usesADL())
1115
0
    OS << " adl";
1116
0
  if (Node->hasStoredFPFeatures())
1117
0
    printFPOptions(Node->getFPFeatures());
1118
0
}
1119
1120
0
void TextNodeDumper::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *Node) {
1121
0
  const char *OperatorSpelling = clang::getOperatorSpelling(Node->getOperator());
1122
0
  if (OperatorSpelling)
1123
0
    OS << " '" << OperatorSpelling << "'";
1124
1125
0
  VisitCallExpr(Node);
1126
0
}
1127
1128
0
void TextNodeDumper::VisitCastExpr(const CastExpr *Node) {
1129
0
  OS << " <";
1130
0
  {
1131
0
    ColorScope Color(OS, ShowColors, CastColor);
1132
0
    OS << Node->getCastKindName();
1133
0
  }
1134
0
  dumpBasePath(OS, Node);
1135
0
  OS << ">";
1136
0
  if (Node->hasStoredFPFeatures())
1137
0
    printFPOptions(Node->getFPFeatures());
1138
0
}
1139
1140
0
void TextNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) {
1141
0
  VisitCastExpr(Node);
1142
0
  if (Node->isPartOfExplicitCast())
1143
0
    OS << " part_of_explicit_cast";
1144
0
}
1145
1146
0
void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
1147
0
  OS << " ";
1148
0
  dumpBareDeclRef(Node->getDecl());
1149
0
  dumpNestedNameSpecifier(Node->getQualifier());
1150
0
  if (Node->getDecl() != Node->getFoundDecl()) {
1151
0
    OS << " (";
1152
0
    dumpBareDeclRef(Node->getFoundDecl());
1153
0
    OS << ")";
1154
0
  }
1155
0
  switch (Node->isNonOdrUse()) {
1156
0
  case NOUR_None: break;
1157
0
  case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break;
1158
0
  case NOUR_Constant: OS << " non_odr_use_constant"; break;
1159
0
  case NOUR_Discarded: OS << " non_odr_use_discarded"; break;
1160
0
  }
1161
0
  if (Node->refersToEnclosingVariableOrCapture())
1162
0
    OS << " refers_to_enclosing_variable_or_capture";
1163
0
  if (Node->isImmediateEscalating())
1164
0
    OS << " immediate-escalating";
1165
0
}
1166
1167
void clang::TextNodeDumper::VisitDependentScopeDeclRefExpr(
1168
0
    const DependentScopeDeclRefExpr *Node) {
1169
1170
0
  dumpNestedNameSpecifier(Node->getQualifier());
1171
0
}
1172
1173
void TextNodeDumper::VisitUnresolvedLookupExpr(
1174
0
    const UnresolvedLookupExpr *Node) {
1175
0
  OS << " (";
1176
0
  if (!Node->requiresADL())
1177
0
    OS << "no ";
1178
0
  OS << "ADL) = '" << Node->getName() << '\'';
1179
1180
0
  UnresolvedLookupExpr::decls_iterator I = Node->decls_begin(),
1181
0
                                       E = Node->decls_end();
1182
0
  if (I == E)
1183
0
    OS << " empty";
1184
0
  for (; I != E; ++I)
1185
0
    dumpPointer(*I);
1186
0
}
1187
1188
0
void TextNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) {
1189
0
  {
1190
0
    ColorScope Color(OS, ShowColors, DeclKindNameColor);
1191
0
    OS << " " << Node->getDecl()->getDeclKindName() << "Decl";
1192
0
  }
1193
0
  OS << "='" << *Node->getDecl() << "'";
1194
0
  dumpPointer(Node->getDecl());
1195
0
  if (Node->isFreeIvar())
1196
0
    OS << " isFreeIvar";
1197
0
}
1198
1199
void TextNodeDumper::VisitSYCLUniqueStableNameExpr(
1200
0
    const SYCLUniqueStableNameExpr *Node) {
1201
0
  dumpType(Node->getTypeSourceInfo()->getType());
1202
0
}
1203
1204
0
void TextNodeDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
1205
0
  OS << " " << PredefinedExpr::getIdentKindName(Node->getIdentKind());
1206
0
}
1207
1208
0
void TextNodeDumper::VisitCharacterLiteral(const CharacterLiteral *Node) {
1209
0
  ColorScope Color(OS, ShowColors, ValueColor);
1210
0
  OS << " " << Node->getValue();
1211
0
}
1212
1213
0
void TextNodeDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
1214
0
  bool isSigned = Node->getType()->isSignedIntegerType();
1215
0
  ColorScope Color(OS, ShowColors, ValueColor);
1216
0
  OS << " " << toString(Node->getValue(), 10, isSigned);
1217
0
}
1218
1219
0
void TextNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *Node) {
1220
0
  ColorScope Color(OS, ShowColors, ValueColor);
1221
0
  OS << " " << Node->getValueAsString(/*Radix=*/10);
1222
0
}
1223
1224
0
void TextNodeDumper::VisitFloatingLiteral(const FloatingLiteral *Node) {
1225
0
  ColorScope Color(OS, ShowColors, ValueColor);
1226
0
  OS << " " << Node->getValueAsApproximateDouble();
1227
0
}
1228
1229
0
void TextNodeDumper::VisitStringLiteral(const StringLiteral *Str) {
1230
0
  ColorScope Color(OS, ShowColors, ValueColor);
1231
0
  OS << " ";
1232
0
  Str->outputString(OS);
1233
0
}
1234
1235
0
void TextNodeDumper::VisitInitListExpr(const InitListExpr *ILE) {
1236
0
  if (auto *Field = ILE->getInitializedFieldInUnion()) {
1237
0
    OS << " field ";
1238
0
    dumpBareDeclRef(Field);
1239
0
  }
1240
0
}
1241
1242
0
void TextNodeDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
1243
0
  if (E->isResultDependent())
1244
0
    OS << " result_dependent";
1245
0
}
1246
1247
0
void TextNodeDumper::VisitUnaryOperator(const UnaryOperator *Node) {
1248
0
  OS << " " << (Node->isPostfix() ? "postfix" : "prefix") << " '"
1249
0
     << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1250
0
  if (!Node->canOverflow())
1251
0
    OS << " cannot overflow";
1252
0
  if (Node->hasStoredFPFeatures())
1253
0
    printFPOptions(Node->getStoredFPFeatures());
1254
0
}
1255
1256
void TextNodeDumper::VisitUnaryExprOrTypeTraitExpr(
1257
0
    const UnaryExprOrTypeTraitExpr *Node) {
1258
0
  OS << " " << getTraitSpelling(Node->getKind());
1259
1260
0
  if (Node->isArgumentType())
1261
0
    dumpType(Node->getArgumentType());
1262
0
}
1263
1264
0
void TextNodeDumper::VisitMemberExpr(const MemberExpr *Node) {
1265
0
  OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl();
1266
0
  dumpPointer(Node->getMemberDecl());
1267
0
  dumpNestedNameSpecifier(Node->getQualifier());
1268
0
  switch (Node->isNonOdrUse()) {
1269
0
  case NOUR_None: break;
1270
0
  case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break;
1271
0
  case NOUR_Constant: OS << " non_odr_use_constant"; break;
1272
0
  case NOUR_Discarded: OS << " non_odr_use_discarded"; break;
1273
0
  }
1274
0
}
1275
1276
void TextNodeDumper::VisitExtVectorElementExpr(
1277
0
    const ExtVectorElementExpr *Node) {
1278
0
  OS << " " << Node->getAccessor().getNameStart();
1279
0
}
1280
1281
0
void TextNodeDumper::VisitBinaryOperator(const BinaryOperator *Node) {
1282
0
  OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1283
0
  if (Node->hasStoredFPFeatures())
1284
0
    printFPOptions(Node->getStoredFPFeatures());
1285
0
}
1286
1287
void TextNodeDumper::VisitCompoundAssignOperator(
1288
0
    const CompoundAssignOperator *Node) {
1289
0
  OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
1290
0
     << "' ComputeLHSTy=";
1291
0
  dumpBareType(Node->getComputationLHSType());
1292
0
  OS << " ComputeResultTy=";
1293
0
  dumpBareType(Node->getComputationResultType());
1294
0
  if (Node->hasStoredFPFeatures())
1295
0
    printFPOptions(Node->getStoredFPFeatures());
1296
0
}
1297
1298
0
void TextNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) {
1299
0
  OS << " " << Node->getLabel()->getName();
1300
0
  dumpPointer(Node->getLabel());
1301
0
}
1302
1303
0
void TextNodeDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) {
1304
0
  OS << " " << Node->getCastName() << "<"
1305
0
     << Node->getTypeAsWritten().getAsString() << ">"
1306
0
     << " <" << Node->getCastKindName();
1307
0
  dumpBasePath(OS, Node);
1308
0
  OS << ">";
1309
0
}
1310
1311
0
void TextNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
1312
0
  OS << " " << (Node->getValue() ? "true" : "false");
1313
0
}
1314
1315
0
void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
1316
0
  if (Node->isImplicit())
1317
0
    OS << " implicit";
1318
0
  OS << " this";
1319
0
}
1320
1321
void TextNodeDumper::VisitCXXFunctionalCastExpr(
1322
0
    const CXXFunctionalCastExpr *Node) {
1323
0
  OS << " functional cast to " << Node->getTypeAsWritten().getAsString() << " <"
1324
0
     << Node->getCastKindName() << ">";
1325
0
  if (Node->hasStoredFPFeatures())
1326
0
    printFPOptions(Node->getFPFeatures());
1327
0
}
1328
1329
0
void TextNodeDumper::VisitCXXStaticCastExpr(const CXXStaticCastExpr *Node) {
1330
0
  VisitCXXNamedCastExpr(Node);
1331
0
  if (Node->hasStoredFPFeatures())
1332
0
    printFPOptions(Node->getFPFeatures());
1333
0
}
1334
1335
void TextNodeDumper::VisitCXXUnresolvedConstructExpr(
1336
0
    const CXXUnresolvedConstructExpr *Node) {
1337
0
  dumpType(Node->getTypeAsWritten());
1338
0
  if (Node->isListInitialization())
1339
0
    OS << " list";
1340
0
}
1341
1342
0
void TextNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
1343
0
  CXXConstructorDecl *Ctor = Node->getConstructor();
1344
0
  dumpType(Ctor->getType());
1345
0
  if (Node->isElidable())
1346
0
    OS << " elidable";
1347
0
  if (Node->isListInitialization())
1348
0
    OS << " list";
1349
0
  if (Node->isStdInitListInitialization())
1350
0
    OS << " std::initializer_list";
1351
0
  if (Node->requiresZeroInitialization())
1352
0
    OS << " zeroing";
1353
0
  if (Node->isImmediateEscalating())
1354
0
    OS << " immediate-escalating";
1355
0
}
1356
1357
void TextNodeDumper::VisitCXXBindTemporaryExpr(
1358
0
    const CXXBindTemporaryExpr *Node) {
1359
0
  OS << " (CXXTemporary";
1360
0
  dumpPointer(Node);
1361
0
  OS << ")";
1362
0
}
1363
1364
0
void TextNodeDumper::VisitCXXNewExpr(const CXXNewExpr *Node) {
1365
0
  if (Node->isGlobalNew())
1366
0
    OS << " global";
1367
0
  if (Node->isArray())
1368
0
    OS << " array";
1369
0
  if (Node->getOperatorNew()) {
1370
0
    OS << ' ';
1371
0
    dumpBareDeclRef(Node->getOperatorNew());
1372
0
  }
1373
  // We could dump the deallocation function used in case of error, but it's
1374
  // usually not that interesting.
1375
0
}
1376
1377
0
void TextNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *Node) {
1378
0
  if (Node->isGlobalDelete())
1379
0
    OS << " global";
1380
0
  if (Node->isArrayForm())
1381
0
    OS << " array";
1382
0
  if (Node->getOperatorDelete()) {
1383
0
    OS << ' ';
1384
0
    dumpBareDeclRef(Node->getOperatorDelete());
1385
0
  }
1386
0
}
1387
1388
0
void TextNodeDumper::VisitTypeTraitExpr(const TypeTraitExpr *Node) {
1389
0
  OS << " " << getTraitSpelling(Node->getTrait());
1390
0
}
1391
1392
0
void TextNodeDumper::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *Node) {
1393
0
  OS << " " << getTraitSpelling(Node->getTrait());
1394
0
}
1395
1396
0
void TextNodeDumper::VisitExpressionTraitExpr(const ExpressionTraitExpr *Node) {
1397
0
  OS << " " << getTraitSpelling(Node->getTrait());
1398
0
}
1399
1400
void TextNodeDumper::VisitMaterializeTemporaryExpr(
1401
0
    const MaterializeTemporaryExpr *Node) {
1402
0
  if (const ValueDecl *VD = Node->getExtendingDecl()) {
1403
0
    OS << " extended by ";
1404
0
    dumpBareDeclRef(VD);
1405
0
  }
1406
0
}
1407
1408
0
void TextNodeDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) {
1409
0
  for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
1410
0
    dumpCleanupObject(Node->getObject(i));
1411
0
}
1412
1413
0
void TextNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
1414
0
  dumpPointer(Node->getPack());
1415
0
  dumpName(Node->getPack());
1416
0
}
1417
1418
void TextNodeDumper::VisitCXXDependentScopeMemberExpr(
1419
0
    const CXXDependentScopeMemberExpr *Node) {
1420
0
  OS << " " << (Node->isArrow() ? "->" : ".") << Node->getMember();
1421
0
}
1422
1423
0
void TextNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
1424
0
  OS << " selector=";
1425
0
  Node->getSelector().print(OS);
1426
0
  switch (Node->getReceiverKind()) {
1427
0
  case ObjCMessageExpr::Instance:
1428
0
    break;
1429
1430
0
  case ObjCMessageExpr::Class:
1431
0
    OS << " class=";
1432
0
    dumpBareType(Node->getClassReceiver());
1433
0
    break;
1434
1435
0
  case ObjCMessageExpr::SuperInstance:
1436
0
    OS << " super (instance)";
1437
0
    break;
1438
1439
0
  case ObjCMessageExpr::SuperClass:
1440
0
    OS << " super (class)";
1441
0
    break;
1442
0
  }
1443
0
}
1444
1445
0
void TextNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
1446
0
  if (auto *BoxingMethod = Node->getBoxingMethod()) {
1447
0
    OS << " selector=";
1448
0
    BoxingMethod->getSelector().print(OS);
1449
0
  }
1450
0
}
1451
1452
0
void TextNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
1453
0
  if (!Node->getCatchParamDecl())
1454
0
    OS << " catch all";
1455
0
}
1456
1457
0
void TextNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
1458
0
  dumpType(Node->getEncodedType());
1459
0
}
1460
1461
0
void TextNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
1462
0
  OS << " ";
1463
0
  Node->getSelector().print(OS);
1464
0
}
1465
1466
0
void TextNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
1467
0
  OS << ' ' << *Node->getProtocol();
1468
0
}
1469
1470
0
void TextNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) {
1471
0
  if (Node->isImplicitProperty()) {
1472
0
    OS << " Kind=MethodRef Getter=\"";
1473
0
    if (Node->getImplicitPropertyGetter())
1474
0
      Node->getImplicitPropertyGetter()->getSelector().print(OS);
1475
0
    else
1476
0
      OS << "(null)";
1477
1478
0
    OS << "\" Setter=\"";
1479
0
    if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
1480
0
      Setter->getSelector().print(OS);
1481
0
    else
1482
0
      OS << "(null)";
1483
0
    OS << "\"";
1484
0
  } else {
1485
0
    OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty()
1486
0
       << '"';
1487
0
  }
1488
1489
0
  if (Node->isSuperReceiver())
1490
0
    OS << " super";
1491
1492
0
  OS << " Messaging=";
1493
0
  if (Node->isMessagingGetter() && Node->isMessagingSetter())
1494
0
    OS << "Getter&Setter";
1495
0
  else if (Node->isMessagingGetter())
1496
0
    OS << "Getter";
1497
0
  else if (Node->isMessagingSetter())
1498
0
    OS << "Setter";
1499
0
}
1500
1501
void TextNodeDumper::VisitObjCSubscriptRefExpr(
1502
0
    const ObjCSubscriptRefExpr *Node) {
1503
0
  if (Node->isArraySubscriptRefExpr())
1504
0
    OS << " Kind=ArraySubscript GetterForArray=\"";
1505
0
  else
1506
0
    OS << " Kind=DictionarySubscript GetterForDictionary=\"";
1507
0
  if (Node->getAtIndexMethodDecl())
1508
0
    Node->getAtIndexMethodDecl()->getSelector().print(OS);
1509
0
  else
1510
0
    OS << "(null)";
1511
1512
0
  if (Node->isArraySubscriptRefExpr())
1513
0
    OS << "\" SetterForArray=\"";
1514
0
  else
1515
0
    OS << "\" SetterForDictionary=\"";
1516
0
  if (Node->setAtIndexMethodDecl())
1517
0
    Node->setAtIndexMethodDecl()->getSelector().print(OS);
1518
0
  else
1519
0
    OS << "(null)";
1520
0
}
1521
1522
0
void TextNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) {
1523
0
  OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
1524
0
}
1525
1526
0
void TextNodeDumper::VisitOMPIteratorExpr(const OMPIteratorExpr *Node) {
1527
0
  OS << " ";
1528
0
  for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) {
1529
0
    Visit(Node->getIteratorDecl(I));
1530
0
    OS << " = ";
1531
0
    const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I);
1532
0
    OS << " begin ";
1533
0
    Visit(Range.Begin);
1534
0
    OS << " end ";
1535
0
    Visit(Range.End);
1536
0
    if (Range.Step) {
1537
0
      OS << " step ";
1538
0
      Visit(Range.Step);
1539
0
    }
1540
0
  }
1541
0
}
1542
1543
void TextNodeDumper::VisitConceptSpecializationExpr(
1544
0
    const ConceptSpecializationExpr *Node) {
1545
0
  OS << " ";
1546
0
  dumpBareDeclRef(Node->getFoundDecl());
1547
0
}
1548
1549
void TextNodeDumper::VisitRequiresExpr(
1550
0
    const RequiresExpr *Node) {
1551
0
  if (!Node->isValueDependent())
1552
0
    OS << (Node->isSatisfied() ? " satisfied" : " unsatisfied");
1553
0
}
1554
1555
0
void TextNodeDumper::VisitRValueReferenceType(const ReferenceType *T) {
1556
0
  if (T->isSpelledAsLValue())
1557
0
    OS << " written as lvalue reference";
1558
0
}
1559
1560
0
void TextNodeDumper::VisitArrayType(const ArrayType *T) {
1561
0
  switch (T->getSizeModifier()) {
1562
0
  case ArraySizeModifier::Normal:
1563
0
    break;
1564
0
  case ArraySizeModifier::Static:
1565
0
    OS << " static";
1566
0
    break;
1567
0
  case ArraySizeModifier::Star:
1568
0
    OS << " *";
1569
0
    break;
1570
0
  }
1571
0
  OS << " " << T->getIndexTypeQualifiers().getAsString();
1572
0
}
1573
1574
0
void TextNodeDumper::VisitConstantArrayType(const ConstantArrayType *T) {
1575
0
  OS << " " << T->getSize();
1576
0
  VisitArrayType(T);
1577
0
}
1578
1579
0
void TextNodeDumper::VisitVariableArrayType(const VariableArrayType *T) {
1580
0
  OS << " ";
1581
0
  dumpSourceRange(T->getBracketsRange());
1582
0
  VisitArrayType(T);
1583
0
}
1584
1585
void TextNodeDumper::VisitDependentSizedArrayType(
1586
0
    const DependentSizedArrayType *T) {
1587
0
  VisitArrayType(T);
1588
0
  OS << " ";
1589
0
  dumpSourceRange(T->getBracketsRange());
1590
0
}
1591
1592
void TextNodeDumper::VisitDependentSizedExtVectorType(
1593
0
    const DependentSizedExtVectorType *T) {
1594
0
  OS << " ";
1595
0
  dumpLocation(T->getAttributeLoc());
1596
0
}
1597
1598
0
void TextNodeDumper::VisitVectorType(const VectorType *T) {
1599
0
  switch (T->getVectorKind()) {
1600
0
  case VectorKind::Generic:
1601
0
    break;
1602
0
  case VectorKind::AltiVecVector:
1603
0
    OS << " altivec";
1604
0
    break;
1605
0
  case VectorKind::AltiVecPixel:
1606
0
    OS << " altivec pixel";
1607
0
    break;
1608
0
  case VectorKind::AltiVecBool:
1609
0
    OS << " altivec bool";
1610
0
    break;
1611
0
  case VectorKind::Neon:
1612
0
    OS << " neon";
1613
0
    break;
1614
0
  case VectorKind::NeonPoly:
1615
0
    OS << " neon poly";
1616
0
    break;
1617
0
  case VectorKind::SveFixedLengthData:
1618
0
    OS << " fixed-length sve data vector";
1619
0
    break;
1620
0
  case VectorKind::SveFixedLengthPredicate:
1621
0
    OS << " fixed-length sve predicate vector";
1622
0
    break;
1623
0
  case VectorKind::RVVFixedLengthData:
1624
0
    OS << " fixed-length rvv data vector";
1625
0
    break;
1626
0
  }
1627
0
  OS << " " << T->getNumElements();
1628
0
}
1629
1630
0
void TextNodeDumper::VisitFunctionType(const FunctionType *T) {
1631
0
  auto EI = T->getExtInfo();
1632
0
  if (EI.getNoReturn())
1633
0
    OS << " noreturn";
1634
0
  if (EI.getProducesResult())
1635
0
    OS << " produces_result";
1636
0
  if (EI.getHasRegParm())
1637
0
    OS << " regparm " << EI.getRegParm();
1638
0
  OS << " " << FunctionType::getNameForCallConv(EI.getCC());
1639
0
}
1640
1641
0
void TextNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) {
1642
0
  auto EPI = T->getExtProtoInfo();
1643
0
  if (EPI.HasTrailingReturn)
1644
0
    OS << " trailing_return";
1645
0
  if (T->isConst())
1646
0
    OS << " const";
1647
0
  if (T->isVolatile())
1648
0
    OS << " volatile";
1649
0
  if (T->isRestrict())
1650
0
    OS << " restrict";
1651
0
  if (T->getExtProtoInfo().Variadic)
1652
0
    OS << " variadic";
1653
0
  switch (EPI.RefQualifier) {
1654
0
  case RQ_None:
1655
0
    break;
1656
0
  case RQ_LValue:
1657
0
    OS << " &";
1658
0
    break;
1659
0
  case RQ_RValue:
1660
0
    OS << " &&";
1661
0
    break;
1662
0
  }
1663
1664
0
  switch (EPI.ExceptionSpec.Type) {
1665
0
  case EST_None:
1666
0
    break;
1667
0
  case EST_DynamicNone:
1668
0
    OS << " exceptionspec_dynamic_none";
1669
0
    break;
1670
0
  case EST_Dynamic:
1671
0
    OS << " exceptionspec_dynamic";
1672
0
    break;
1673
0
  case EST_MSAny:
1674
0
    OS << " exceptionspec_ms_any";
1675
0
    break;
1676
0
  case EST_NoThrow:
1677
0
    OS << " exceptionspec_nothrow";
1678
0
    break;
1679
0
  case EST_BasicNoexcept:
1680
0
    OS << " exceptionspec_basic_noexcept";
1681
0
    break;
1682
0
  case EST_DependentNoexcept:
1683
0
    OS << " exceptionspec_dependent_noexcept";
1684
0
    break;
1685
0
  case EST_NoexceptFalse:
1686
0
    OS << " exceptionspec_noexcept_false";
1687
0
    break;
1688
0
  case EST_NoexceptTrue:
1689
0
    OS << " exceptionspec_noexcept_true";
1690
0
    break;
1691
0
  case EST_Unevaluated:
1692
0
    OS << " exceptionspec_unevaluated";
1693
0
    break;
1694
0
  case EST_Uninstantiated:
1695
0
    OS << " exceptionspec_uninstantiated";
1696
0
    break;
1697
0
  case EST_Unparsed:
1698
0
    OS << " exceptionspec_unparsed";
1699
0
    break;
1700
0
  }
1701
0
  if (!EPI.ExceptionSpec.Exceptions.empty()) {
1702
0
    AddChild([=] {
1703
0
      OS << "Exceptions:";
1704
0
      for (unsigned I = 0, N = EPI.ExceptionSpec.Exceptions.size(); I != N;
1705
0
           ++I) {
1706
0
        if (I)
1707
0
          OS << ",";
1708
0
        dumpType(EPI.ExceptionSpec.Exceptions[I]);
1709
0
      }
1710
0
    });
1711
0
  }
1712
0
  if (EPI.ExceptionSpec.NoexceptExpr) {
1713
0
    AddChild([=] {
1714
0
      OS << "NoexceptExpr: ";
1715
0
      Visit(EPI.ExceptionSpec.NoexceptExpr);
1716
0
    });
1717
0
  }
1718
0
  dumpDeclRef(EPI.ExceptionSpec.SourceDecl, "ExceptionSourceDecl");
1719
0
  dumpDeclRef(EPI.ExceptionSpec.SourceTemplate, "ExceptionSourceTemplate");
1720
1721
  // FIXME: Consumed parameters.
1722
0
  VisitFunctionType(T);
1723
0
}
1724
1725
0
void TextNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
1726
0
  dumpDeclRef(T->getDecl());
1727
0
}
1728
1729
0
void TextNodeDumper::VisitUsingType(const UsingType *T) {
1730
0
  dumpDeclRef(T->getFoundDecl());
1731
0
  if (!T->typeMatchesDecl())
1732
0
    OS << " divergent";
1733
0
}
1734
1735
0
void TextNodeDumper::VisitTypedefType(const TypedefType *T) {
1736
0
  dumpDeclRef(T->getDecl());
1737
0
  if (!T->typeMatchesDecl())
1738
0
    OS << " divergent";
1739
0
}
1740
1741
0
void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType *T) {
1742
0
  switch (T->getUTTKind()) {
1743
0
#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait)                                  \
1744
0
  case UnaryTransformType::Enum:                                               \
1745
0
    OS << " " #Trait;                                                          \
1746
0
    break;
1747
0
#include "clang/Basic/TransformTypeTraits.def"
1748
0
  }
1749
0
}
1750
1751
0
void TextNodeDumper::VisitTagType(const TagType *T) {
1752
0
  dumpDeclRef(T->getDecl());
1753
0
}
1754
1755
0
void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
1756
0
  OS << " depth " << T->getDepth() << " index " << T->getIndex();
1757
0
  if (T->isParameterPack())
1758
0
    OS << " pack";
1759
0
  dumpDeclRef(T->getDecl());
1760
0
}
1761
1762
void TextNodeDumper::VisitSubstTemplateTypeParmType(
1763
0
    const SubstTemplateTypeParmType *T) {
1764
0
  dumpDeclRef(T->getAssociatedDecl());
1765
0
  VisitTemplateTypeParmDecl(T->getReplacedParameter());
1766
0
  if (auto PackIndex = T->getPackIndex())
1767
0
    OS << " pack_index " << *PackIndex;
1768
0
}
1769
1770
void TextNodeDumper::VisitSubstTemplateTypeParmPackType(
1771
0
    const SubstTemplateTypeParmPackType *T) {
1772
0
  dumpDeclRef(T->getAssociatedDecl());
1773
0
  VisitTemplateTypeParmDecl(T->getReplacedParameter());
1774
0
}
1775
1776
0
void TextNodeDumper::VisitAutoType(const AutoType *T) {
1777
0
  if (T->isDecltypeAuto())
1778
0
    OS << " decltype(auto)";
1779
0
  if (!T->isDeduced())
1780
0
    OS << " undeduced";
1781
0
  if (T->isConstrained()) {
1782
0
    dumpDeclRef(T->getTypeConstraintConcept());
1783
0
    for (const auto &Arg : T->getTypeConstraintArguments())
1784
0
      VisitTemplateArgument(Arg);
1785
0
  }
1786
0
}
1787
1788
void TextNodeDumper::VisitDeducedTemplateSpecializationType(
1789
0
    const DeducedTemplateSpecializationType *T) {
1790
0
  if (T->getTemplateName().getKind() == TemplateName::UsingTemplate)
1791
0
    OS << " using";
1792
0
}
1793
1794
void TextNodeDumper::VisitTemplateSpecializationType(
1795
0
    const TemplateSpecializationType *T) {
1796
0
  if (T->isTypeAlias())
1797
0
    OS << " alias";
1798
0
  if (T->getTemplateName().getKind() == TemplateName::UsingTemplate)
1799
0
    OS << " using";
1800
0
  OS << " ";
1801
0
  T->getTemplateName().dump(OS);
1802
0
}
1803
1804
void TextNodeDumper::VisitInjectedClassNameType(
1805
0
    const InjectedClassNameType *T) {
1806
0
  dumpDeclRef(T->getDecl());
1807
0
}
1808
1809
0
void TextNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
1810
0
  dumpDeclRef(T->getDecl());
1811
0
}
1812
1813
0
void TextNodeDumper::VisitPackExpansionType(const PackExpansionType *T) {
1814
0
  if (auto N = T->getNumExpansions())
1815
0
    OS << " expansions " << *N;
1816
0
}
1817
1818
0
void TextNodeDumper::VisitLabelDecl(const LabelDecl *D) { dumpName(D); }
1819
1820
0
void TextNodeDumper::VisitTypedefDecl(const TypedefDecl *D) {
1821
0
  dumpName(D);
1822
0
  dumpType(D->getUnderlyingType());
1823
0
  if (D->isModulePrivate())
1824
0
    OS << " __module_private__";
1825
0
}
1826
1827
0
void TextNodeDumper::VisitEnumDecl(const EnumDecl *D) {
1828
0
  if (D->isScoped()) {
1829
0
    if (D->isScopedUsingClassTag())
1830
0
      OS << " class";
1831
0
    else
1832
0
      OS << " struct";
1833
0
  }
1834
0
  dumpName(D);
1835
0
  if (D->isModulePrivate())
1836
0
    OS << " __module_private__";
1837
0
  if (D->isFixed())
1838
0
    dumpType(D->getIntegerType());
1839
0
}
1840
1841
0
void TextNodeDumper::VisitRecordDecl(const RecordDecl *D) {
1842
0
  OS << ' ' << D->getKindName();
1843
0
  dumpName(D);
1844
0
  if (D->isModulePrivate())
1845
0
    OS << " __module_private__";
1846
0
  if (D->isCompleteDefinition())
1847
0
    OS << " definition";
1848
0
}
1849
1850
0
void TextNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
1851
0
  dumpName(D);
1852
0
  dumpType(D->getType());
1853
0
}
1854
1855
0
void TextNodeDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
1856
0
  dumpName(D);
1857
0
  dumpType(D->getType());
1858
1859
0
  for (const auto *Child : D->chain())
1860
0
    dumpDeclRef(Child);
1861
0
}
1862
1863
0
void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) {
1864
0
  dumpName(D);
1865
0
  dumpType(D->getType());
1866
0
  dumpTemplateSpecializationKind(D->getTemplateSpecializationKind());
1867
1868
0
  StorageClass SC = D->getStorageClass();
1869
0
  if (SC != SC_None)
1870
0
    OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
1871
0
  if (D->isInlineSpecified())
1872
0
    OS << " inline";
1873
0
  if (D->isVirtualAsWritten())
1874
0
    OS << " virtual";
1875
0
  if (D->isModulePrivate())
1876
0
    OS << " __module_private__";
1877
1878
0
  if (D->isPure())
1879
0
    OS << " pure";
1880
0
  if (D->isDefaulted()) {
1881
0
    OS << " default";
1882
0
    if (D->isDeleted())
1883
0
      OS << "_delete";
1884
0
  }
1885
0
  if (D->isDeletedAsWritten())
1886
0
    OS << " delete";
1887
0
  if (D->isTrivial())
1888
0
    OS << " trivial";
1889
1890
0
  if (D->isIneligibleOrNotSelected())
1891
0
    OS << (isa<CXXDestructorDecl>(D) ? " not_selected" : " ineligible");
1892
1893
0
  if (const auto *FPT = D->getType()->getAs<FunctionProtoType>()) {
1894
0
    FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
1895
0
    switch (EPI.ExceptionSpec.Type) {
1896
0
    default:
1897
0
      break;
1898
0
    case EST_Unevaluated:
1899
0
      OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl;
1900
0
      break;
1901
0
    case EST_Uninstantiated:
1902
0
      OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate;
1903
0
      break;
1904
0
    }
1905
0
  }
1906
1907
0
  if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
1908
0
    if (MD->size_overridden_methods() != 0) {
1909
0
      auto dumpOverride = [=](const CXXMethodDecl *D) {
1910
0
        SplitQualType T_split = D->getType().split();
1911
0
        OS << D << " " << D->getParent()->getName() << "::" << D->getDeclName()
1912
0
           << " '" << QualType::getAsString(T_split, PrintPolicy) << "'";
1913
0
      };
1914
1915
0
      AddChild([=] {
1916
0
        auto Overrides = MD->overridden_methods();
1917
0
        OS << "Overrides: [ ";
1918
0
        dumpOverride(*Overrides.begin());
1919
0
        for (const auto *Override : llvm::drop_begin(Overrides)) {
1920
0
          OS << ", ";
1921
0
          dumpOverride(Override);
1922
0
        }
1923
0
        OS << " ]";
1924
0
      });
1925
0
    }
1926
0
  }
1927
1928
0
  if (!D->isInlineSpecified() && D->isInlined()) {
1929
0
    OS << " implicit-inline";
1930
0
  }
1931
  // Since NumParams comes from the FunctionProtoType of the FunctionDecl and
1932
  // the Params are set later, it is possible for a dump during debugging to
1933
  // encounter a FunctionDecl that has been created but hasn't been assigned
1934
  // ParmVarDecls yet.
1935
0
  if (!D->param_empty() && !D->param_begin())
1936
0
    OS << " <<<NULL params x " << D->getNumParams() << ">>>";
1937
1938
0
  if (const auto *Instance = D->getInstantiatedFromMemberFunction()) {
1939
0
    OS << " instantiated_from";
1940
0
    dumpPointer(Instance);
1941
0
  }
1942
0
}
1943
1944
void TextNodeDumper::VisitLifetimeExtendedTemporaryDecl(
1945
0
    const LifetimeExtendedTemporaryDecl *D) {
1946
0
  OS << " extended by ";
1947
0
  dumpBareDeclRef(D->getExtendingDecl());
1948
0
  OS << " mangling ";
1949
0
  {
1950
0
    ColorScope Color(OS, ShowColors, ValueColor);
1951
0
    OS << D->getManglingNumber();
1952
0
  }
1953
0
}
1954
1955
0
void TextNodeDumper::VisitFieldDecl(const FieldDecl *D) {
1956
0
  dumpName(D);
1957
0
  dumpType(D->getType());
1958
0
  if (D->isMutable())
1959
0
    OS << " mutable";
1960
0
  if (D->isModulePrivate())
1961
0
    OS << " __module_private__";
1962
0
}
1963
1964
0
void TextNodeDumper::VisitVarDecl(const VarDecl *D) {
1965
0
  dumpNestedNameSpecifier(D->getQualifier());
1966
0
  dumpName(D);
1967
0
  if (const auto *P = dyn_cast<ParmVarDecl>(D);
1968
0
      P && P->isExplicitObjectParameter())
1969
0
    OS << " this";
1970
1971
0
  dumpType(D->getType());
1972
0
  dumpTemplateSpecializationKind(D->getTemplateSpecializationKind());
1973
0
  StorageClass SC = D->getStorageClass();
1974
0
  if (SC != SC_None)
1975
0
    OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
1976
0
  switch (D->getTLSKind()) {
1977
0
  case VarDecl::TLS_None:
1978
0
    break;
1979
0
  case VarDecl::TLS_Static:
1980
0
    OS << " tls";
1981
0
    break;
1982
0
  case VarDecl::TLS_Dynamic:
1983
0
    OS << " tls_dynamic";
1984
0
    break;
1985
0
  }
1986
0
  if (D->isModulePrivate())
1987
0
    OS << " __module_private__";
1988
0
  if (D->isNRVOVariable())
1989
0
    OS << " nrvo";
1990
0
  if (D->isInline())
1991
0
    OS << " inline";
1992
0
  if (D->isConstexpr())
1993
0
    OS << " constexpr";
1994
0
  if (D->hasInit()) {
1995
0
    switch (D->getInitStyle()) {
1996
0
    case VarDecl::CInit:
1997
0
      OS << " cinit";
1998
0
      break;
1999
0
    case VarDecl::CallInit:
2000
0
      OS << " callinit";
2001
0
      break;
2002
0
    case VarDecl::ListInit:
2003
0
      OS << " listinit";
2004
0
      break;
2005
0
    case VarDecl::ParenListInit:
2006
0
      OS << " parenlistinit";
2007
0
    }
2008
0
  }
2009
0
  if (D->needsDestruction(D->getASTContext()))
2010
0
    OS << " destroyed";
2011
0
  if (D->isParameterPack())
2012
0
    OS << " pack";
2013
2014
0
  if (D->hasInit()) {
2015
0
    const Expr *E = D->getInit();
2016
    // Only dump the value of constexpr VarDecls for now.
2017
0
    if (E && !E->isValueDependent() && D->isConstexpr() &&
2018
0
        !D->getType()->isDependentType()) {
2019
0
      const APValue *Value = D->evaluateValue();
2020
0
      if (Value)
2021
0
        AddChild("value", [=] { Visit(*Value, E->getType()); });
2022
0
    }
2023
0
  }
2024
0
}
2025
2026
0
void TextNodeDumper::VisitBindingDecl(const BindingDecl *D) {
2027
0
  dumpName(D);
2028
0
  dumpType(D->getType());
2029
0
}
2030
2031
0
void TextNodeDumper::VisitCapturedDecl(const CapturedDecl *D) {
2032
0
  if (D->isNothrow())
2033
0
    OS << " nothrow";
2034
0
}
2035
2036
0
void TextNodeDumper::VisitImportDecl(const ImportDecl *D) {
2037
0
  OS << ' ' << D->getImportedModule()->getFullModuleName();
2038
2039
0
  for (Decl *InitD :
2040
0
       D->getASTContext().getModuleInitializers(D->getImportedModule()))
2041
0
    dumpDeclRef(InitD, "initializer");
2042
0
}
2043
2044
0
void TextNodeDumper::VisitPragmaCommentDecl(const PragmaCommentDecl *D) {
2045
0
  OS << ' ';
2046
0
  switch (D->getCommentKind()) {
2047
0
  case PCK_Unknown:
2048
0
    llvm_unreachable("unexpected pragma comment kind");
2049
0
  case PCK_Compiler:
2050
0
    OS << "compiler";
2051
0
    break;
2052
0
  case PCK_ExeStr:
2053
0
    OS << "exestr";
2054
0
    break;
2055
0
  case PCK_Lib:
2056
0
    OS << "lib";
2057
0
    break;
2058
0
  case PCK_Linker:
2059
0
    OS << "linker";
2060
0
    break;
2061
0
  case PCK_User:
2062
0
    OS << "user";
2063
0
    break;
2064
0
  }
2065
0
  StringRef Arg = D->getArg();
2066
0
  if (!Arg.empty())
2067
0
    OS << " \"" << Arg << "\"";
2068
0
}
2069
2070
void TextNodeDumper::VisitPragmaDetectMismatchDecl(
2071
0
    const PragmaDetectMismatchDecl *D) {
2072
0
  OS << " \"" << D->getName() << "\" \"" << D->getValue() << "\"";
2073
0
}
2074
2075
void TextNodeDumper::VisitOMPExecutableDirective(
2076
0
    const OMPExecutableDirective *D) {
2077
0
  if (D->isStandaloneDirective())
2078
0
    OS << " openmp_standalone_directive";
2079
0
}
2080
2081
void TextNodeDumper::VisitOMPDeclareReductionDecl(
2082
0
    const OMPDeclareReductionDecl *D) {
2083
0
  dumpName(D);
2084
0
  dumpType(D->getType());
2085
0
  OS << " combiner";
2086
0
  dumpPointer(D->getCombiner());
2087
0
  if (const auto *Initializer = D->getInitializer()) {
2088
0
    OS << " initializer";
2089
0
    dumpPointer(Initializer);
2090
0
    switch (D->getInitializerKind()) {
2091
0
    case OMPDeclareReductionInitKind::Direct:
2092
0
      OS << " omp_priv = ";
2093
0
      break;
2094
0
    case OMPDeclareReductionInitKind::Copy:
2095
0
      OS << " omp_priv ()";
2096
0
      break;
2097
0
    case OMPDeclareReductionInitKind::Call:
2098
0
      break;
2099
0
    }
2100
0
  }
2101
0
}
2102
2103
0
void TextNodeDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) {
2104
0
  for (const auto *C : D->clauselists()) {
2105
0
    AddChild([=] {
2106
0
      if (!C) {
2107
0
        ColorScope Color(OS, ShowColors, NullColor);
2108
0
        OS << "<<<NULL>>> OMPClause";
2109
0
        return;
2110
0
      }
2111
0
      {
2112
0
        ColorScope Color(OS, ShowColors, AttrColor);
2113
0
        StringRef ClauseName(
2114
0
            llvm::omp::getOpenMPClauseName(C->getClauseKind()));
2115
0
        OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
2116
0
           << ClauseName.drop_front() << "Clause";
2117
0
      }
2118
0
      dumpPointer(C);
2119
0
      dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
2120
0
    });
2121
0
  }
2122
0
}
2123
2124
0
void TextNodeDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
2125
0
  dumpName(D);
2126
0
  dumpType(D->getType());
2127
0
}
2128
2129
0
void TextNodeDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
2130
0
  dumpName(D);
2131
0
  if (D->isInline())
2132
0
    OS << " inline";
2133
0
  if (D->isNested())
2134
0
    OS << " nested";
2135
0
  if (!D->isOriginalNamespace())
2136
0
    dumpDeclRef(D->getOriginalNamespace(), "original");
2137
0
}
2138
2139
0
void TextNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
2140
0
  OS << ' ';
2141
0
  dumpBareDeclRef(D->getNominatedNamespace());
2142
0
}
2143
2144
0
void TextNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
2145
0
  dumpName(D);
2146
0
  dumpDeclRef(D->getAliasedNamespace());
2147
0
}
2148
2149
0
void TextNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
2150
0
  dumpName(D);
2151
0
  dumpType(D->getUnderlyingType());
2152
0
}
2153
2154
void TextNodeDumper::VisitTypeAliasTemplateDecl(
2155
0
    const TypeAliasTemplateDecl *D) {
2156
0
  dumpName(D);
2157
0
}
2158
2159
0
void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
2160
0
  VisitRecordDecl(D);
2161
0
  if (const auto *Instance = D->getInstantiatedFromMemberClass()) {
2162
0
    OS << " instantiated_from";
2163
0
    dumpPointer(Instance);
2164
0
  }
2165
0
  if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D))
2166
0
    dumpTemplateSpecializationKind(CTSD->getSpecializationKind());
2167
2168
0
  dumpNestedNameSpecifier(D->getQualifier());
2169
2170
0
  if (!D->isCompleteDefinition())
2171
0
    return;
2172
2173
0
  AddChild([=] {
2174
0
    {
2175
0
      ColorScope Color(OS, ShowColors, DeclKindNameColor);
2176
0
      OS << "DefinitionData";
2177
0
    }
2178
0
#define FLAG(fn, name)                                                         \
2179
0
  if (D->fn())                                                                 \
2180
0
    OS << " " #name;
2181
0
    FLAG(isParsingBaseSpecifiers, parsing_base_specifiers);
2182
2183
0
    FLAG(isGenericLambda, generic);
2184
0
    FLAG(isLambda, lambda);
2185
2186
0
    FLAG(isAnonymousStructOrUnion, is_anonymous);
2187
0
    FLAG(canPassInRegisters, pass_in_registers);
2188
0
    FLAG(isEmpty, empty);
2189
0
    FLAG(isAggregate, aggregate);
2190
0
    FLAG(isStandardLayout, standard_layout);
2191
0
    FLAG(isTriviallyCopyable, trivially_copyable);
2192
0
    FLAG(isPOD, pod);
2193
0
    FLAG(isTrivial, trivial);
2194
0
    FLAG(isPolymorphic, polymorphic);
2195
0
    FLAG(isAbstract, abstract);
2196
0
    FLAG(isLiteral, literal);
2197
2198
0
    FLAG(hasUserDeclaredConstructor, has_user_declared_ctor);
2199
0
    FLAG(hasConstexprNonCopyMoveConstructor, has_constexpr_non_copy_move_ctor);
2200
0
    FLAG(hasMutableFields, has_mutable_fields);
2201
0
    FLAG(hasVariantMembers, has_variant_members);
2202
0
    FLAG(allowConstDefaultInit, can_const_default_init);
2203
2204
0
    AddChild([=] {
2205
0
      {
2206
0
        ColorScope Color(OS, ShowColors, DeclKindNameColor);
2207
0
        OS << "DefaultConstructor";
2208
0
      }
2209
0
      FLAG(hasDefaultConstructor, exists);
2210
0
      FLAG(hasTrivialDefaultConstructor, trivial);
2211
0
      FLAG(hasNonTrivialDefaultConstructor, non_trivial);
2212
0
      FLAG(hasUserProvidedDefaultConstructor, user_provided);
2213
0
      FLAG(hasConstexprDefaultConstructor, constexpr);
2214
0
      FLAG(needsImplicitDefaultConstructor, needs_implicit);
2215
0
      FLAG(defaultedDefaultConstructorIsConstexpr, defaulted_is_constexpr);
2216
0
    });
2217
2218
0
    AddChild([=] {
2219
0
      {
2220
0
        ColorScope Color(OS, ShowColors, DeclKindNameColor);
2221
0
        OS << "CopyConstructor";
2222
0
      }
2223
0
      FLAG(hasSimpleCopyConstructor, simple);
2224
0
      FLAG(hasTrivialCopyConstructor, trivial);
2225
0
      FLAG(hasNonTrivialCopyConstructor, non_trivial);
2226
0
      FLAG(hasUserDeclaredCopyConstructor, user_declared);
2227
0
      FLAG(hasCopyConstructorWithConstParam, has_const_param);
2228
0
      FLAG(needsImplicitCopyConstructor, needs_implicit);
2229
0
      FLAG(needsOverloadResolutionForCopyConstructor,
2230
0
           needs_overload_resolution);
2231
0
      if (!D->needsOverloadResolutionForCopyConstructor())
2232
0
        FLAG(defaultedCopyConstructorIsDeleted, defaulted_is_deleted);
2233
0
      FLAG(implicitCopyConstructorHasConstParam, implicit_has_const_param);
2234
0
    });
2235
2236
0
    AddChild([=] {
2237
0
      {
2238
0
        ColorScope Color(OS, ShowColors, DeclKindNameColor);
2239
0
        OS << "MoveConstructor";
2240
0
      }
2241
0
      FLAG(hasMoveConstructor, exists);
2242
0
      FLAG(hasSimpleMoveConstructor, simple);
2243
0
      FLAG(hasTrivialMoveConstructor, trivial);
2244
0
      FLAG(hasNonTrivialMoveConstructor, non_trivial);
2245
0
      FLAG(hasUserDeclaredMoveConstructor, user_declared);
2246
0
      FLAG(needsImplicitMoveConstructor, needs_implicit);
2247
0
      FLAG(needsOverloadResolutionForMoveConstructor,
2248
0
           needs_overload_resolution);
2249
0
      if (!D->needsOverloadResolutionForMoveConstructor())
2250
0
        FLAG(defaultedMoveConstructorIsDeleted, defaulted_is_deleted);
2251
0
    });
2252
2253
0
    AddChild([=] {
2254
0
      {
2255
0
        ColorScope Color(OS, ShowColors, DeclKindNameColor);
2256
0
        OS << "CopyAssignment";
2257
0
      }
2258
0
      FLAG(hasSimpleCopyAssignment, simple);
2259
0
      FLAG(hasTrivialCopyAssignment, trivial);
2260
0
      FLAG(hasNonTrivialCopyAssignment, non_trivial);
2261
0
      FLAG(hasCopyAssignmentWithConstParam, has_const_param);
2262
0
      FLAG(hasUserDeclaredCopyAssignment, user_declared);
2263
0
      FLAG(needsImplicitCopyAssignment, needs_implicit);
2264
0
      FLAG(needsOverloadResolutionForCopyAssignment, needs_overload_resolution);
2265
0
      FLAG(implicitCopyAssignmentHasConstParam, implicit_has_const_param);
2266
0
    });
2267
2268
0
    AddChild([=] {
2269
0
      {
2270
0
        ColorScope Color(OS, ShowColors, DeclKindNameColor);
2271
0
        OS << "MoveAssignment";
2272
0
      }
2273
0
      FLAG(hasMoveAssignment, exists);
2274
0
      FLAG(hasSimpleMoveAssignment, simple);
2275
0
      FLAG(hasTrivialMoveAssignment, trivial);
2276
0
      FLAG(hasNonTrivialMoveAssignment, non_trivial);
2277
0
      FLAG(hasUserDeclaredMoveAssignment, user_declared);
2278
0
      FLAG(needsImplicitMoveAssignment, needs_implicit);
2279
0
      FLAG(needsOverloadResolutionForMoveAssignment, needs_overload_resolution);
2280
0
    });
2281
2282
0
    AddChild([=] {
2283
0
      {
2284
0
        ColorScope Color(OS, ShowColors, DeclKindNameColor);
2285
0
        OS << "Destructor";
2286
0
      }
2287
0
      FLAG(hasSimpleDestructor, simple);
2288
0
      FLAG(hasIrrelevantDestructor, irrelevant);
2289
0
      FLAG(hasTrivialDestructor, trivial);
2290
0
      FLAG(hasNonTrivialDestructor, non_trivial);
2291
0
      FLAG(hasUserDeclaredDestructor, user_declared);
2292
0
      FLAG(hasConstexprDestructor, constexpr);
2293
0
      FLAG(needsImplicitDestructor, needs_implicit);
2294
0
      FLAG(needsOverloadResolutionForDestructor, needs_overload_resolution);
2295
0
      if (!D->needsOverloadResolutionForDestructor())
2296
0
        FLAG(defaultedDestructorIsDeleted, defaulted_is_deleted);
2297
0
    });
2298
0
  });
2299
2300
0
  for (const auto &I : D->bases()) {
2301
0
    AddChild([=] {
2302
0
      if (I.isVirtual())
2303
0
        OS << "virtual ";
2304
0
      dumpAccessSpecifier(I.getAccessSpecifier());
2305
0
      dumpType(I.getType());
2306
0
      if (I.isPackExpansion())
2307
0
        OS << "...";
2308
0
    });
2309
0
  }
2310
0
}
2311
2312
0
void TextNodeDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
2313
0
  dumpName(D);
2314
0
}
2315
2316
0
void TextNodeDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
2317
0
  dumpName(D);
2318
0
}
2319
2320
0
void TextNodeDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
2321
0
  dumpName(D);
2322
0
}
2323
2324
0
void TextNodeDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
2325
0
  dumpName(D);
2326
0
}
2327
2328
0
void TextNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
2329
0
  if (const auto *TC = D->getTypeConstraint()) {
2330
0
    OS << " ";
2331
0
    dumpBareDeclRef(TC->getNamedConcept());
2332
0
    if (TC->getNamedConcept() != TC->getFoundDecl()) {
2333
0
      OS << " (";
2334
0
      dumpBareDeclRef(TC->getFoundDecl());
2335
0
      OS << ")";
2336
0
    }
2337
0
  } else if (D->wasDeclaredWithTypename())
2338
0
    OS << " typename";
2339
0
  else
2340
0
    OS << " class";
2341
0
  OS << " depth " << D->getDepth() << " index " << D->getIndex();
2342
0
  if (D->isParameterPack())
2343
0
    OS << " ...";
2344
0
  dumpName(D);
2345
0
}
2346
2347
void TextNodeDumper::VisitNonTypeTemplateParmDecl(
2348
0
    const NonTypeTemplateParmDecl *D) {
2349
0
  dumpType(D->getType());
2350
0
  OS << " depth " << D->getDepth() << " index " << D->getIndex();
2351
0
  if (D->isParameterPack())
2352
0
    OS << " ...";
2353
0
  dumpName(D);
2354
0
}
2355
2356
void TextNodeDumper::VisitTemplateTemplateParmDecl(
2357
0
    const TemplateTemplateParmDecl *D) {
2358
0
  OS << " depth " << D->getDepth() << " index " << D->getIndex();
2359
0
  if (D->isParameterPack())
2360
0
    OS << " ...";
2361
0
  dumpName(D);
2362
0
}
2363
2364
0
void TextNodeDumper::VisitUsingDecl(const UsingDecl *D) {
2365
0
  OS << ' ';
2366
0
  if (D->getQualifier())
2367
0
    D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2368
0
  OS << D->getDeclName();
2369
0
  dumpNestedNameSpecifier(D->getQualifier());
2370
0
}
2371
2372
0
void TextNodeDumper::VisitUsingEnumDecl(const UsingEnumDecl *D) {
2373
0
  OS << ' ';
2374
0
  dumpBareDeclRef(D->getEnumDecl());
2375
0
}
2376
2377
void TextNodeDumper::VisitUnresolvedUsingTypenameDecl(
2378
0
    const UnresolvedUsingTypenameDecl *D) {
2379
0
  OS << ' ';
2380
0
  if (D->getQualifier())
2381
0
    D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2382
0
  OS << D->getDeclName();
2383
0
}
2384
2385
void TextNodeDumper::VisitUnresolvedUsingValueDecl(
2386
0
    const UnresolvedUsingValueDecl *D) {
2387
0
  OS << ' ';
2388
0
  if (D->getQualifier())
2389
0
    D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2390
0
  OS << D->getDeclName();
2391
0
  dumpType(D->getType());
2392
0
}
2393
2394
0
void TextNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
2395
0
  OS << ' ';
2396
0
  dumpBareDeclRef(D->getTargetDecl());
2397
0
}
2398
2399
void TextNodeDumper::VisitConstructorUsingShadowDecl(
2400
0
    const ConstructorUsingShadowDecl *D) {
2401
0
  if (D->constructsVirtualBase())
2402
0
    OS << " virtual";
2403
2404
0
  AddChild([=] {
2405
0
    OS << "target ";
2406
0
    dumpBareDeclRef(D->getTargetDecl());
2407
0
  });
2408
2409
0
  AddChild([=] {
2410
0
    OS << "nominated ";
2411
0
    dumpBareDeclRef(D->getNominatedBaseClass());
2412
0
    OS << ' ';
2413
0
    dumpBareDeclRef(D->getNominatedBaseClassShadowDecl());
2414
0
  });
2415
2416
0
  AddChild([=] {
2417
0
    OS << "constructed ";
2418
0
    dumpBareDeclRef(D->getConstructedBaseClass());
2419
0
    OS << ' ';
2420
0
    dumpBareDeclRef(D->getConstructedBaseClassShadowDecl());
2421
0
  });
2422
0
}
2423
2424
0
void TextNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
2425
0
  switch (D->getLanguage()) {
2426
0
  case LinkageSpecLanguageIDs::C:
2427
0
    OS << " C";
2428
0
    break;
2429
0
  case LinkageSpecLanguageIDs::CXX:
2430
0
    OS << " C++";
2431
0
    break;
2432
0
  }
2433
0
}
2434
2435
0
void TextNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
2436
0
  OS << ' ';
2437
0
  dumpAccessSpecifier(D->getAccess());
2438
0
}
2439
2440
0
void TextNodeDumper::VisitFriendDecl(const FriendDecl *D) {
2441
0
  if (TypeSourceInfo *T = D->getFriendType())
2442
0
    dumpType(T->getType());
2443
0
}
2444
2445
0
void TextNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
2446
0
  dumpName(D);
2447
0
  dumpType(D->getType());
2448
0
  if (D->getSynthesize())
2449
0
    OS << " synthesize";
2450
2451
0
  switch (D->getAccessControl()) {
2452
0
  case ObjCIvarDecl::None:
2453
0
    OS << " none";
2454
0
    break;
2455
0
  case ObjCIvarDecl::Private:
2456
0
    OS << " private";
2457
0
    break;
2458
0
  case ObjCIvarDecl::Protected:
2459
0
    OS << " protected";
2460
0
    break;
2461
0
  case ObjCIvarDecl::Public:
2462
0
    OS << " public";
2463
0
    break;
2464
0
  case ObjCIvarDecl::Package:
2465
0
    OS << " package";
2466
0
    break;
2467
0
  }
2468
0
}
2469
2470
0
void TextNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
2471
0
  if (D->isInstanceMethod())
2472
0
    OS << " -";
2473
0
  else
2474
0
    OS << " +";
2475
0
  dumpName(D);
2476
0
  dumpType(D->getReturnType());
2477
2478
0
  if (D->isVariadic())
2479
0
    OS << " variadic";
2480
0
}
2481
2482
0
void TextNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
2483
0
  dumpName(D);
2484
0
  switch (D->getVariance()) {
2485
0
  case ObjCTypeParamVariance::Invariant:
2486
0
    break;
2487
2488
0
  case ObjCTypeParamVariance::Covariant:
2489
0
    OS << " covariant";
2490
0
    break;
2491
2492
0
  case ObjCTypeParamVariance::Contravariant:
2493
0
    OS << " contravariant";
2494
0
    break;
2495
0
  }
2496
2497
0
  if (D->hasExplicitBound())
2498
0
    OS << " bounded";
2499
0
  dumpType(D->getUnderlyingType());
2500
0
}
2501
2502
0
void TextNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
2503
0
  dumpName(D);
2504
0
  dumpDeclRef(D->getClassInterface());
2505
0
  dumpDeclRef(D->getImplementation());
2506
0
  for (const auto *P : D->protocols())
2507
0
    dumpDeclRef(P);
2508
0
}
2509
2510
0
void TextNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
2511
0
  dumpName(D);
2512
0
  dumpDeclRef(D->getClassInterface());
2513
0
  dumpDeclRef(D->getCategoryDecl());
2514
0
}
2515
2516
0
void TextNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
2517
0
  dumpName(D);
2518
2519
0
  for (const auto *Child : D->protocols())
2520
0
    dumpDeclRef(Child);
2521
0
}
2522
2523
0
void TextNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
2524
0
  dumpName(D);
2525
0
  dumpDeclRef(D->getSuperClass(), "super");
2526
2527
0
  dumpDeclRef(D->getImplementation());
2528
0
  for (const auto *Child : D->protocols())
2529
0
    dumpDeclRef(Child);
2530
0
}
2531
2532
void TextNodeDumper::VisitObjCImplementationDecl(
2533
0
    const ObjCImplementationDecl *D) {
2534
0
  dumpName(D);
2535
0
  dumpDeclRef(D->getSuperClass(), "super");
2536
0
  dumpDeclRef(D->getClassInterface());
2537
0
}
2538
2539
void TextNodeDumper::VisitObjCCompatibleAliasDecl(
2540
0
    const ObjCCompatibleAliasDecl *D) {
2541
0
  dumpName(D);
2542
0
  dumpDeclRef(D->getClassInterface());
2543
0
}
2544
2545
0
void TextNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
2546
0
  dumpName(D);
2547
0
  dumpType(D->getType());
2548
2549
0
  if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
2550
0
    OS << " required";
2551
0
  else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
2552
0
    OS << " optional";
2553
2554
0
  ObjCPropertyAttribute::Kind Attrs = D->getPropertyAttributes();
2555
0
  if (Attrs != ObjCPropertyAttribute::kind_noattr) {
2556
0
    if (Attrs & ObjCPropertyAttribute::kind_readonly)
2557
0
      OS << " readonly";
2558
0
    if (Attrs & ObjCPropertyAttribute::kind_assign)
2559
0
      OS << " assign";
2560
0
    if (Attrs & ObjCPropertyAttribute::kind_readwrite)
2561
0
      OS << " readwrite";
2562
0
    if (Attrs & ObjCPropertyAttribute::kind_retain)
2563
0
      OS << " retain";
2564
0
    if (Attrs & ObjCPropertyAttribute::kind_copy)
2565
0
      OS << " copy";
2566
0
    if (Attrs & ObjCPropertyAttribute::kind_nonatomic)
2567
0
      OS << " nonatomic";
2568
0
    if (Attrs & ObjCPropertyAttribute::kind_atomic)
2569
0
      OS << " atomic";
2570
0
    if (Attrs & ObjCPropertyAttribute::kind_weak)
2571
0
      OS << " weak";
2572
0
    if (Attrs & ObjCPropertyAttribute::kind_strong)
2573
0
      OS << " strong";
2574
0
    if (Attrs & ObjCPropertyAttribute::kind_unsafe_unretained)
2575
0
      OS << " unsafe_unretained";
2576
0
    if (Attrs & ObjCPropertyAttribute::kind_class)
2577
0
      OS << " class";
2578
0
    if (Attrs & ObjCPropertyAttribute::kind_direct)
2579
0
      OS << " direct";
2580
0
    if (Attrs & ObjCPropertyAttribute::kind_getter)
2581
0
      dumpDeclRef(D->getGetterMethodDecl(), "getter");
2582
0
    if (Attrs & ObjCPropertyAttribute::kind_setter)
2583
0
      dumpDeclRef(D->getSetterMethodDecl(), "setter");
2584
0
  }
2585
0
}
2586
2587
0
void TextNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
2588
0
  dumpName(D->getPropertyDecl());
2589
0
  if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
2590
0
    OS << " synthesize";
2591
0
  else
2592
0
    OS << " dynamic";
2593
0
  dumpDeclRef(D->getPropertyDecl());
2594
0
  dumpDeclRef(D->getPropertyIvarDecl());
2595
0
}
2596
2597
0
void TextNodeDumper::VisitBlockDecl(const BlockDecl *D) {
2598
0
  if (D->isVariadic())
2599
0
    OS << " variadic";
2600
2601
0
  if (D->capturesCXXThis())
2602
0
    OS << " captures_this";
2603
0
}
2604
2605
0
void TextNodeDumper::VisitConceptDecl(const ConceptDecl *D) {
2606
0
  dumpName(D);
2607
0
}
2608
2609
0
void TextNodeDumper::VisitCompoundStmt(const CompoundStmt *S) {
2610
0
  VisitStmt(S);
2611
0
  if (S->hasStoredFPFeatures())
2612
0
    printFPOptions(S->getStoredFPFeatures());
2613
0
}
2614
2615
0
void TextNodeDumper::VisitHLSLBufferDecl(const HLSLBufferDecl *D) {
2616
0
  if (D->isCBuffer())
2617
0
    OS << " cbuffer";
2618
0
  else
2619
0
    OS << " tbuffer";
2620
0
  dumpName(D);
2621
0
}