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