Coverage Report

Created: 2022-05-14 11:35

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