Coverage Report

Created: 2020-10-24 06:27

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