Coverage Report

Created: 2022-01-18 06:27

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