Coverage Report

Created: 2022-07-16 07:03

/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.40k
static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {}
32
33
template <typename T>
34
2.21k
static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) {
35
2.21k
  const T *First = D->getFirstDecl();
36
2.21k
  if (First != D)
37
0
    OS << " first " << First;
38
2.21k
}
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
2.01k
static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) {
35
2.01k
  const T *First = D->getFirstDecl();
36
2.01k
  if (First != D)
37
0
    OS << " first " << First;
38
2.01k
}
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
22.3k
static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) {
42
22.3k
  const T *Prev = D->getPreviousDecl();
43
22.3k
  if (Prev)
44
287
    OS << " prev " << Prev;
45
22.3k
}
TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::NamespaceDecl>(llvm::raw_ostream&, clang::Redeclarable<clang::NamespaceDecl> const*)
Line
Count
Source
41
202
static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) {
42
202
  const T *Prev = D->getPreviousDecl();
43
202
  if (Prev)
44
4
    OS << " prev " << Prev;
45
202
}
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
620
static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) {
42
620
  const T *Prev = D->getPreviousDecl();
43
620
  if (Prev)
44
32
    OS << " prev " << Prev;
45
620
}
TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::TagDecl>(llvm::raw_ostream&, clang::Redeclarable<clang::TagDecl> const*)
Line
Count
Source
41
3.21k
static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) {
42
3.21k
  const T *Prev = D->getPreviousDecl();
43
3.21k
  if (Prev)
44
48
    OS << " prev " << Prev;
45
3.21k
}
TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::TypedefNameDecl>(llvm::raw_ostream&, clang::Redeclarable<clang::TypedefNameDecl> const*)
Line
Count
Source
41
3.17k
static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) {
42
3.17k
  const T *Prev = D->getPreviousDecl();
43
3.17k
  if (Prev)
44
5
    OS << " prev " << Prev;
45
3.17k
}
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.96k
static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) {
42
4.96k
  const T *Prev = D->getPreviousDecl();
43
4.96k
  if (Prev)
44
181
    OS << " prev " << Prev;
45
4.96k
}
TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::VarDecl>(llvm::raw_ostream&, clang::Redeclarable<clang::VarDecl> const*)
Line
Count
Source
41
9.43k
static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) {
42
9.43k
  const T *Prev = D->getPreviousDecl();
43
9.43k
  if (Prev)
44
16
    OS << " prev " << Prev;
45
9.43k
}
TextNodeDumper.cpp:void dumpPreviousDeclImpl<clang::TranslationUnitDecl>(llvm::raw_ostream&, clang::Redeclarable<clang::TranslationUnitDecl> const*)
Line
Count
Source
41
487
static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) {
42
487
  const T *Prev = D->getPreviousDecl();
43
487
  if (Prev)
44
0
    OS << " prev " << Prev;
45
487
}
46
47
/// Dump the previous declaration in the redeclaration chain for a declaration,
48
/// if any.
49
26.9k
static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) {
50
26.9k
  switch (D->getKind()) {
51
0
#define DECL(DERIVED, BASE)                                                    \
52
26.9k
  case Decl::DERIVED:                                                          \
53
26.9k
    return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D));
54
0
#define ABSTRACT_DECL(DECL)
55
26.9k
#include 
"clang/AST/DeclNodes.inc"0
56
26.9k
  }
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.71k
      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.44k
void TextNodeDumper::Visit(const Attr *A) {
90
2.44k
  {
91
2.44k
    ColorScope Color(OS, ShowColors, AttrColor);
92
93
2.44k
    switch (A->getKind()) {
94
0
#define ATTR(X)                                                                \
95
2.44k
  case attr::X:                                                                \
96
2.44k
    OS << #X;                                                                  \
97
2.44k
    break;
98
2.44k
#include 
"clang/Basic/AttrList.inc"0
99
2.44k
    }
100
2.44k
    OS << "Attr";
101
2.44k
  }
102
0
  dumpPointer(A);
103
2.44k
  dumpSourceRange(A->getRange());
104
2.44k
  if (A->isInherited())
105
108
    OS << " Inherited";
106
2.44k
  if (A->isImplicit())
107
1.70k
    OS << " Implicit";
108
109
2.44k
  ConstAttrVisitor<TextNodeDumper>::Visit(A);
110
2.44k
}
111
112
void TextNodeDumper::Visit(const TemplateArgument &TA, SourceRange R,
113
855
                           const Decl *From, StringRef Label) {
114
855
  OS << "TemplateArgument";
115
855
  if (R.isValid())
116
26
    dumpSourceRange(R);
117
118
855
  if (From)
119
12
    dumpDeclRef(From, Label);
120
121
855
  ConstTemplateArgumentVisitor<TextNodeDumper>::Visit(TA);
122
855
}
123
124
35.8k
void TextNodeDumper::Visit(const Stmt *Node) {
125
35.8k
  if (!Node) {
126
1.03k
    ColorScope Color(OS, ShowColors, NullColor);
127
1.03k
    OS << "<<<NULL>>>";
128
1.03k
    return;
129
1.03k
  }
130
34.8k
  {
131
34.8k
    ColorScope Color(OS, ShowColors, StmtColor);
132
34.8k
    OS << Node->getStmtClassName();
133
34.8k
  }
134
34.8k
  dumpPointer(Node);
135
34.8k
  dumpSourceRange(Node->getSourceRange());
136
137
34.8k
  if (const auto *E = dyn_cast<Expr>(Node)) {
138
26.2k
    dumpType(E->getType());
139
140
26.2k
    if (E->containsErrors()) {
141
182
      ColorScope Color(OS, ShowColors, ErrorsColor);
142
182
      OS << " contains-errors";
143
182
    }
144
145
26.2k
    {
146
26.2k
      ColorScope Color(OS, ShowColors, ValueKindColor);
147
26.2k
      switch (E->getValueKind()) {
148
17.3k
      case VK_PRValue:
149
17.3k
        break;
150
8.60k
      case VK_LValue:
151
8.60k
        OS << " lvalue";
152
8.60k
        break;
153
278
      case VK_XValue:
154
278
        OS << " xvalue";
155
278
        break;
156
26.2k
      }
157
26.2k
    }
158
159
26.2k
    {
160
26.2k
      ColorScope Color(OS, ShowColors, ObjectKindColor);
161
26.2k
      switch (E->getObjectKind()) {
162
26.2k
      case OK_Ordinary:
163
26.2k
        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
9
      case OK_VectorComponent:
174
9
        OS << " vectorcomponent";
175
9
        break;
176
0
      case OK_MatrixComponent:
177
0
        OS << " matrixcomponent";
178
0
        break;
179
26.2k
      }
180
26.2k
    }
181
26.2k
  }
182
183
34.8k
  ConstStmtVisitor<TextNodeDumper>::Visit(Node);
184
34.8k
}
185
186
5.45k
void TextNodeDumper::Visit(const Type *T) {
187
5.45k
  if (!T) {
188
0
    ColorScope Color(OS, ShowColors, NullColor);
189
0
    OS << "<<<NULL>>>";
190
0
    return;
191
0
  }
192
5.45k
  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
5.45k
  {
202
5.45k
    ColorScope Color(OS, ShowColors, TypeColor);
203
5.45k
    OS << T->getTypeClassName() << "Type";
204
5.45k
  }
205
5.45k
  dumpPointer(T);
206
5.45k
  OS << " ";
207
5.45k
  dumpBareType(QualType(T, 0), false);
208
209
5.45k
  QualType SingleStepDesugar =
210
5.45k
      T->getLocallyUnqualifiedSingleStepDesugaredType();
211
5.45k
  if (SingleStepDesugar != QualType(T, 0))
212
277
    OS << " sugar";
213
214
5.45k
  if (T->containsErrors()) {
215
1
    ColorScope Color(OS, ShowColors, ErrorsColor);
216
1
    OS << " contains-errors";
217
1
  }
218
219
5.45k
  if (T->isDependentType())
220
406
    OS << " dependent";
221
5.05k
  else if (T->isInstantiationDependentType())
222
0
    OS << " instantiation_dependent";
223
224
5.45k
  if (T->isVariablyModifiedType())
225
0
    OS << " variably_modified";
226
5.45k
  if (T->containsUnexpandedParameterPack())
227
98
    OS << " contains_unexpanded_pack";
228
5.45k
  if (T->isFromAST())
229
258
    OS << " imported";
230
231
5.45k
  TypeVisitor<TextNodeDumper>::Visit(T);
232
5.45k
}
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.9k
void TextNodeDumper::Visit(const Decl *D) {
243
26.9k
  if (!D) {
244
3
    ColorScope Color(OS, ShowColors, NullColor);
245
3
    OS << "<<<NULL>>>";
246
3
    return;
247
3
  }
248
249
26.9k
  {
250
26.9k
    ColorScope Color(OS, ShowColors, DeclKindNameColor);
251
26.9k
    OS << D->getDeclKindName() << "Decl";
252
26.9k
  }
253
26.9k
  dumpPointer(D);
254
26.9k
  if (D->getLexicalDeclContext() != D->getDeclContext())
255
86
    OS << " parent " << cast<Decl>(D->getDeclContext());
256
26.9k
  dumpPreviousDecl(OS, D);
257
26.9k
  dumpSourceRange(D->getSourceRange());
258
26.9k
  OS << ' ';
259
26.9k
  dumpLocation(D->getLocation());
260
26.9k
  if (D->isFromASTFile())
261
3.94k
    OS << " imported";
262
26.9k
  if (Module *M = D->getOwningModule())
263
175
    OS << " in " << M->getFullModuleName();
264
26.9k
  if (auto *ND = dyn_cast<NamedDecl>(D))
265
25.2k
    for (Module *M : D->getASTContext().getModulesWithMergedDefinition(
266
25.2k
             const_cast<NamedDecl *>(ND)))
267
3
      AddChild([=] { OS << "also in " << M->getFullModuleName(); });
268
26.9k
  if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
269
25.2k
    if (!ND->isUnconditionallyVisible())
270
66
      OS << " hidden";
271
26.9k
  if (D->isImplicit())
272
10.3k
    OS << " implicit";
273
274
26.9k
  if (D->isUsed())
275
4.49k
    OS << " used";
276
22.4k
  else if (D->isThisDeclarationReferenced())
277
1.72k
    OS << " referenced";
278
279
26.9k
  if (D->isInvalidDecl())
280
55
    OS << " invalid";
281
26.9k
  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
282
4.96k
    if (FD->isConstexprSpecified())
283
802
      OS << " constexpr";
284
4.96k
    if (FD->isConsteval())
285
2
      OS << " consteval";
286
4.96k
    if (FD->isMultiVersion())
287
8
      OS << " multiversion";
288
4.96k
  }
289
290
26.9k
  if (!isa<FunctionDecl>(*D)) {
291
21.9k
    const auto *MD = dyn_cast<ObjCMethodDecl>(D);
292
21.9k
    if (!MD || 
!MD->isThisDeclarationADefinition()178
) {
293
21.9k
      const auto *DC = dyn_cast<DeclContext>(D);
294
21.9k
      if (DC && 
DC->hasExternalLexicalStorage()5.19k
) {
295
740
        ColorScope Color(OS, ShowColors, UndeserializedColor);
296
740
        OS << " <undeserialized declarations>";
297
740
      }
298
21.9k
    }
299
21.9k
  }
300
301
26.9k
  ConstDeclVisitor<TextNodeDumper>::Visit(D);
302
26.9k
}
303
304
191
void TextNodeDumper::Visit(const CXXCtorInitializer *Init) {
305
191
  OS << "CXXCtorInitializer";
306
191
  if (Init->isAnyMemberInitializer()) {
307
143
    OS << ' ';
308
143
    dumpBareDeclRef(Init->getAnyMember());
309
143
  } 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
191
}
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
420
void TextNodeDumper::Visit(const OMPClause *C) {
331
420
  if (!C) {
332
0
    ColorScope Color(OS, ShowColors, NullColor);
333
0
    OS << "<<<NULL>>> OMPClause";
334
0
    return;
335
0
  }
336
420
  {
337
420
    ColorScope Color(OS, ShowColors, AttrColor);
338
420
    StringRef ClauseName(llvm::omp::getOpenMPClauseName(C->getClauseKind()));
339
420
    OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
340
420
       << ClauseName.drop_front() << "Clause";
341
420
  }
342
420
  dumpPointer(C);
343
420
  dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
344
420
  if (C->isImplicit())
345
90
    OS << " <implicit>";
346
420
}
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
81.4k
void TextNodeDumper::dumpPointer(const void *Ptr) {
614
81.4k
  ColorScope Color(OS, ShowColors, AddressColor);
615
81.4k
  OS << ' ' << Ptr;
616
81.4k
}
617
618
122k
void TextNodeDumper::dumpLocation(SourceLocation Loc) {
619
122k
  if (!SM)
620
0
    return;
621
622
122k
  ColorScope Color(OS, ShowColors, LocationColor);
623
122k
  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
122k
  PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
628
629
122k
  if (PLoc.isInvalid()) {
630
13.3k
    OS << "<invalid sloc>";
631
13.3k
    return;
632
13.3k
  }
633
634
108k
  if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
635
1.75k
    OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':'
636
1.75k
       << PLoc.getColumn();
637
1.75k
    LastLocFilename = PLoc.getFilename();
638
1.75k
    LastLocLine = PLoc.getLine();
639
107k
  } else if (PLoc.getLine() != LastLocLine) {
640
26.2k
    OS << "line" << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
641
26.2k
    LastLocLine = PLoc.getLine();
642
80.7k
  } else {
643
80.7k
    OS << "col" << ':' << PLoc.getColumn();
644
80.7k
  }
645
108k
}
646
647
65.2k
void TextNodeDumper::dumpSourceRange(SourceRange R) {
648
  // Can't translate locations if a SourceManager isn't available.
649
65.2k
  if (!SM)
650
436
    return;
651
652
64.8k
  OS << " <";
653
64.8k
  dumpLocation(R.getBegin());
654
64.8k
  if (R.getBegin() != R.getEnd()) {
655
30.3k
    OS << ", ";
656
30.3k
    dumpLocation(R.getEnd());
657
30.3k
  }
658
64.8k
  OS << ">";
659
660
  // <t2.c:123:421[blah], t2.c:412:321>
661
64.8k
}
662
663
61.5k
void TextNodeDumper::dumpBareType(QualType T, bool Desugar) {
664
61.5k
  ColorScope Color(OS, ShowColors, TypeColor);
665
666
61.5k
  SplitQualType T_split = T.split();
667
61.5k
  OS << "'" << QualType::getAsString(T_split, PrintPolicy) << "'";
668
669
61.5k
  if (Desugar && 
!T.isNull()56.0k
) {
670
    // If the type is sugared, also dump a (shallow) desugared type.
671
56.0k
    SplitQualType D_split = T.getSplitDesugaredType();
672
56.0k
    if (T_split != D_split)
673
4.07k
      OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'";
674
56.0k
  }
675
61.5k
}
676
677
55.8k
void TextNodeDumper::dumpType(QualType T) {
678
55.8k
  OS << ' ';
679
55.8k
  dumpBareType(T);
680
55.8k
}
681
682
9.91k
void TextNodeDumper::dumpBareDeclRef(const Decl *D) {
683
9.91k
  if (!D) {
684
34
    ColorScope Color(OS, ShowColors, NullColor);
685
34
    OS << "<<<NULL>>>";
686
34
    return;
687
34
  }
688
689
9.88k
  {
690
9.88k
    ColorScope Color(OS, ShowColors, DeclKindNameColor);
691
9.88k
    OS << D->getDeclKindName();
692
9.88k
  }
693
9.88k
  dumpPointer(D);
694
695
9.88k
  if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
696
9.87k
    ColorScope Color(OS, ShowColors, DeclNameColor);
697
9.87k
    OS << " '" << ND->getDeclName() << '\'';
698
9.87k
  }
699
700
9.88k
  if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
701
8.08k
    dumpType(VD->getType());
702
9.88k
}
703
704
25.1k
void TextNodeDumper::dumpName(const NamedDecl *ND) {
705
25.1k
  if (ND->getDeclName()) {
706
22.2k
    ColorScope Color(OS, ShowColors, DeclNameColor);
707
22.2k
    OS << ' ' << ND->getDeclName();
708
22.2k
  }
709
25.1k
}
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.83k
void TextNodeDumper::dumpDeclRef(const Decl *D, StringRef Label) {
736
1.83k
  if (!D)
737
242
    return;
738
739
1.59k
  AddChild([=] {
740
1.59k
    if (!Label.empty())
741
66
      OS << Label << ' ';
742
1.59k
    dumpBareDeclRef(D);
743
1.59k
  });
744
1.59k
}
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
318
void TextNodeDumper::printFPOptions(FPOptionsOverride FPO) {
757
318
#define OPTION(NAME, TYPE, WIDTH, PREVIOUS)                                    \
758
3.81k
  if (FPO.has##NAME##Override())                                               \
759
3.81k
    
OS << " " #NAME "=" << FPO.get##NAME##Override()318
;
760
318
#include "clang/Basic/FPOptions.def"
761
318
}
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
565
void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) {
884
565
  OS << " type";
885
565
  dumpType(TA.getAsType());
886
565
}
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
142
void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) {
899
142
  OS << " integral " << TA.getAsIntegral();
900
142
}
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
71
void TextNodeDumper::VisitExpressionTemplateArgument(const TemplateArgument &) {
919
71
  OS << " expr";
920
71
}
921
922
54
void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &) {
923
54
  OS << " pack";
924
54
}
925
926
5.43k
static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
927
5.43k
  if (Node->path_empty())
928
5.34k
    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
50
void TextNodeDumper::VisitIfStmt(const IfStmt *Node) {
952
50
  if (Node->hasInitStorage())
953
3
    OS << " has_init";
954
50
  if (Node->hasVarStorage())
955
1
    OS << " has_var";
956
50
  if (Node->hasElseStorage())
957
23
    OS << " has_else";
958
50
  if (Node->isConstexpr())
959
4
    OS << " constexpr";
960
50
  if (Node->isConsteval()) {
961
4
    OS << " ";
962
4
    if (Node->isNegatedConsteval())
963
2
      OS << "!";
964
4
    OS << "consteval";
965
4
  }
966
50
}
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.25k
void TextNodeDumper::VisitCallExpr(const CallExpr *Node) {
1003
1.25k
  if (Node->usesADL())
1004
8
    OS << " adl";
1005
1.25k
  if (Node->hasStoredFPFeatures())
1006
8
    printFPOptions(Node->getFPFeatures());
1007
1.25k
}
1008
1009
43
void TextNodeDumper::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *Node) {
1010
43
  const char *OperatorSpelling = clang::getOperatorSpelling(Node->getOperator());
1011
43
  if (OperatorSpelling)
1012
43
    OS << " '" << OperatorSpelling << "'";
1013
1014
43
  VisitCallExpr(Node);
1015
43
}
1016
1017
5.37k
void TextNodeDumper::VisitCastExpr(const CastExpr *Node) {
1018
5.37k
  OS << " <";
1019
5.37k
  {
1020
5.37k
    ColorScope Color(OS, ShowColors, CastColor);
1021
5.37k
    OS << Node->getCastKindName();
1022
5.37k
  }
1023
5.37k
  dumpBasePath(OS, Node);
1024
5.37k
  OS << ">";
1025
5.37k
  if (Node->hasStoredFPFeatures())
1026
88
    printFPOptions(Node->getFPFeatures());
1027
5.37k
}
1028
1029
5.11k
void TextNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) {
1030
5.11k
  VisitCastExpr(Node);
1031
5.11k
  if (Node->isPartOfExplicitCast())
1032
127
    OS << " part_of_explicit_cast";
1033
5.11k
}
1034
1035
7.51k
void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
1036
7.51k
  OS << " ";
1037
7.51k
  dumpBareDeclRef(Node->getDecl());
1038
7.51k
  if (Node->getDecl() != Node->getFoundDecl()) {
1039
128
    OS << " (";
1040
128
    dumpBareDeclRef(Node->getFoundDecl());
1041
128
    OS << ")";
1042
128
  }
1043
7.51k
  switch (Node->isNonOdrUse()) {
1044
7.13k
  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.51k
  }
1049
7.51k
}
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
22
void TextNodeDumper::VisitCharacterLiteral(const CharacterLiteral *Node) {
1087
22
  ColorScope Color(OS, ShowColors, ValueColor);
1088
22
  OS << " " << Node->getValue();
1089
22
}
1090
1091
3.84k
void TextNodeDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
1092
3.84k
  bool isSigned = Node->getType()->isSignedIntegerType();
1093
3.84k
  ColorScope Color(OS, ShowColors, ValueColor);
1094
3.84k
  OS << " " << toString(Node->getValue(), 10, isSigned);
1095
3.84k
}
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
203
void TextNodeDumper::VisitFloatingLiteral(const FloatingLiteral *Node) {
1103
203
  ColorScope Color(OS, ShowColors, ValueColor);
1104
203
  OS << " " << Node->getValueAsApproximateDouble();
1105
203
}
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
312
void TextNodeDumper::VisitInitListExpr(const InitListExpr *ILE) {
1114
312
  if (auto *Field = ILE->getInitializedFieldInUnion()) {
1115
54
    OS << " field ";
1116
54
    dumpBareDeclRef(Field);
1117
54
  }
1118
312
}
1119
1120
14
void TextNodeDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
1121
14
  if (E->isResultDependent())
1122
0
    OS << " result_dependent";
1123
14
}
1124
1125
1.20k
void TextNodeDumper::VisitUnaryOperator(const UnaryOperator *Node) {
1126
1.20k
  OS << " " << (Node->isPostfix() ? 
"postfix"800
:
"prefix"402
) << " '"
1127
1.20k
     << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1128
1.20k
  if (!Node->canOverflow())
1129
199
    OS << " cannot overflow";
1130
1.20k
  if (Node->hasStoredFPFeatures())
1131
0
    printFPOptions(Node->getStoredFPFeatures());
1132
1.20k
}
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
598
void TextNodeDumper::VisitMemberExpr(const MemberExpr *Node) {
1143
598
  OS << " " << (Node->isArrow() ? 
"->"149
:
"."449
) << *Node->getMemberDecl();
1144
598
  dumpPointer(Node->getMemberDecl());
1145
598
  switch (Node->isNonOdrUse()) {
1146
584
  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
598
  }
1151
598
}
1152
1153
void TextNodeDumper::VisitExtVectorElementExpr(
1154
9
    const ExtVectorElementExpr *Node) {
1155
9
  OS << " " << Node->getAccessor().getNameStart();
1156
9
}
1157
1158
1.76k
void TextNodeDumper::VisitBinaryOperator(const BinaryOperator *Node) {
1159
1.76k
  OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1160
1.76k
  if (Node->hasStoredFPFeatures())
1161
30
    printFPOptions(Node->getStoredFPFeatures());
1162
1.76k
}
1163
1164
void TextNodeDumper::VisitCompoundAssignOperator(
1165
95
    const CompoundAssignOperator *Node) {
1166
95
  OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
1167
95
     << "' ComputeLHSTy=";
1168
95
  dumpBareType(Node->getComputationLHSType());
1169
95
  OS << " ComputeResultTy=";
1170
95
  dumpBareType(Node->getComputationResultType());
1171
95
  if (Node->hasStoredFPFeatures())
1172
0
    printFPOptions(Node->getStoredFPFeatures());
1173
95
}
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
180
void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
1193
180
  if (Node->isImplicit())
1194
134
    OS << " implicit";
1195
180
  OS << " this";
1196
180
}
1197
1198
void TextNodeDumper::VisitCXXFunctionalCastExpr(
1199
41
    const CXXFunctionalCastExpr *Node) {
1200
41
  OS << " functional cast to " << Node->getTypeAsWritten().getAsString() << " <"
1201
41
     << Node->getCastKindName() << ">";
1202
41
  if (Node->hasStoredFPFeatures())
1203
2
    printFPOptions(Node->getFPFeatures());
1204
41
}
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
503
void TextNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
1220
503
  CXXConstructorDecl *Ctor = Node->getConstructor();
1221
503
  dumpType(Ctor->getType());
1222
503
  if (Node->isElidable())
1223
91
    OS << " elidable";
1224
503
  if (Node->isListInitialization())
1225
12
    OS << " list";
1226
503
  if (Node->isStdInitListInitialization())
1227
1
    OS << " std::initializer_list";
1228
503
  if (Node->requiresZeroInitialization())
1229
37
    OS << " zeroing";
1230
503
}
1231
1232
void TextNodeDumper::VisitCXXBindTemporaryExpr(
1233
97
    const CXXBindTemporaryExpr *Node) {
1234
97
  OS << " (CXXTemporary";
1235
97
  dumpPointer(Node);
1236
97
  OS << ")";
1237
97
}
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
288
    const MaterializeTemporaryExpr *Node) {
1277
288
  if (const ValueDecl *VD = Node->getExtendingDecl()) {
1278
8
    OS << " extended by ";
1279
8
    dumpBareDeclRef(VD);
1280
8
  }
1281
288
}
1282
1283
228
void TextNodeDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) {
1284
242
  for (unsigned i = 0, e = Node->getNumObjects(); i != e; 
++i14
)
1285
14
    dumpCleanupObject(Node->getObject(i));
1286
228
}
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
380
void TextNodeDumper::VisitArrayType(const ArrayType *T) {
1436
380
  switch (T->getSizeModifier()) {
1437
380
  case ArrayType::Normal:
1438
380
    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
380
  }
1446
380
  OS << " " << T->getIndexTypeQualifiers().getAsString();
1447
380
}
1448
1449
374
void TextNodeDumper::VisitConstantArrayType(const ConstantArrayType *T) {
1450
374
  OS << " " << T->getSize();
1451
374
  VisitArrayType(T);
1452
374
}
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
21
    const DependentSizedExtVectorType *T) {
1469
21
  OS << " ";
1470
21
  dumpLocation(T->getAttributeLoc());
1471
21
}
1472
1473
9
void TextNodeDumper::VisitVectorType(const VectorType *T) {
1474
9
  switch (T->getVectorKind()) {
1475
8
  case VectorType::GenericVector:
1476
8
    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
9
  }
1499
9
  OS << " " << T->getNumElements();
1500
9
}
1501
1502
48
void TextNodeDumper::VisitFunctionType(const FunctionType *T) {
1503
48
  auto EI = T->getExtInfo();
1504
48
  if (EI.getNoReturn())
1505
0
    OS << " noreturn";
1506
48
  if (EI.getProducesResult())
1507
0
    OS << " produces_result";
1508
48
  if (EI.getHasRegParm())
1509
0
    OS << " regparm " << EI.getRegParm();
1510
48
  OS << " " << FunctionType::getNameForCallConv(EI.getCC());
1511
48
}
1512
1513
48
void TextNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) {
1514
48
  auto EPI = T->getExtProtoInfo();
1515
48
  if (EPI.HasTrailingReturn)
1516
13
    OS << " trailing_return";
1517
48
  if (T->isConst())
1518
0
    OS << " const";
1519
48
  if (T->isVolatile())
1520
0
    OS << " volatile";
1521
48
  if (T->isRestrict())
1522
0
    OS << " restrict";
1523
48
  if (T->getExtProtoInfo().Variadic)
1524
0
    OS << " variadic";
1525
48
  switch (EPI.RefQualifier) {
1526
48
  case RQ_None:
1527
48
    break;
1528
0
  case RQ_LValue:
1529
0
    OS << " &";
1530
0
    break;
1531
0
  case RQ_RValue:
1532
0
    OS << " &&";
1533
0
    break;
1534
48
  }
1535
  // FIXME: Exception specification.
1536
  // FIXME: Consumed parameters.
1537
48
  VisitFunctionType(T);
1538
48
}
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
33
void TextNodeDumper::VisitTypedefType(const TypedefType *T) {
1549
33
  dumpDeclRef(T->getDecl());
1550
33
}
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
966
void TextNodeDumper::VisitTagType(const TagType *T) {
1561
966
  dumpDeclRef(T->getDecl());
1562
966
}
1563
1564
212
void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
1565
212
  OS << " depth " << T->getDepth() << " index " << T->getIndex();
1566
212
  if (T->isParameterPack())
1567
70
    OS << " pack";
1568
212
  dumpDeclRef(T->getDecl());
1569
212
}
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
86
    const TemplateSpecializationType *T) {
1591
86
  if (T->isTypeAlias())
1592
18
    OS << " alias";
1593
86
  if (T->getTemplateName().getKind() == TemplateName::UsingTemplate)
1594
1
    OS << " using";
1595
86
  OS << " ";
1596
86
  T->getTemplateName().dump(OS);
1597
86
}
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
24
void TextNodeDumper::VisitPackExpansionType(const PackExpansionType *T) {
1609
24
  if (auto N = T->getNumExpansions())
1610
4
    OS << " expansions " << *N;
1611
24
}
1612
1613
4
void TextNodeDumper::VisitLabelDecl(const LabelDecl *D) { dumpName(D); }
1614
1615
3.03k
void TextNodeDumper::VisitTypedefDecl(const TypedefDecl *D) {
1616
3.03k
  dumpName(D);
1617
3.03k
  dumpType(D->getUnderlyingType());
1618
3.03k
  if (D->isModulePrivate())
1619
1
    OS << " __module_private__";
1620
3.03k
}
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.13k
void TextNodeDumper::VisitRecordDecl(const RecordDecl *D) {
1637
3.13k
  OS << ' ' << D->getKindName();
1638
3.13k
  dumpName(D);
1639
3.13k
  if (D->isModulePrivate())
1640
1
    OS << " __module_private__";
1641
3.13k
  if (D->isCompleteDefinition())
1642
1.89k
    OS << " definition";
1643
3.13k
}
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.96k
void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) {
1659
4.96k
  dumpName(D);
1660
4.96k
  dumpType(D->getType());
1661
1662
4.96k
  StorageClass SC = D->getStorageClass();
1663
4.96k
  if (SC != SC_None)
1664
339
    OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
1665
4.96k
  if (D->isInlineSpecified())
1666
1.61k
    OS << " inline";
1667
4.96k
  if (D->isVirtualAsWritten())
1668
47
    OS << " virtual";
1669
4.96k
  if (D->isModulePrivate())
1670
0
    OS << " __module_private__";
1671
1672
4.96k
  if (D->isPure())
1673
6
    OS << " pure";
1674
4.96k
  if (D->isDefaulted()) {
1675
1.20k
    OS << " default";
1676
1.20k
    if (D->isDeleted())
1677
88
      OS << "_delete";
1678
1.20k
  }
1679
4.96k
  if (D->isDeletedAsWritten())
1680
22
    OS << " delete";
1681
4.96k
  if (D->isTrivial())
1682
995
    OS << " trivial";
1683
1684
4.96k
  if (D->isIneligibleOrNotSelected())
1685
3
    OS << (isa<CXXDestructorDecl>(D) ? " not_selected" : 
" ineligible"0
);
1686
1687
4.96k
  if (const auto *FPT = D->getType()->getAs<FunctionProtoType>()) {
1688
4.85k
    FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
1689
4.85k
    switch (EPI.ExceptionSpec.Type) {
1690
4.06k
    default:
1691
4.06k
      break;
1692
4.06k
    case EST_Unevaluated:
1693
799
      OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl;
1694
799
      break;
1695
0
    case EST_Uninstantiated:
1696
0
      OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate;
1697
0
      break;
1698
4.85k
    }
1699
4.85k
  }
1700
1701
4.96k
  if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
1702
2.48k
    if (MD->size_overridden_methods() != 0) {
1703
14
      auto dumpOverride = [=](const CXXMethodDecl *D) {
1704
14
        SplitQualType T_split = D->getType().split();
1705
14
        OS << D << " " << D->getParent()->getName() << "::" << D->getDeclName()
1706
14
           << " '" << QualType::getAsString(T_split, PrintPolicy) << "'";
1707
14
      };
1708
1709
13
      AddChild([=] {
1710
13
        auto Overrides = MD->overridden_methods();
1711
13
        OS << "Overrides: [ ";
1712
13
        dumpOverride(*Overrides.begin());
1713
13
        for (const auto *Override :
1714
13
             llvm::make_range(Overrides.begin() + 1, Overrides.end())) {
1715
1
          OS << ", ";
1716
1
          dumpOverride(Override);
1717
1
        }
1718
13
        OS << " ]";
1719
13
      });
1720
13
    }
1721
2.48k
  }
1722
1723
  // Since NumParams comes from the FunctionProtoType of the FunctionDecl and
1724
  // the Params are set later, it is possible for a dump during debugging to
1725
  // encounter a FunctionDecl that has been created but hasn't been assigned
1726
  // ParmVarDecls yet.
1727
4.96k
  if (!D->param_empty() && 
!D->param_begin()2.25k
)
1728
0
    OS << " <<<NULL params x " << D->getNumParams() << ">>>";
1729
4.96k
}
1730
1731
void TextNodeDumper::VisitLifetimeExtendedTemporaryDecl(
1732
0
    const LifetimeExtendedTemporaryDecl *D) {
1733
0
  OS << " extended by ";
1734
0
  dumpBareDeclRef(D->getExtendingDecl());
1735
0
  OS << " mangling ";
1736
0
  {
1737
0
    ColorScope Color(OS, ShowColors, ValueColor);
1738
0
    OS << D->getManglingNumber();
1739
0
  }
1740
0
}
1741
1742
1.96k
void TextNodeDumper::VisitFieldDecl(const FieldDecl *D) {
1743
1.96k
  dumpName(D);
1744
1.96k
  dumpType(D->getType());
1745
1.96k
  if (D->isMutable())
1746
2
    OS << " mutable";
1747
1.96k
  if (D->isModulePrivate())
1748
1
    OS << " __module_private__";
1749
1.96k
}
1750
1751
9.33k
void TextNodeDumper::VisitVarDecl(const VarDecl *D) {
1752
9.33k
  dumpName(D);
1753
9.33k
  dumpType(D->getType());
1754
9.33k
  StorageClass SC = D->getStorageClass();
1755
9.33k
  if (SC != SC_None)
1756
116
    OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
1757
9.33k
  switch (D->getTLSKind()) {
1758
9.31k
  case VarDecl::TLS_None:
1759
9.31k
    break;
1760
10
  case VarDecl::TLS_Static:
1761
10
    OS << " tls";
1762
10
    break;
1763
7
  case VarDecl::TLS_Dynamic:
1764
7
    OS << " tls_dynamic";
1765
7
    break;
1766
9.33k
  }
1767
9.33k
  if (D->isModulePrivate())
1768
1
    OS << " __module_private__";
1769
9.33k
  if (D->isNRVOVariable())
1770
32
    OS << " nrvo";
1771
9.33k
  if (D->isInline())
1772
1
    OS << " inline";
1773
9.33k
  if (D->isConstexpr())
1774
92
    OS << " constexpr";
1775
9.33k
  if (D->hasInit()) {
1776
2.76k
    switch (D->getInitStyle()) {
1777
2.58k
    case VarDecl::CInit:
1778
2.58k
      OS << " cinit";
1779
2.58k
      break;
1780
119
    case VarDecl::CallInit:
1781
119
      OS << " callinit";
1782
119
      break;
1783
56
    case VarDecl::ListInit:
1784
56
      OS << " listinit";
1785
56
      break;
1786
2.76k
    }
1787
2.76k
  }
1788
9.33k
  if (D->needsDestruction(D->getASTContext()))
1789
51
    OS << " destroyed";
1790
9.33k
  if (D->isParameterPack())
1791
19
    OS << " pack";
1792
1793
9.33k
  if (D->hasInit()) {
1794
2.76k
    const Expr *E = D->getInit();
1795
    // Only dump the value of constexpr VarDecls for now.
1796
2.76k
    if (E && !E->isValueDependent() && 
D->isConstexpr()2.67k
) {
1797
89
      const APValue *Value = D->evaluateValue();
1798
89
      if (Value)
1799
89
        AddChild("value", [=] { Visit(*Value, E->getType()); });
1800
89
    }
1801
2.76k
  }
1802
9.33k
}
1803
1804
0
void TextNodeDumper::VisitBindingDecl(const BindingDecl *D) {
1805
0
  dumpName(D);
1806
0
  dumpType(D->getType());
1807
0
}
1808
1809
868
void TextNodeDumper::VisitCapturedDecl(const CapturedDecl *D) {
1810
868
  if (D->isNothrow())
1811
777
    OS << " nothrow";
1812
868
}
1813
1814
4
void TextNodeDumper::VisitImportDecl(const ImportDecl *D) {
1815
4
  OS << ' ' << D->getImportedModule()->getFullModuleName();
1816
1817
4
  for (Decl *InitD :
1818
4
       D->getASTContext().getModuleInitializers(D->getImportedModule()))
1819
0
    dumpDeclRef(InitD, "initializer");
1820
4
}
1821
1822
0
void TextNodeDumper::VisitPragmaCommentDecl(const PragmaCommentDecl *D) {
1823
0
  OS << ' ';
1824
0
  switch (D->getCommentKind()) {
1825
0
  case PCK_Unknown:
1826
0
    llvm_unreachable("unexpected pragma comment kind");
1827
0
  case PCK_Compiler:
1828
0
    OS << "compiler";
1829
0
    break;
1830
0
  case PCK_ExeStr:
1831
0
    OS << "exestr";
1832
0
    break;
1833
0
  case PCK_Lib:
1834
0
    OS << "lib";
1835
0
    break;
1836
0
  case PCK_Linker:
1837
0
    OS << "linker";
1838
0
    break;
1839
0
  case PCK_User:
1840
0
    OS << "user";
1841
0
    break;
1842
0
  }
1843
0
  StringRef Arg = D->getArg();
1844
0
  if (!Arg.empty())
1845
0
    OS << " \"" << Arg << "\"";
1846
0
}
1847
1848
void TextNodeDumper::VisitPragmaDetectMismatchDecl(
1849
0
    const PragmaDetectMismatchDecl *D) {
1850
0
  OS << " \"" << D->getName() << "\" \"" << D->getValue() << "\"";
1851
0
}
1852
1853
void TextNodeDumper::VisitOMPExecutableDirective(
1854
417
    const OMPExecutableDirective *D) {
1855
417
  if (D->isStandaloneDirective())
1856
66
    OS << " openmp_standalone_directive";
1857
417
}
1858
1859
void TextNodeDumper::VisitOMPDeclareReductionDecl(
1860
6
    const OMPDeclareReductionDecl *D) {
1861
6
  dumpName(D);
1862
6
  dumpType(D->getType());
1863
6
  OS << " combiner";
1864
6
  dumpPointer(D->getCombiner());
1865
6
  if (const auto *Initializer = D->getInitializer()) {
1866
2
    OS << " initializer";
1867
2
    dumpPointer(Initializer);
1868
2
    switch (D->getInitializerKind()) {
1869
0
    case OMPDeclareReductionDecl::DirectInit:
1870
0
      OS << " omp_priv = ";
1871
0
      break;
1872
2
    case OMPDeclareReductionDecl::CopyInit:
1873
2
      OS << " omp_priv ()";
1874
2
      break;
1875
0
    case OMPDeclareReductionDecl::CallInit:
1876
0
      break;
1877
2
    }
1878
2
  }
1879
6
}
1880
1881
0
void TextNodeDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) {
1882
0
  for (const auto *C : D->clauselists()) {
1883
0
    AddChild([=] {
1884
0
      if (!C) {
1885
0
        ColorScope Color(OS, ShowColors, NullColor);
1886
0
        OS << "<<<NULL>>> OMPClause";
1887
0
        return;
1888
0
      }
1889
0
      {
1890
0
        ColorScope Color(OS, ShowColors, AttrColor);
1891
0
        StringRef ClauseName(
1892
0
            llvm::omp::getOpenMPClauseName(C->getClauseKind()));
1893
0
        OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
1894
0
           << ClauseName.drop_front() << "Clause";
1895
0
      }
1896
0
      dumpPointer(C);
1897
0
      dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
1898
0
    });
1899
0
  }
1900
0
}
1901
1902
104
void TextNodeDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
1903
104
  dumpName(D);
1904
104
  dumpType(D->getType());
1905
104
}
1906
1907
202
void TextNodeDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
1908
202
  dumpName(D);
1909
202
  if (D->isInline())
1910
3
    OS << " inline";
1911
202
  if (!D->isOriginalNamespace())
1912
4
    dumpDeclRef(D->getOriginalNamespace(), "original");
1913
202
}
1914
1915
47
void TextNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
1916
47
  OS << ' ';
1917
47
  dumpBareDeclRef(D->getNominatedNamespace());
1918
47
}
1919
1920
4
void TextNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
1921
4
  dumpName(D);
1922
4
  dumpDeclRef(D->getAliasedNamespace());
1923
4
}
1924
1925
138
void TextNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
1926
138
  dumpName(D);
1927
138
  dumpType(D->getUnderlyingType());
1928
138
}
1929
1930
void TextNodeDumper::VisitTypeAliasTemplateDecl(
1931
43
    const TypeAliasTemplateDecl *D) {
1932
43
  dumpName(D);
1933
43
}
1934
1935
2.71k
void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
1936
2.71k
  VisitRecordDecl(D);
1937
2.71k
  if (!D->isCompleteDefinition())
1938
1.21k
    return;
1939
1940
1.49k
  AddChild([=] {
1941
1.49k
    {
1942
1.49k
      ColorScope Color(OS, ShowColors, DeclKindNameColor);
1943
1.49k
      OS << "DefinitionData";
1944
1.49k
    }
1945
1.49k
#define FLAG(fn, name)                                                         \
1946
99.9k
  
if (4.37k
D->fn()) \
1947
45.2k
    OS << " " #name;
1948
1.49k
    FLAG(isParsingBaseSpecifiers, parsing_base_specifiers);
1949
1950
1.49k
    FLAG(isGenericLambda, generic);
1951
1.49k
    FLAG(isLambda, lambda);
1952
1953
1.49k
    FLAG(isAnonymousStructOrUnion, is_anonymous);
1954
1.49k
    FLAG(canPassInRegisters, pass_in_registers);
1955
1.49k
    FLAG(isEmpty, empty);
1956
1.49k
    FLAG(isAggregate, aggregate);
1957
1.49k
    FLAG(isStandardLayout, standard_layout);
1958
1.49k
    FLAG(isTriviallyCopyable, trivially_copyable);
1959
1.49k
    FLAG(isPOD, pod);
1960
1.49k
    FLAG(isTrivial, trivial);
1961
1.49k
    FLAG(isPolymorphic, polymorphic);
1962
1.49k
    FLAG(isAbstract, abstract);
1963
1.49k
    FLAG(isLiteral, literal);
1964
1965
1.49k
    FLAG(hasUserDeclaredConstructor, has_user_declared_ctor);
1966
1.49k
    FLAG(hasConstexprNonCopyMoveConstructor, has_constexpr_non_copy_move_ctor);
1967
1.49k
    FLAG(hasMutableFields, has_mutable_fields);
1968
1.49k
    FLAG(hasVariantMembers, has_variant_members);
1969
1.49k
    FLAG(allowConstDefaultInit, can_const_default_init);
1970
1971
1.49k
    AddChild([=] {
1972
1.49k
      {
1973
1.49k
        ColorScope Color(OS, ShowColors, DeclKindNameColor);
1974
1.49k
        OS << "DefaultConstructor";
1975
1.49k
      }
1976
1.49k
      FLAG(hasDefaultConstructor, exists);
1977
1.49k
      FLAG(hasTrivialDefaultConstructor, trivial);
1978
1.49k
      FLAG(hasNonTrivialDefaultConstructor, non_trivial);
1979
1.49k
      FLAG(hasUserProvidedDefaultConstructor, user_provided);
1980
1.49k
      FLAG(hasConstexprDefaultConstructor, constexpr);
1981
1.49k
      FLAG(needsImplicitDefaultConstructor, needs_implicit);
1982
1.49k
      FLAG(defaultedDefaultConstructorIsConstexpr, defaulted_is_constexpr);
1983
1.49k
    });
1984
1985
1.49k
    AddChild([=] {
1986
1.49k
      {
1987
1.49k
        ColorScope Color(OS, ShowColors, DeclKindNameColor);
1988
1.49k
        OS << "CopyConstructor";
1989
1.49k
      }
1990
1.49k
      FLAG(hasSimpleCopyConstructor, simple);
1991
1.49k
      FLAG(hasTrivialCopyConstructor, trivial);
1992
1.49k
      FLAG(hasNonTrivialCopyConstructor, non_trivial);
1993
1.49k
      FLAG(hasUserDeclaredCopyConstructor, user_declared);
1994
1.49k
      FLAG(hasCopyConstructorWithConstParam, has_const_param);
1995
1.49k
      FLAG(needsImplicitCopyConstructor, needs_implicit);
1996
1.49k
      FLAG(needsOverloadResolutionForCopyConstructor,
1997
1.49k
           needs_overload_resolution);
1998
1.49k
      if (!D->needsOverloadResolutionForCopyConstructor())
1999
1.44k
        FLAG(defaultedCopyConstructorIsDeleted, defaulted_is_deleted);
2000
1.49k
      FLAG(implicitCopyConstructorHasConstParam, implicit_has_const_param);
2001
1.49k
    });
2002
2003
1.49k
    AddChild([=] {
2004
1.49k
      {
2005
1.49k
        ColorScope Color(OS, ShowColors, DeclKindNameColor);
2006
1.49k
        OS << "MoveConstructor";
2007
1.49k
      }
2008
1.49k
      FLAG(hasMoveConstructor, exists);
2009
1.49k
      FLAG(hasSimpleMoveConstructor, simple);
2010
1.49k
      FLAG(hasTrivialMoveConstructor, trivial);
2011
1.49k
      FLAG(hasNonTrivialMoveConstructor, non_trivial);
2012
1.49k
      FLAG(hasUserDeclaredMoveConstructor, user_declared);
2013
1.49k
      FLAG(needsImplicitMoveConstructor, needs_implicit);
2014
1.49k
      FLAG(needsOverloadResolutionForMoveConstructor,
2015
1.49k
           needs_overload_resolution);
2016
1.49k
      if (!D->needsOverloadResolutionForMoveConstructor())
2017
1.46k
        FLAG(defaultedMoveConstructorIsDeleted, defaulted_is_deleted);
2018
1.49k
    });
2019
2020
1.49k
    AddChild([=] {
2021
1.49k
      {
2022
1.49k
        ColorScope Color(OS, ShowColors, DeclKindNameColor);
2023
1.49k
        OS << "CopyAssignment";
2024
1.49k
      }
2025
1.49k
      FLAG(hasSimpleCopyAssignment, simple);
2026
1.49k
      FLAG(hasTrivialCopyAssignment, trivial);
2027
1.49k
      FLAG(hasNonTrivialCopyAssignment, non_trivial);
2028
1.49k
      FLAG(hasCopyAssignmentWithConstParam, has_const_param);
2029
1.49k
      FLAG(hasUserDeclaredCopyAssignment, user_declared);
2030
1.49k
      FLAG(needsImplicitCopyAssignment, needs_implicit);
2031
1.49k
      FLAG(needsOverloadResolutionForCopyAssignment, needs_overload_resolution);
2032
1.49k
      FLAG(implicitCopyAssignmentHasConstParam, implicit_has_const_param);
2033
1.49k
    });
2034
2035
1.49k
    AddChild([=] {
2036
1.49k
      {
2037
1.49k
        ColorScope Color(OS, ShowColors, DeclKindNameColor);
2038
1.49k
        OS << "MoveAssignment";
2039
1.49k
      }
2040
1.49k
      FLAG(hasMoveAssignment, exists);
2041
1.49k
      FLAG(hasSimpleMoveAssignment, simple);
2042
1.49k
      FLAG(hasTrivialMoveAssignment, trivial);
2043
1.49k
      FLAG(hasNonTrivialMoveAssignment, non_trivial);
2044
1.49k
      FLAG(hasUserDeclaredMoveAssignment, user_declared);
2045
1.49k
      FLAG(needsImplicitMoveAssignment, needs_implicit);
2046
1.49k
      FLAG(needsOverloadResolutionForMoveAssignment, needs_overload_resolution);
2047
1.49k
    });
2048
2049
1.49k
    AddChild([=] {
2050
1.49k
      {
2051
1.49k
        ColorScope Color(OS, ShowColors, DeclKindNameColor);
2052
1.49k
        OS << "Destructor";
2053
1.49k
      }
2054
1.49k
      FLAG(hasSimpleDestructor, simple);
2055
1.49k
      FLAG(hasIrrelevantDestructor, irrelevant);
2056
1.49k
      FLAG(hasTrivialDestructor, trivial);
2057
1.49k
      FLAG(hasNonTrivialDestructor, non_trivial);
2058
1.49k
      FLAG(hasUserDeclaredDestructor, user_declared);
2059
1.49k
      FLAG(hasConstexprDestructor, constexpr);
2060
1.49k
      FLAG(needsImplicitDestructor, needs_implicit);
2061
1.49k
      FLAG(needsOverloadResolutionForDestructor, needs_overload_resolution);
2062
1.49k
      if (!D->needsOverloadResolutionForDestructor())
2063
1.47k
        FLAG(defaultedDestructorIsDeleted, defaulted_is_deleted);
2064
1.49k
    });
2065
1.49k
  });
2066
2067
1.49k
  for (const auto &I : D->bases()) {
2068
118
    AddChild([=] {
2069
118
      if (I.isVirtual())
2070
31
        OS << "virtual ";
2071
118
      dumpAccessSpecifier(I.getAccessSpecifier());
2072
118
      dumpType(I.getType());
2073
118
      if (I.isPackExpansion())
2074
3
        OS << "...";
2075
118
    });
2076
118
  }
2077
1.49k
}
2078
2079
350
void TextNodeDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
2080
350
  dumpName(D);
2081
350
}
2082
2083
222
void TextNodeDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
2084
222
  dumpName(D);
2085
222
}
2086
2087
5
void TextNodeDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
2088
5
  dumpName(D);
2089
5
}
2090
2091
4
void TextNodeDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
2092
4
  dumpName(D);
2093
4
}
2094
2095
633
void TextNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
2096
633
  if (const auto *TC = D->getTypeConstraint()) {
2097
12
    OS << " ";
2098
12
    dumpBareDeclRef(TC->getNamedConcept());
2099
12
    if (TC->getNamedConcept() != TC->getFoundDecl()) {
2100
4
      OS << " (";
2101
4
      dumpBareDeclRef(TC->getFoundDecl());
2102
4
      OS << ")";
2103
4
    }
2104
621
  } else if (D->wasDeclaredWithTypename())
2105
450
    OS << " typename";
2106
171
  else
2107
171
    OS << " class";
2108
633
  OS << " depth " << D->getDepth() << " index " << D->getIndex();
2109
633
  if (D->isParameterPack())
2110
67
    OS << " ...";
2111
633
  dumpName(D);
2112
633
}
2113
2114
void TextNodeDumper::VisitNonTypeTemplateParmDecl(
2115
239
    const NonTypeTemplateParmDecl *D) {
2116
239
  dumpType(D->getType());
2117
239
  OS << " depth " << D->getDepth() << " index " << D->getIndex();
2118
239
  if (D->isParameterPack())
2119
42
    OS << " ...";
2120
239
  dumpName(D);
2121
239
}
2122
2123
void TextNodeDumper::VisitTemplateTemplateParmDecl(
2124
16
    const TemplateTemplateParmDecl *D) {
2125
16
  OS << " depth " << D->getDepth() << " index " << D->getIndex();
2126
16
  if (D->isParameterPack())
2127
5
    OS << " ...";
2128
16
  dumpName(D);
2129
16
}
2130
2131
43
void TextNodeDumper::VisitUsingDecl(const UsingDecl *D) {
2132
43
  OS << ' ';
2133
43
  if (D->getQualifier())
2134
43
    D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2135
43
  OS << D->getDeclName();
2136
43
}
2137
2138
10
void TextNodeDumper::VisitUsingEnumDecl(const UsingEnumDecl *D) {
2139
10
  OS << ' ';
2140
10
  dumpBareDeclRef(D->getEnumDecl());
2141
10
}
2142
2143
void TextNodeDumper::VisitUnresolvedUsingTypenameDecl(
2144
1
    const UnresolvedUsingTypenameDecl *D) {
2145
1
  OS << ' ';
2146
1
  if (D->getQualifier())
2147
1
    D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2148
1
  OS << D->getDeclName();
2149
1
}
2150
2151
void TextNodeDumper::VisitUnresolvedUsingValueDecl(
2152
1
    const UnresolvedUsingValueDecl *D) {
2153
1
  OS << ' ';
2154
1
  if (D->getQualifier())
2155
1
    D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2156
1
  OS << D->getDeclName();
2157
1
  dumpType(D->getType());
2158
1
}
2159
2160
65
void TextNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
2161
65
  OS << ' ';
2162
65
  dumpBareDeclRef(D->getTargetDecl());
2163
65
}
2164
2165
void TextNodeDumper::VisitConstructorUsingShadowDecl(
2166
15
    const ConstructorUsingShadowDecl *D) {
2167
15
  if (D->constructsVirtualBase())
2168
0
    OS << " virtual";
2169
2170
15
  AddChild([=] {
2171
15
    OS << "target ";
2172
15
    dumpBareDeclRef(D->getTargetDecl());
2173
15
  });
2174
2175
15
  AddChild([=] {
2176
15
    OS << "nominated ";
2177
15
    dumpBareDeclRef(D->getNominatedBaseClass());
2178
15
    OS << ' ';
2179
15
    dumpBareDeclRef(D->getNominatedBaseClassShadowDecl());
2180
15
  });
2181
2182
15
  AddChild([=] {
2183
15
    OS << "constructed ";
2184
15
    dumpBareDeclRef(D->getConstructedBaseClass());
2185
15
    OS << ' ';
2186
15
    dumpBareDeclRef(D->getConstructedBaseClassShadowDecl());
2187
15
  });
2188
15
}
2189
2190
85
void TextNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
2191
85
  switch (D->getLanguage()) {
2192
84
  case LinkageSpecDecl::lang_c:
2193
84
    OS << " C";
2194
84
    break;
2195
1
  case LinkageSpecDecl::lang_cxx:
2196
1
    OS << " C++";
2197
1
    break;
2198
85
  }
2199
85
}
2200
2201
102
void TextNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
2202
102
  OS << ' ';
2203
102
  dumpAccessSpecifier(D->getAccess());
2204
102
}
2205
2206
10
void TextNodeDumper::VisitFriendDecl(const FriendDecl *D) {
2207
10
  if (TypeSourceInfo *T = D->getFriendType())
2208
4
    dumpType(T->getType());
2209
10
}
2210
2211
52
void TextNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
2212
52
  dumpName(D);
2213
52
  dumpType(D->getType());
2214
52
  if (D->getSynthesize())
2215
11
    OS << " synthesize";
2216
2217
52
  switch (D->getAccessControl()) {
2218
0
  case ObjCIvarDecl::None:
2219
0
    OS << " none";
2220
0
    break;
2221
23
  case ObjCIvarDecl::Private:
2222
23
    OS << " private";
2223
23
    break;
2224
21
  case ObjCIvarDecl::Protected:
2225
21
    OS << " protected";
2226
21
    break;
2227
6
  case ObjCIvarDecl::Public:
2228
6
    OS << " public";
2229
6
    break;
2230
2
  case ObjCIvarDecl::Package:
2231
2
    OS << " package";
2232
2
    break;
2233
52
  }
2234
52
}
2235
2236
178
void TextNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
2237
178
  if (D->isInstanceMethod())
2238
154
    OS << " -";
2239
24
  else
2240
24
    OS << " +";
2241
178
  dumpName(D);
2242
178
  dumpType(D->getReturnType());
2243
2244
178
  if (D->isVariadic())
2245
5
    OS << " variadic";
2246
178
}
2247
2248
4
void TextNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
2249
4
  dumpName(D);
2250
4
  switch (D->getVariance()) {
2251
4
  case ObjCTypeParamVariance::Invariant:
2252
4
    break;
2253
2254
0
  case ObjCTypeParamVariance::Covariant:
2255
0
    OS << " covariant";
2256
0
    break;
2257
2258
0
  case ObjCTypeParamVariance::Contravariant:
2259
0
    OS << " contravariant";
2260
0
    break;
2261
4
  }
2262
2263
4
  if (D->hasExplicitBound())
2264
1
    OS << " bounded";
2265
4
  dumpType(D->getUnderlyingType());
2266
4
}
2267
2268
19
void TextNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
2269
19
  dumpName(D);
2270
19
  dumpDeclRef(D->getClassInterface());
2271
19
  dumpDeclRef(D->getImplementation());
2272
19
  for (const auto *P : D->protocols())
2273
2
    dumpDeclRef(P);
2274
19
}
2275
2276
4
void TextNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
2277
4
  dumpName(D);
2278
4
  dumpDeclRef(D->getClassInterface());
2279
4
  dumpDeclRef(D->getCategoryDecl());
2280
4
}
2281
2282
20
void TextNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
2283
20
  dumpName(D);
2284
2285
20
  for (const auto *Child : D->protocols())
2286
0
    dumpDeclRef(Child);
2287
20
}
2288
2289
105
void TextNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
2290
105
  dumpName(D);
2291
105
  dumpDeclRef(D->getSuperClass(), "super");
2292
2293
105
  dumpDeclRef(D->getImplementation());
2294
105
  for (const auto *Child : D->protocols())
2295
5
    dumpDeclRef(Child);
2296
105
}
2297
2298
void TextNodeDumper::VisitObjCImplementationDecl(
2299
25
    const ObjCImplementationDecl *D) {
2300
25
  dumpName(D);
2301
25
  dumpDeclRef(D->getSuperClass(), "super");
2302
25
  dumpDeclRef(D->getClassInterface());
2303
25
}
2304
2305
void TextNodeDumper::VisitObjCCompatibleAliasDecl(
2306
3
    const ObjCCompatibleAliasDecl *D) {
2307
3
  dumpName(D);
2308
3
  dumpDeclRef(D->getClassInterface());
2309
3
}
2310
2311
45
void TextNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
2312
45
  dumpName(D);
2313
45
  dumpType(D->getType());
2314
2315
45
  if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
2316
0
    OS << " required";
2317
45
  else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
2318
0
    OS << " optional";
2319
2320
45
  ObjCPropertyAttribute::Kind Attrs = D->getPropertyAttributes();
2321
45
  if (Attrs != ObjCPropertyAttribute::kind_noattr) {
2322
45
    if (Attrs & ObjCPropertyAttribute::kind_readonly)
2323
16
      OS << " readonly";
2324
45
    if (Attrs & ObjCPropertyAttribute::kind_assign)
2325
27
      OS << " assign";
2326
45
    if (Attrs & ObjCPropertyAttribute::kind_readwrite)
2327
29
      OS << " readwrite";
2328
45
    if (Attrs & ObjCPropertyAttribute::kind_retain)
2329
1
      OS << " retain";
2330
45
    if (Attrs & ObjCPropertyAttribute::kind_copy)
2331
1
      OS << " copy";
2332
45
    if (Attrs & ObjCPropertyAttribute::kind_nonatomic)
2333
5
      OS << " nonatomic";
2334
45
    if (Attrs & ObjCPropertyAttribute::kind_atomic)
2335
31
      OS << " atomic";
2336
45
    if (Attrs & ObjCPropertyAttribute::kind_weak)
2337
0
      OS << " weak";
2338
45
    if (Attrs & ObjCPropertyAttribute::kind_strong)
2339
0
      OS << " strong";
2340
45
    if (Attrs & ObjCPropertyAttribute::kind_unsafe_unretained)
2341
26
      OS << " unsafe_unretained";
2342
45
    if (Attrs & ObjCPropertyAttribute::kind_class)
2343
1
      OS << " class";
2344
45
    if (Attrs & ObjCPropertyAttribute::kind_direct)
2345
0
      OS << " direct";
2346
45
    if (Attrs & ObjCPropertyAttribute::kind_getter)
2347
12
      dumpDeclRef(D->getGetterMethodDecl(), "getter");
2348
45
    if (Attrs & ObjCPropertyAttribute::kind_setter)
2349
12
      dumpDeclRef(D->getSetterMethodDecl(), "setter");
2350
45
  }
2351
45
}
2352
2353
20
void TextNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
2354
20
  dumpName(D->getPropertyDecl());
2355
20
  if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
2356
19
    OS << " synthesize";
2357
1
  else
2358
1
    OS << " dynamic";
2359
20
  dumpDeclRef(D->getPropertyDecl());
2360
20
  dumpDeclRef(D->getPropertyIvarDecl());
2361
20
}
2362
2363
21
void TextNodeDumper::VisitBlockDecl(const BlockDecl *D) {
2364
21
  if (D->isVariadic())
2365
2
    OS << " variadic";
2366
2367
21
  if (D->capturesCXXThis())
2368
3
    OS << " captures_this";
2369
21
}
2370
2371
4
void TextNodeDumper::VisitConceptDecl(const ConceptDecl *D) {
2372
4
  dumpName(D);
2373
4
}
2374
2375
2.98k
void TextNodeDumper::VisitCompoundStmt(const CompoundStmt *S) {
2376
2.98k
  VisitStmt(S);
2377
2.98k
  if (S->hasStoredFPFeatures())
2378
188
    printFPOptions(S->getStoredFPFeatures());
2379
2.98k
}