xref: /llvm-project/clang/lib/AST/TextNodeDumper.cpp (revision 8c2574832ed2064996389e4259eaf0bea0fa7951)
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/NestedNameSpecifier.h"
20 #include "clang/AST/Type.h"
21 #include "clang/AST/TypeLocVisitor.h"
22 #include "clang/Basic/Module.h"
23 #include "clang/Basic/SourceManager.h"
24 #include "clang/Basic/Specifiers.h"
25 #include "clang/Basic/TypeTraits.h"
26 #include "llvm/ADT/StringExtras.h"
27 
28 #include <algorithm>
29 #include <utility>
30 
31 using namespace clang;
32 
33 static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {}
34 
35 template <typename T>
36 static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) {
37   const T *First = D->getFirstDecl();
38   if (First != D)
39     OS << " first " << First;
40 }
41 
42 template <typename T>
43 static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) {
44   const T *Prev = D->getPreviousDecl();
45   if (Prev)
46     OS << " prev " << Prev;
47 }
48 
49 /// Dump the previous declaration in the redeclaration chain for a declaration,
50 /// if any.
51 static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) {
52   switch (D->getKind()) {
53 #define DECL(DERIVED, BASE)                                                    \
54   case Decl::DERIVED:                                                          \
55     return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D));
56 #define ABSTRACT_DECL(DECL)
57 #include "clang/AST/DeclNodes.inc"
58   }
59   llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
60 }
61 
62 TextNodeDumper::TextNodeDumper(raw_ostream &OS, const ASTContext &Context,
63                                bool ShowColors)
64     : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors),
65       Context(&Context), SM(&Context.getSourceManager()),
66       PrintPolicy(Context.getPrintingPolicy()),
67       Traits(&Context.getCommentCommandTraits()) {}
68 
69 TextNodeDumper::TextNodeDumper(raw_ostream &OS, bool ShowColors)
70     : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors) {}
71 
72 void TextNodeDumper::Visit(const comments::Comment *C,
73                            const comments::FullComment *FC) {
74   if (!C) {
75     ColorScope Color(OS, ShowColors, NullColor);
76     OS << "<<<NULL>>>";
77     return;
78   }
79 
80   {
81     ColorScope Color(OS, ShowColors, CommentColor);
82     OS << C->getCommentKindName();
83   }
84   dumpPointer(C);
85   dumpSourceRange(C->getSourceRange());
86 
87   ConstCommentVisitor<TextNodeDumper, void,
88                       const comments::FullComment *>::visit(C, FC);
89 }
90 
91 void TextNodeDumper::Visit(const Attr *A) {
92   {
93     ColorScope Color(OS, ShowColors, AttrColor);
94 
95     switch (A->getKind()) {
96 #define ATTR(X)                                                                \
97   case attr::X:                                                                \
98     OS << #X;                                                                  \
99     break;
100 #include "clang/Basic/AttrList.inc"
101     }
102     OS << "Attr";
103   }
104   dumpPointer(A);
105   dumpSourceRange(A->getRange());
106   if (A->isInherited())
107     OS << " Inherited";
108   if (A->isImplicit())
109     OS << " Implicit";
110 
111   ConstAttrVisitor<TextNodeDumper>::Visit(A);
112 }
113 
114 void TextNodeDumper::Visit(const TemplateArgument &TA, SourceRange R,
115                            const Decl *From, StringRef Label) {
116   OS << "TemplateArgument";
117   if (R.isValid())
118     dumpSourceRange(R);
119 
120   if (From)
121     dumpDeclRef(From, Label);
122 
123   ConstTemplateArgumentVisitor<TextNodeDumper>::Visit(TA);
124 }
125 
126 void TextNodeDumper::Visit(const Stmt *Node) {
127   if (!Node) {
128     ColorScope Color(OS, ShowColors, NullColor);
129     OS << "<<<NULL>>>";
130     return;
131   }
132   {
133     ColorScope Color(OS, ShowColors, StmtColor);
134     OS << Node->getStmtClassName();
135   }
136   dumpPointer(Node);
137   dumpSourceRange(Node->getSourceRange());
138 
139   if (const auto *E = dyn_cast<Expr>(Node)) {
140     dumpType(E->getType());
141 
142     if (E->containsErrors()) {
143       ColorScope Color(OS, ShowColors, ErrorsColor);
144       OS << " contains-errors";
145     }
146 
147     {
148       ColorScope Color(OS, ShowColors, ValueKindColor);
149       switch (E->getValueKind()) {
150       case VK_PRValue:
151         break;
152       case VK_LValue:
153         OS << " lvalue";
154         break;
155       case VK_XValue:
156         OS << " xvalue";
157         break;
158       }
159     }
160 
161     {
162       ColorScope Color(OS, ShowColors, ObjectKindColor);
163       switch (E->getObjectKind()) {
164       case OK_Ordinary:
165         break;
166       case OK_BitField:
167         OS << " bitfield";
168         break;
169       case OK_ObjCProperty:
170         OS << " objcproperty";
171         break;
172       case OK_ObjCSubscript:
173         OS << " objcsubscript";
174         break;
175       case OK_VectorComponent:
176         OS << " vectorcomponent";
177         break;
178       case OK_MatrixComponent:
179         OS << " matrixcomponent";
180         break;
181       }
182     }
183   }
184 
185   ConstStmtVisitor<TextNodeDumper>::Visit(Node);
186 }
187 
188 void TextNodeDumper::Visit(const Type *T) {
189   if (!T) {
190     ColorScope Color(OS, ShowColors, NullColor);
191     OS << "<<<NULL>>>";
192     return;
193   }
194   if (isa<LocInfoType>(T)) {
195     {
196       ColorScope Color(OS, ShowColors, TypeColor);
197       OS << "LocInfo Type";
198     }
199     dumpPointer(T);
200     return;
201   }
202 
203   {
204     ColorScope Color(OS, ShowColors, TypeColor);
205     OS << T->getTypeClassName() << "Type";
206   }
207   dumpPointer(T);
208   OS << " ";
209   dumpBareType(QualType(T, 0), false);
210 
211   QualType SingleStepDesugar =
212       T->getLocallyUnqualifiedSingleStepDesugaredType();
213   if (SingleStepDesugar != QualType(T, 0))
214     OS << " sugar";
215 
216   if (T->containsErrors()) {
217     ColorScope Color(OS, ShowColors, ErrorsColor);
218     OS << " contains-errors";
219   }
220 
221   if (T->isDependentType())
222     OS << " dependent";
223   else if (T->isInstantiationDependentType())
224     OS << " instantiation_dependent";
225 
226   if (T->isVariablyModifiedType())
227     OS << " variably_modified";
228   if (T->containsUnexpandedParameterPack())
229     OS << " contains_unexpanded_pack";
230   if (T->isFromAST())
231     OS << " imported";
232 
233   TypeVisitor<TextNodeDumper>::Visit(T);
234 }
235 
236 void TextNodeDumper::Visit(QualType T) {
237   OS << "QualType";
238   dumpPointer(T.getAsOpaquePtr());
239   OS << " ";
240   dumpBareType(T, false);
241   OS << " " << T.split().Quals.getAsString();
242 }
243 
244 void TextNodeDumper::Visit(TypeLoc TL) {
245   if (!TL) {
246     ColorScope Color(OS, ShowColors, NullColor);
247     OS << "<<<NULL>>>";
248     return;
249   }
250 
251   {
252     ColorScope Color(OS, ShowColors, TypeColor);
253     OS << (TL.getTypeLocClass() == TypeLoc::Qualified
254                ? "Qualified"
255                : TL.getType()->getTypeClassName())
256        << "TypeLoc";
257   }
258   dumpSourceRange(TL.getSourceRange());
259   OS << ' ';
260   dumpBareType(TL.getType(), /*Desugar=*/false);
261 
262   TypeLocVisitor<TextNodeDumper>::Visit(TL);
263 }
264 
265 void TextNodeDumper::Visit(const Decl *D) {
266   if (!D) {
267     ColorScope Color(OS, ShowColors, NullColor);
268     OS << "<<<NULL>>>";
269     return;
270   }
271 
272   {
273     ColorScope Color(OS, ShowColors, DeclKindNameColor);
274     OS << D->getDeclKindName() << "Decl";
275   }
276   dumpPointer(D);
277   if (D->getLexicalDeclContext() != D->getDeclContext())
278     OS << " parent " << cast<Decl>(D->getDeclContext());
279   dumpPreviousDecl(OS, D);
280   dumpSourceRange(D->getSourceRange());
281   OS << ' ';
282   dumpLocation(D->getLocation());
283   if (D->isFromASTFile())
284     OS << " imported";
285   if (Module *M = D->getOwningModule())
286     OS << " in " << M->getFullModuleName();
287   if (auto *ND = dyn_cast<NamedDecl>(D))
288     for (Module *M : D->getASTContext().getModulesWithMergedDefinition(
289              const_cast<NamedDecl *>(ND)))
290       AddChild([=] { OS << "also in " << M->getFullModuleName(); });
291   if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
292     if (!ND->isUnconditionallyVisible())
293       OS << " hidden";
294   if (D->isImplicit())
295     OS << " implicit";
296 
297   if (D->isUsed())
298     OS << " used";
299   else if (D->isThisDeclarationReferenced())
300     OS << " referenced";
301 
302   if (D->isInvalidDecl())
303     OS << " invalid";
304   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
305     if (FD->isConstexprSpecified())
306       OS << " constexpr";
307     if (FD->isConsteval())
308       OS << " consteval";
309     else if (FD->isImmediateFunction())
310       OS << " immediate";
311     if (FD->isMultiVersion())
312       OS << " multiversion";
313   }
314 
315   if (!isa<FunctionDecl>(*D)) {
316     const auto *MD = dyn_cast<ObjCMethodDecl>(D);
317     if (!MD || !MD->isThisDeclarationADefinition()) {
318       const auto *DC = dyn_cast<DeclContext>(D);
319       if (DC && DC->hasExternalLexicalStorage()) {
320         ColorScope Color(OS, ShowColors, UndeserializedColor);
321         OS << " <undeserialized declarations>";
322       }
323     }
324   }
325 
326   switch (D->getFriendObjectKind()) {
327   case Decl::FOK_None:
328     break;
329   case Decl::FOK_Declared:
330     OS << " friend";
331     break;
332   case Decl::FOK_Undeclared:
333     OS << " friend_undeclared";
334     break;
335   }
336 
337   ConstDeclVisitor<TextNodeDumper>::Visit(D);
338 }
339 
340 void TextNodeDumper::Visit(const CXXCtorInitializer *Init) {
341   OS << "CXXCtorInitializer";
342   if (Init->isAnyMemberInitializer()) {
343     OS << ' ';
344     dumpBareDeclRef(Init->getAnyMember());
345   } else if (Init->isBaseInitializer()) {
346     dumpType(QualType(Init->getBaseClass(), 0));
347   } else if (Init->isDelegatingInitializer()) {
348     dumpType(Init->getTypeSourceInfo()->getType());
349   } else {
350     llvm_unreachable("Unknown initializer type");
351   }
352 }
353 
354 void TextNodeDumper::Visit(const BlockDecl::Capture &C) {
355   OS << "capture";
356   if (C.isByRef())
357     OS << " byref";
358   if (C.isNested())
359     OS << " nested";
360   if (C.getVariable()) {
361     OS << ' ';
362     dumpBareDeclRef(C.getVariable());
363   }
364 }
365 
366 void TextNodeDumper::Visit(const OMPClause *C) {
367   if (!C) {
368     ColorScope Color(OS, ShowColors, NullColor);
369     OS << "<<<NULL>>> OMPClause";
370     return;
371   }
372   {
373     ColorScope Color(OS, ShowColors, AttrColor);
374     StringRef ClauseName(llvm::omp::getOpenMPClauseName(C->getClauseKind()));
375     OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
376        << ClauseName.drop_front() << "Clause";
377   }
378   dumpPointer(C);
379   dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
380   if (C->isImplicit())
381     OS << " <implicit>";
382 }
383 
384 void TextNodeDumper::VisitOpenACCAsteriskSizeExpr(
385     const OpenACCAsteriskSizeExpr *E) {
386   // Nothing to do here, only location exists, and that is printed elsewhere.
387 }
388 
389 void TextNodeDumper::Visit(const OpenACCClause *C) {
390   if (!C) {
391     ColorScope Color(OS, ShowColors, NullColor);
392     OS << "<<<NULL>>> OpenACCClause";
393     return;
394   }
395   {
396     ColorScope Color(OS, ShowColors, AttrColor);
397     OS << C->getClauseKind();
398 
399     // Handle clauses with parens for types that have no children, likely
400     // because there is no sub expression.
401     switch (C->getClauseKind()) {
402     case OpenACCClauseKind::Default:
403       OS << '(' << cast<OpenACCDefaultClause>(C)->getDefaultClauseKind() << ')';
404       break;
405     case OpenACCClauseKind::Async:
406     case OpenACCClauseKind::Auto:
407     case OpenACCClauseKind::Attach:
408     case OpenACCClauseKind::Copy:
409     case OpenACCClauseKind::PCopy:
410     case OpenACCClauseKind::PresentOrCopy:
411     case OpenACCClauseKind::Host:
412     case OpenACCClauseKind::If:
413     case OpenACCClauseKind::IfPresent:
414     case OpenACCClauseKind::Independent:
415     case OpenACCClauseKind::Detach:
416     case OpenACCClauseKind::Delete:
417     case OpenACCClauseKind::Device:
418     case OpenACCClauseKind::DeviceNum:
419     case OpenACCClauseKind::DefaultAsync:
420     case OpenACCClauseKind::DevicePtr:
421     case OpenACCClauseKind::Finalize:
422     case OpenACCClauseKind::FirstPrivate:
423     case OpenACCClauseKind::NoCreate:
424     case OpenACCClauseKind::NumGangs:
425     case OpenACCClauseKind::NumWorkers:
426     case OpenACCClauseKind::Present:
427     case OpenACCClauseKind::Private:
428     case OpenACCClauseKind::Self:
429     case OpenACCClauseKind::Seq:
430     case OpenACCClauseKind::Tile:
431     case OpenACCClauseKind::Worker:
432     case OpenACCClauseKind::UseDevice:
433     case OpenACCClauseKind::Vector:
434     case OpenACCClauseKind::VectorLength:
435       // The condition expression will be printed as a part of the 'children',
436       // but print 'clause' here so it is clear what is happening from the dump.
437       OS << " clause";
438       break;
439     case OpenACCClauseKind::Gang: {
440       OS << " clause";
441       // print the list of all GangKinds, so that there is some sort of
442       // relationship to the expressions listed afterwards.
443       auto *GC = cast<OpenACCGangClause>(C);
444 
445       for (unsigned I = 0; I < GC->getNumExprs(); ++I) {
446         OS << " " << GC->getExpr(I).first;
447       }
448       break;
449     }
450     case OpenACCClauseKind::Collapse:
451       OS << " clause";
452       if (cast<OpenACCCollapseClause>(C)->hasForce())
453         OS << ": force";
454       break;
455 
456     case OpenACCClauseKind::CopyIn:
457     case OpenACCClauseKind::PCopyIn:
458     case OpenACCClauseKind::PresentOrCopyIn:
459       OS << " clause";
460       if (cast<OpenACCCopyInClause>(C)->isReadOnly())
461         OS << " : readonly";
462       break;
463     case OpenACCClauseKind::CopyOut:
464     case OpenACCClauseKind::PCopyOut:
465     case OpenACCClauseKind::PresentOrCopyOut:
466       OS << " clause";
467       if (cast<OpenACCCopyOutClause>(C)->isZero())
468         OS << " : zero";
469       break;
470     case OpenACCClauseKind::Create:
471     case OpenACCClauseKind::PCreate:
472     case OpenACCClauseKind::PresentOrCreate:
473       OS << " clause";
474       if (cast<OpenACCCreateClause>(C)->isZero())
475         OS << " : zero";
476       break;
477     case OpenACCClauseKind::Wait:
478       OS << " clause";
479       if (cast<OpenACCWaitClause>(C)->hasDevNumExpr())
480         OS << " has devnum";
481       if (cast<OpenACCWaitClause>(C)->hasQueuesTag())
482         OS << " has queues tag";
483       break;
484     case OpenACCClauseKind::DeviceType:
485     case OpenACCClauseKind::DType:
486       OS << "(";
487       llvm::interleaveComma(
488           cast<OpenACCDeviceTypeClause>(C)->getArchitectures(), OS,
489           [&](const DeviceTypeArgument &Arch) {
490             if (Arch.first == nullptr)
491               OS << "*";
492             else
493               OS << Arch.first->getName();
494           });
495       OS << ")";
496       break;
497     case OpenACCClauseKind::Reduction:
498       OS << " clause Operator: "
499          << cast<OpenACCReductionClause>(C)->getReductionOp();
500       break;
501     default:
502       // Nothing to do here.
503       break;
504     }
505   }
506   dumpPointer(C);
507   dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
508 }
509 
510 void TextNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) {
511   const TypeSourceInfo *TSI = A.getTypeSourceInfo();
512   if (TSI) {
513     OS << "case ";
514     dumpType(TSI->getType());
515   } else {
516     OS << "default";
517   }
518 
519   if (A.isSelected())
520     OS << " selected";
521 }
522 
523 void TextNodeDumper::Visit(const ConceptReference *R) {
524   if (!R) {
525     ColorScope Color(OS, ShowColors, NullColor);
526     OS << "<<<NULL>>> ConceptReference";
527     return;
528   }
529 
530   OS << "ConceptReference";
531   dumpPointer(R);
532   dumpSourceRange(R->getSourceRange());
533   OS << ' ';
534   dumpBareDeclRef(R->getNamedConcept());
535 }
536 
537 void TextNodeDumper::Visit(const concepts::Requirement *R) {
538   if (!R) {
539     ColorScope Color(OS, ShowColors, NullColor);
540     OS << "<<<NULL>>> Requirement";
541     return;
542   }
543 
544   {
545     ColorScope Color(OS, ShowColors, StmtColor);
546     switch (R->getKind()) {
547     case concepts::Requirement::RK_Type:
548       OS << "TypeRequirement";
549       break;
550     case concepts::Requirement::RK_Simple:
551       OS << "SimpleRequirement";
552       break;
553     case concepts::Requirement::RK_Compound:
554       OS << "CompoundRequirement";
555       break;
556     case concepts::Requirement::RK_Nested:
557       OS << "NestedRequirement";
558       break;
559     }
560   }
561 
562   dumpPointer(R);
563 
564   if (auto *ER = dyn_cast<concepts::ExprRequirement>(R)) {
565     if (ER->hasNoexceptRequirement())
566       OS << " noexcept";
567   }
568 
569   if (R->isDependent())
570     OS << " dependent";
571   else
572     OS << (R->isSatisfied() ? " satisfied" : " unsatisfied");
573   if (R->containsUnexpandedParameterPack())
574     OS << " contains_unexpanded_pack";
575 }
576 
577 static double GetApproxValue(const llvm::APFloat &F) {
578   llvm::APFloat V = F;
579   bool ignored;
580   V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven,
581             &ignored);
582   return V.convertToDouble();
583 }
584 
585 /// True if the \p APValue \p Value can be folded onto the current line.
586 static bool isSimpleAPValue(const APValue &Value) {
587   switch (Value.getKind()) {
588   case APValue::None:
589   case APValue::Indeterminate:
590   case APValue::Int:
591   case APValue::Float:
592   case APValue::FixedPoint:
593   case APValue::ComplexInt:
594   case APValue::ComplexFloat:
595   case APValue::LValue:
596   case APValue::MemberPointer:
597   case APValue::AddrLabelDiff:
598     return true;
599   case APValue::Vector:
600   case APValue::Array:
601   case APValue::Struct:
602     return false;
603   case APValue::Union:
604     return isSimpleAPValue(Value.getUnionValue());
605   }
606   llvm_unreachable("unexpected APValue kind!");
607 }
608 
609 /// Dump the children of the \p APValue \p Value.
610 ///
611 /// \param[in] Value          The \p APValue to visit
612 /// \param[in] Ty             The \p QualType passed to \p Visit
613 ///
614 /// \param[in] IdxToChildFun  A function mapping an \p APValue and an index
615 ///                           to one of the child of the \p APValue
616 ///
617 /// \param[in] NumChildren    \p IdxToChildFun will be called on \p Value with
618 ///                           the indices in the range \p [0,NumChildren(
619 ///
620 /// \param[in] LabelSingular  The label to use on a line with a single child
621 /// \param[in] LabelPlurial   The label to use on a line with multiple children
622 void TextNodeDumper::dumpAPValueChildren(
623     const APValue &Value, QualType Ty,
624     const APValue &(*IdxToChildFun)(const APValue &, unsigned),
625     unsigned NumChildren, StringRef LabelSingular, StringRef LabelPlurial) {
626   // To save some vertical space we print up to MaxChildrenPerLine APValues
627   // considered to be simple (by isSimpleAPValue) on a single line.
628   constexpr unsigned MaxChildrenPerLine = 4;
629   unsigned I = 0;
630   while (I < NumChildren) {
631     unsigned J = I;
632     while (J < NumChildren) {
633       if (isSimpleAPValue(IdxToChildFun(Value, J)) &&
634           (J - I < MaxChildrenPerLine)) {
635         ++J;
636         continue;
637       }
638       break;
639     }
640 
641     J = std::max(I + 1, J);
642 
643     // Print [I,J) on a single line.
644     AddChild(J - I > 1 ? LabelPlurial : LabelSingular, [=]() {
645       for (unsigned X = I; X < J; ++X) {
646         Visit(IdxToChildFun(Value, X), Ty);
647         if (X + 1 != J)
648           OS << ", ";
649       }
650     });
651     I = J;
652   }
653 }
654 
655 void TextNodeDumper::Visit(const APValue &Value, QualType Ty) {
656   ColorScope Color(OS, ShowColors, ValueKindColor);
657   switch (Value.getKind()) {
658   case APValue::None:
659     OS << "None";
660     return;
661   case APValue::Indeterminate:
662     OS << "Indeterminate";
663     return;
664   case APValue::Int:
665     OS << "Int ";
666     {
667       ColorScope Color(OS, ShowColors, ValueColor);
668       OS << Value.getInt();
669     }
670     return;
671   case APValue::Float:
672     OS << "Float ";
673     {
674       ColorScope Color(OS, ShowColors, ValueColor);
675       OS << GetApproxValue(Value.getFloat());
676     }
677     return;
678   case APValue::FixedPoint:
679     OS << "FixedPoint ";
680     {
681       ColorScope Color(OS, ShowColors, ValueColor);
682       OS << Value.getFixedPoint();
683     }
684     return;
685   case APValue::Vector: {
686     unsigned VectorLength = Value.getVectorLength();
687     OS << "Vector length=" << VectorLength;
688 
689     dumpAPValueChildren(
690         Value, Ty,
691         [](const APValue &Value, unsigned Index) -> const APValue & {
692           return Value.getVectorElt(Index);
693         },
694         VectorLength, "element", "elements");
695     return;
696   }
697   case APValue::ComplexInt:
698     OS << "ComplexInt ";
699     {
700       ColorScope Color(OS, ShowColors, ValueColor);
701       OS << Value.getComplexIntReal() << " + " << Value.getComplexIntImag()
702          << 'i';
703     }
704     return;
705   case APValue::ComplexFloat:
706     OS << "ComplexFloat ";
707     {
708       ColorScope Color(OS, ShowColors, ValueColor);
709       OS << GetApproxValue(Value.getComplexFloatReal()) << " + "
710          << GetApproxValue(Value.getComplexFloatImag()) << 'i';
711     }
712     return;
713   case APValue::LValue: {
714     (void)Context;
715     OS << "LValue Base=";
716     APValue::LValueBase B = Value.getLValueBase();
717     if (B.isNull())
718       OS << "null";
719     else if (const auto *BE = B.dyn_cast<const Expr *>()) {
720       OS << BE->getStmtClassName() << ' ';
721       dumpPointer(BE);
722     } else {
723       const auto *VDB = B.get<const ValueDecl *>();
724       OS << VDB->getDeclKindName() << "Decl";
725       dumpPointer(VDB);
726     }
727     OS << ", Null=" << Value.isNullPointer()
728        << ", Offset=" << Value.getLValueOffset().getQuantity()
729        << ", HasPath=" << Value.hasLValuePath();
730     if (Value.hasLValuePath()) {
731       OS << ", PathLength=" << Value.getLValuePath().size();
732       OS << ", Path=(";
733       llvm::ListSeparator Sep;
734       for (const auto &PathEntry : Value.getLValuePath()) {
735         // We're printing all entries as array indices because don't have the
736         // type information here to do anything else.
737         OS << Sep << PathEntry.getAsArrayIndex();
738       }
739       OS << ")";
740     }
741     return;
742   }
743   case APValue::Array: {
744     unsigned ArraySize = Value.getArraySize();
745     unsigned NumInitializedElements = Value.getArrayInitializedElts();
746     OS << "Array size=" << ArraySize;
747 
748     dumpAPValueChildren(
749         Value, Ty,
750         [](const APValue &Value, unsigned Index) -> const APValue & {
751           return Value.getArrayInitializedElt(Index);
752         },
753         NumInitializedElements, "element", "elements");
754 
755     if (Value.hasArrayFiller()) {
756       AddChild("filler", [=] {
757         {
758           ColorScope Color(OS, ShowColors, ValueColor);
759           OS << ArraySize - NumInitializedElements << " x ";
760         }
761         Visit(Value.getArrayFiller(), Ty);
762       });
763     }
764 
765     return;
766   }
767   case APValue::Struct: {
768     OS << "Struct";
769 
770     dumpAPValueChildren(
771         Value, Ty,
772         [](const APValue &Value, unsigned Index) -> const APValue & {
773           return Value.getStructBase(Index);
774         },
775         Value.getStructNumBases(), "base", "bases");
776 
777     dumpAPValueChildren(
778         Value, Ty,
779         [](const APValue &Value, unsigned Index) -> const APValue & {
780           return Value.getStructField(Index);
781         },
782         Value.getStructNumFields(), "field", "fields");
783 
784     return;
785   }
786   case APValue::Union: {
787     OS << "Union";
788     {
789       ColorScope Color(OS, ShowColors, ValueColor);
790       if (const FieldDecl *FD = Value.getUnionField())
791         OS << " ." << *cast<NamedDecl>(FD);
792     }
793     // If the union value is considered to be simple, fold it into the
794     // current line to save some vertical space.
795     const APValue &UnionValue = Value.getUnionValue();
796     if (isSimpleAPValue(UnionValue)) {
797       OS << ' ';
798       Visit(UnionValue, Ty);
799     } else {
800       AddChild([=] { Visit(UnionValue, Ty); });
801     }
802 
803     return;
804   }
805   case APValue::MemberPointer:
806     OS << "MemberPointer <todo>";
807     return;
808   case APValue::AddrLabelDiff:
809     OS << "AddrLabelDiff <todo>";
810     return;
811   }
812   llvm_unreachable("Unknown APValue kind!");
813 }
814 
815 void TextNodeDumper::dumpPointer(const void *Ptr) {
816   ColorScope Color(OS, ShowColors, AddressColor);
817   OS << ' ' << Ptr;
818 }
819 
820 void TextNodeDumper::dumpLocation(SourceLocation Loc) {
821   if (!SM)
822     return;
823 
824   ColorScope Color(OS, ShowColors, LocationColor);
825   SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
826 
827   // The general format we print out is filename:line:col, but we drop pieces
828   // that haven't changed since the last loc printed.
829   PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
830 
831   if (PLoc.isInvalid()) {
832     OS << "<invalid sloc>";
833     return;
834   }
835 
836   if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
837     OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':'
838        << PLoc.getColumn();
839     LastLocFilename = PLoc.getFilename();
840     LastLocLine = PLoc.getLine();
841   } else if (PLoc.getLine() != LastLocLine) {
842     OS << "line" << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
843     LastLocLine = PLoc.getLine();
844   } else {
845     OS << "col" << ':' << PLoc.getColumn();
846   }
847 }
848 
849 void TextNodeDumper::dumpSourceRange(SourceRange R) {
850   // Can't translate locations if a SourceManager isn't available.
851   if (!SM)
852     return;
853 
854   OS << " <";
855   dumpLocation(R.getBegin());
856   if (R.getBegin() != R.getEnd()) {
857     OS << ", ";
858     dumpLocation(R.getEnd());
859   }
860   OS << ">";
861 
862   // <t2.c:123:421[blah], t2.c:412:321>
863 }
864 
865 void TextNodeDumper::dumpBareType(QualType T, bool Desugar) {
866   ColorScope Color(OS, ShowColors, TypeColor);
867 
868   SplitQualType T_split = T.split();
869   std::string T_str = QualType::getAsString(T_split, PrintPolicy);
870   OS << "'" << T_str << "'";
871 
872   if (Desugar && !T.isNull()) {
873     // If the type is sugared, also dump a (shallow) desugared type when
874     // it is visibly different.
875     SplitQualType D_split = T.getSplitDesugaredType();
876     if (T_split != D_split) {
877       std::string D_str = QualType::getAsString(D_split, PrintPolicy);
878       if (T_str != D_str)
879         OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'";
880     }
881   }
882 }
883 
884 void TextNodeDumper::dumpType(QualType T) {
885   OS << ' ';
886   dumpBareType(T);
887 }
888 
889 void TextNodeDumper::dumpBareDeclRef(const Decl *D) {
890   if (!D) {
891     ColorScope Color(OS, ShowColors, NullColor);
892     OS << "<<<NULL>>>";
893     return;
894   }
895 
896   {
897     ColorScope Color(OS, ShowColors, DeclKindNameColor);
898     OS << D->getDeclKindName();
899   }
900   dumpPointer(D);
901 
902   if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
903     ColorScope Color(OS, ShowColors, DeclNameColor);
904     if (DeclarationName Name = ND->getDeclName())
905       OS << " '" << Name << '\'';
906     else
907       switch (ND->getKind()) {
908       case Decl::Decomposition: {
909         auto *DD = cast<DecompositionDecl>(ND);
910         OS << " first_binding '" << DD->bindings()[0]->getDeclName() << '\'';
911         break;
912       }
913       case Decl::Field: {
914         auto *FD = cast<FieldDecl>(ND);
915         OS << " field_index " << FD->getFieldIndex();
916         break;
917       }
918       case Decl::ParmVar: {
919         auto *PD = cast<ParmVarDecl>(ND);
920         OS << " depth " << PD->getFunctionScopeDepth() << " index "
921            << PD->getFunctionScopeIndex();
922         break;
923       }
924       case Decl::TemplateTypeParm: {
925         auto *TD = cast<TemplateTypeParmDecl>(ND);
926         OS << " depth " << TD->getDepth() << " index " << TD->getIndex();
927         break;
928       }
929       case Decl::NonTypeTemplateParm: {
930         auto *TD = cast<NonTypeTemplateParmDecl>(ND);
931         OS << " depth " << TD->getDepth() << " index " << TD->getIndex();
932         break;
933       }
934       default:
935         // Var, Namespace, (CXX)Record: Nothing else besides source location.
936         dumpSourceRange(ND->getSourceRange());
937         break;
938       }
939   }
940 
941   if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
942     dumpType(VD->getType());
943 }
944 
945 void TextNodeDumper::dumpName(const NamedDecl *ND) {
946   if (ND->getDeclName()) {
947     ColorScope Color(OS, ShowColors, DeclNameColor);
948     OS << ' ' << ND->getDeclName();
949   }
950 }
951 
952 void TextNodeDumper::dumpAccessSpecifier(AccessSpecifier AS) {
953   const auto AccessSpelling = getAccessSpelling(AS);
954   if (AccessSpelling.empty())
955     return;
956   OS << AccessSpelling;
957 }
958 
959 void TextNodeDumper::dumpCleanupObject(
960     const ExprWithCleanups::CleanupObject &C) {
961   if (auto *BD = C.dyn_cast<BlockDecl *>())
962     dumpDeclRef(BD, "cleanup");
963   else if (auto *CLE = C.dyn_cast<CompoundLiteralExpr *>())
964     AddChild([=] {
965       OS << "cleanup ";
966       {
967         ColorScope Color(OS, ShowColors, StmtColor);
968         OS << CLE->getStmtClassName();
969       }
970       dumpPointer(CLE);
971     });
972   else
973     llvm_unreachable("unexpected cleanup type");
974 }
975 
976 void clang::TextNodeDumper::dumpTemplateSpecializationKind(
977     TemplateSpecializationKind TSK) {
978   switch (TSK) {
979   case TSK_Undeclared:
980     break;
981   case TSK_ImplicitInstantiation:
982     OS << " implicit_instantiation";
983     break;
984   case TSK_ExplicitSpecialization:
985     OS << " explicit_specialization";
986     break;
987   case TSK_ExplicitInstantiationDeclaration:
988     OS << " explicit_instantiation_declaration";
989     break;
990   case TSK_ExplicitInstantiationDefinition:
991     OS << " explicit_instantiation_definition";
992     break;
993   }
994 }
995 
996 void clang::TextNodeDumper::dumpNestedNameSpecifier(const NestedNameSpecifier *NNS) {
997   if (!NNS)
998     return;
999 
1000   AddChild([=] {
1001     OS << "NestedNameSpecifier";
1002 
1003     switch (NNS->getKind()) {
1004     case NestedNameSpecifier::Identifier:
1005       OS << " Identifier";
1006       OS << " '" << NNS->getAsIdentifier()->getName() << "'";
1007       break;
1008     case NestedNameSpecifier::Namespace:
1009       OS << " "; // "Namespace" is printed as the decl kind.
1010       dumpBareDeclRef(NNS->getAsNamespace());
1011       break;
1012     case NestedNameSpecifier::NamespaceAlias:
1013       OS << " "; // "NamespaceAlias" is printed as the decl kind.
1014       dumpBareDeclRef(NNS->getAsNamespaceAlias());
1015       break;
1016     case NestedNameSpecifier::TypeSpec:
1017       OS << " TypeSpec";
1018       dumpType(QualType(NNS->getAsType(), 0));
1019       break;
1020     case NestedNameSpecifier::TypeSpecWithTemplate:
1021       OS << " TypeSpecWithTemplate";
1022       dumpType(QualType(NNS->getAsType(), 0));
1023       break;
1024     case NestedNameSpecifier::Global:
1025       OS << " Global";
1026       break;
1027     case NestedNameSpecifier::Super:
1028       OS << " Super";
1029       break;
1030     }
1031 
1032     dumpNestedNameSpecifier(NNS->getPrefix());
1033   });
1034 }
1035 
1036 void TextNodeDumper::dumpDeclRef(const Decl *D, StringRef Label) {
1037   if (!D)
1038     return;
1039 
1040   AddChild([=] {
1041     if (!Label.empty())
1042       OS << Label << ' ';
1043     dumpBareDeclRef(D);
1044   });
1045 }
1046 
1047 void TextNodeDumper::dumpTemplateArgument(const TemplateArgument &TA) {
1048   llvm::SmallString<128> Str;
1049   {
1050     llvm::raw_svector_ostream SS(Str);
1051     TA.print(PrintPolicy, SS, /*IncludeType=*/true);
1052   }
1053   OS << " '" << Str << "'";
1054 
1055   if (!Context)
1056     return;
1057 
1058   if (TemplateArgument CanonTA = Context->getCanonicalTemplateArgument(TA);
1059       !CanonTA.structurallyEquals(TA)) {
1060     llvm::SmallString<128> CanonStr;
1061     {
1062       llvm::raw_svector_ostream SS(CanonStr);
1063       CanonTA.print(PrintPolicy, SS, /*IncludeType=*/true);
1064     }
1065     if (CanonStr != Str)
1066       OS << ":'" << CanonStr << "'";
1067   }
1068 }
1069 
1070 const char *TextNodeDumper::getCommandName(unsigned CommandID) {
1071   if (Traits)
1072     return Traits->getCommandInfo(CommandID)->Name;
1073   const comments::CommandInfo *Info =
1074       comments::CommandTraits::getBuiltinCommandInfo(CommandID);
1075   if (Info)
1076     return Info->Name;
1077   return "<not a builtin command>";
1078 }
1079 
1080 void TextNodeDumper::printFPOptions(FPOptionsOverride FPO) {
1081 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS)                                    \
1082   if (FPO.has##NAME##Override())                                               \
1083     OS << " " #NAME "=" << FPO.get##NAME##Override();
1084 #include "clang/Basic/FPOptions.def"
1085 }
1086 
1087 void TextNodeDumper::visitTextComment(const comments::TextComment *C,
1088                                       const comments::FullComment *) {
1089   OS << " Text=\"" << C->getText() << "\"";
1090 }
1091 
1092 void TextNodeDumper::visitInlineCommandComment(
1093     const comments::InlineCommandComment *C, const comments::FullComment *) {
1094   OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
1095   switch (C->getRenderKind()) {
1096   case comments::InlineCommandRenderKind::Normal:
1097     OS << " RenderNormal";
1098     break;
1099   case comments::InlineCommandRenderKind::Bold:
1100     OS << " RenderBold";
1101     break;
1102   case comments::InlineCommandRenderKind::Monospaced:
1103     OS << " RenderMonospaced";
1104     break;
1105   case comments::InlineCommandRenderKind::Emphasized:
1106     OS << " RenderEmphasized";
1107     break;
1108   case comments::InlineCommandRenderKind::Anchor:
1109     OS << " RenderAnchor";
1110     break;
1111   }
1112 
1113   for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
1114     OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
1115 }
1116 
1117 void TextNodeDumper::visitHTMLStartTagComment(
1118     const comments::HTMLStartTagComment *C, const comments::FullComment *) {
1119   OS << " Name=\"" << C->getTagName() << "\"";
1120   if (C->getNumAttrs() != 0) {
1121     OS << " Attrs: ";
1122     for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
1123       const comments::HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
1124       OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
1125     }
1126   }
1127   if (C->isSelfClosing())
1128     OS << " SelfClosing";
1129 }
1130 
1131 void TextNodeDumper::visitHTMLEndTagComment(
1132     const comments::HTMLEndTagComment *C, const comments::FullComment *) {
1133   OS << " Name=\"" << C->getTagName() << "\"";
1134 }
1135 
1136 void TextNodeDumper::visitBlockCommandComment(
1137     const comments::BlockCommandComment *C, const comments::FullComment *) {
1138   OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
1139   for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
1140     OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
1141 }
1142 
1143 void TextNodeDumper::visitParamCommandComment(
1144     const comments::ParamCommandComment *C, const comments::FullComment *FC) {
1145   OS << " "
1146      << comments::ParamCommandComment::getDirectionAsString(C->getDirection());
1147 
1148   if (C->isDirectionExplicit())
1149     OS << " explicitly";
1150   else
1151     OS << " implicitly";
1152 
1153   if (C->hasParamName()) {
1154     if (C->isParamIndexValid())
1155       OS << " Param=\"" << C->getParamName(FC) << "\"";
1156     else
1157       OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
1158   }
1159 
1160   if (C->isParamIndexValid() && !C->isVarArgParam())
1161     OS << " ParamIndex=" << C->getParamIndex();
1162 }
1163 
1164 void TextNodeDumper::visitTParamCommandComment(
1165     const comments::TParamCommandComment *C, const comments::FullComment *FC) {
1166   if (C->hasParamName()) {
1167     if (C->isPositionValid())
1168       OS << " Param=\"" << C->getParamName(FC) << "\"";
1169     else
1170       OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
1171   }
1172 
1173   if (C->isPositionValid()) {
1174     OS << " Position=<";
1175     for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
1176       OS << C->getIndex(i);
1177       if (i != e - 1)
1178         OS << ", ";
1179     }
1180     OS << ">";
1181   }
1182 }
1183 
1184 void TextNodeDumper::visitVerbatimBlockComment(
1185     const comments::VerbatimBlockComment *C, const comments::FullComment *) {
1186   OS << " Name=\"" << getCommandName(C->getCommandID())
1187      << "\""
1188         " CloseName=\""
1189      << C->getCloseName() << "\"";
1190 }
1191 
1192 void TextNodeDumper::visitVerbatimBlockLineComment(
1193     const comments::VerbatimBlockLineComment *C,
1194     const comments::FullComment *) {
1195   OS << " Text=\"" << C->getText() << "\"";
1196 }
1197 
1198 void TextNodeDumper::visitVerbatimLineComment(
1199     const comments::VerbatimLineComment *C, const comments::FullComment *) {
1200   OS << " Text=\"" << C->getText() << "\"";
1201 }
1202 
1203 void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument &) {
1204   OS << " null";
1205 }
1206 
1207 void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) {
1208   OS << " type";
1209   dumpTemplateArgument(TA);
1210 }
1211 
1212 void TextNodeDumper::VisitDeclarationTemplateArgument(
1213     const TemplateArgument &TA) {
1214   OS << " decl";
1215   dumpTemplateArgument(TA);
1216   dumpDeclRef(TA.getAsDecl());
1217 }
1218 
1219 void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &TA) {
1220   OS << " nullptr";
1221   dumpTemplateArgument(TA);
1222 }
1223 
1224 void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) {
1225   OS << " integral";
1226   dumpTemplateArgument(TA);
1227 }
1228 
1229 void TextNodeDumper::dumpTemplateName(TemplateName TN, StringRef Label) {
1230   AddChild(Label, [=] {
1231     {
1232       llvm::SmallString<128> Str;
1233       {
1234         llvm::raw_svector_ostream SS(Str);
1235         TN.print(SS, PrintPolicy);
1236       }
1237       OS << "'" << Str << "'";
1238 
1239       if (Context) {
1240         if (TemplateName CanonTN = Context->getCanonicalTemplateName(TN);
1241             CanonTN != TN) {
1242           llvm::SmallString<128> CanonStr;
1243           {
1244             llvm::raw_svector_ostream SS(CanonStr);
1245             CanonTN.print(SS, PrintPolicy);
1246           }
1247           if (CanonStr != Str)
1248             OS << ":'" << CanonStr << "'";
1249         }
1250       }
1251     }
1252     dumpBareTemplateName(TN);
1253   });
1254 }
1255 
1256 void TextNodeDumper::dumpBareTemplateName(TemplateName TN) {
1257   switch (TN.getKind()) {
1258   case TemplateName::Template:
1259     AddChild([=] { Visit(TN.getAsTemplateDecl()); });
1260     return;
1261   case TemplateName::UsingTemplate: {
1262     const UsingShadowDecl *USD = TN.getAsUsingShadowDecl();
1263     AddChild([=] { Visit(USD); });
1264     AddChild("target", [=] { Visit(USD->getTargetDecl()); });
1265     return;
1266   }
1267   case TemplateName::QualifiedTemplate: {
1268     OS << " qualified";
1269     const QualifiedTemplateName *QTN = TN.getAsQualifiedTemplateName();
1270     if (QTN->hasTemplateKeyword())
1271       OS << " keyword";
1272     dumpNestedNameSpecifier(QTN->getQualifier());
1273     dumpBareTemplateName(QTN->getUnderlyingTemplate());
1274     return;
1275   }
1276   case TemplateName::DependentTemplate: {
1277     OS << " dependent";
1278     const DependentTemplateName *DTN = TN.getAsDependentTemplateName();
1279     dumpNestedNameSpecifier(DTN->getQualifier());
1280     return;
1281   }
1282   case TemplateName::SubstTemplateTemplateParm: {
1283     OS << " subst";
1284     const SubstTemplateTemplateParmStorage *STS =
1285         TN.getAsSubstTemplateTemplateParm();
1286     OS << " index " << STS->getIndex();
1287     if (std::optional<unsigned int> PackIndex = STS->getPackIndex())
1288       OS << " pack_index " << *PackIndex;
1289     if (const TemplateTemplateParmDecl *P = STS->getParameter())
1290       AddChild("parameter", [=] { Visit(P); });
1291     dumpDeclRef(STS->getAssociatedDecl(), "associated");
1292     dumpTemplateName(STS->getReplacement(), "replacement");
1293     return;
1294   }
1295   case TemplateName::DeducedTemplate: {
1296     OS << " deduced";
1297     const DeducedTemplateStorage *DTS = TN.getAsDeducedTemplateName();
1298     dumpTemplateName(DTS->getUnderlying(), "underlying");
1299     AddChild("defaults", [=] {
1300       auto [StartPos, Args] = DTS->getDefaultArguments();
1301       OS << " start " << StartPos;
1302       for (const TemplateArgument &Arg : Args)
1303         AddChild([=] { Visit(Arg, SourceRange()); });
1304     });
1305     return;
1306   }
1307   // FIXME: Implement these.
1308   case TemplateName::OverloadedTemplate:
1309     OS << " overloaded";
1310     return;
1311   case TemplateName::AssumedTemplate:
1312     OS << " assumed";
1313     return;
1314   case TemplateName::SubstTemplateTemplateParmPack:
1315     OS << " subst_pack";
1316     return;
1317   }
1318   llvm_unreachable("Unexpected TemplateName Kind");
1319 }
1320 
1321 void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) {
1322   OS << " template";
1323   dumpTemplateArgument(TA);
1324   dumpBareTemplateName(TA.getAsTemplate());
1325 }
1326 
1327 void TextNodeDumper::VisitTemplateExpansionTemplateArgument(
1328     const TemplateArgument &TA) {
1329   OS << " template expansion";
1330   dumpTemplateArgument(TA);
1331   dumpBareTemplateName(TA.getAsTemplateOrTemplatePattern());
1332 }
1333 
1334 void TextNodeDumper::VisitExpressionTemplateArgument(
1335     const TemplateArgument &TA) {
1336   OS << " expr";
1337   dumpTemplateArgument(TA);
1338 }
1339 
1340 void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &TA) {
1341   OS << " pack";
1342   dumpTemplateArgument(TA);
1343 }
1344 
1345 static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
1346   if (Node->path_empty())
1347     return;
1348 
1349   OS << " (";
1350   bool First = true;
1351   for (CastExpr::path_const_iterator I = Node->path_begin(),
1352                                      E = Node->path_end();
1353        I != E; ++I) {
1354     const CXXBaseSpecifier *Base = *I;
1355     if (!First)
1356       OS << " -> ";
1357 
1358     const auto *RD =
1359         cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl());
1360 
1361     if (Base->isVirtual())
1362       OS << "virtual ";
1363     OS << RD->getName();
1364     First = false;
1365   }
1366 
1367   OS << ')';
1368 }
1369 
1370 void TextNodeDumper::VisitIfStmt(const IfStmt *Node) {
1371   if (Node->hasInitStorage())
1372     OS << " has_init";
1373   if (Node->hasVarStorage())
1374     OS << " has_var";
1375   if (Node->hasElseStorage())
1376     OS << " has_else";
1377   if (Node->isConstexpr())
1378     OS << " constexpr";
1379   if (Node->isConsteval()) {
1380     OS << " ";
1381     if (Node->isNegatedConsteval())
1382       OS << "!";
1383     OS << "consteval";
1384   }
1385 }
1386 
1387 void TextNodeDumper::VisitSwitchStmt(const SwitchStmt *Node) {
1388   if (Node->hasInitStorage())
1389     OS << " has_init";
1390   if (Node->hasVarStorage())
1391     OS << " has_var";
1392 }
1393 
1394 void TextNodeDumper::VisitWhileStmt(const WhileStmt *Node) {
1395   if (Node->hasVarStorage())
1396     OS << " has_var";
1397 }
1398 
1399 void TextNodeDumper::VisitLabelStmt(const LabelStmt *Node) {
1400   OS << " '" << Node->getName() << "'";
1401   if (Node->isSideEntry())
1402     OS << " side_entry";
1403 }
1404 
1405 void TextNodeDumper::VisitGotoStmt(const GotoStmt *Node) {
1406   OS << " '" << Node->getLabel()->getName() << "'";
1407   dumpPointer(Node->getLabel());
1408 }
1409 
1410 void TextNodeDumper::VisitCaseStmt(const CaseStmt *Node) {
1411   if (Node->caseStmtIsGNURange())
1412     OS << " gnu_range";
1413 }
1414 
1415 void clang::TextNodeDumper::VisitReturnStmt(const ReturnStmt *Node) {
1416   if (const VarDecl *Cand = Node->getNRVOCandidate()) {
1417     OS << " nrvo_candidate(";
1418     dumpBareDeclRef(Cand);
1419     OS << ")";
1420   }
1421 }
1422 
1423 void clang::TextNodeDumper::VisitCoawaitExpr(const CoawaitExpr *Node) {
1424   if (Node->isImplicit())
1425     OS << " implicit";
1426 }
1427 
1428 void clang::TextNodeDumper::VisitCoreturnStmt(const CoreturnStmt *Node) {
1429   if (Node->isImplicit())
1430     OS << " implicit";
1431 }
1432 
1433 void TextNodeDumper::VisitConstantExpr(const ConstantExpr *Node) {
1434   if (Node->hasAPValueResult())
1435     AddChild("value",
1436              [=] { Visit(Node->getAPValueResult(), Node->getType()); });
1437 }
1438 
1439 void TextNodeDumper::VisitCallExpr(const CallExpr *Node) {
1440   if (Node->usesADL())
1441     OS << " adl";
1442   if (Node->hasStoredFPFeatures())
1443     printFPOptions(Node->getFPFeatures());
1444 }
1445 
1446 void TextNodeDumper::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *Node) {
1447   const char *OperatorSpelling = clang::getOperatorSpelling(Node->getOperator());
1448   if (OperatorSpelling)
1449     OS << " '" << OperatorSpelling << "'";
1450 
1451   VisitCallExpr(Node);
1452 }
1453 
1454 void TextNodeDumper::VisitCastExpr(const CastExpr *Node) {
1455   OS << " <";
1456   {
1457     ColorScope Color(OS, ShowColors, CastColor);
1458     OS << Node->getCastKindName();
1459   }
1460   dumpBasePath(OS, Node);
1461   OS << ">";
1462   if (Node->hasStoredFPFeatures())
1463     printFPOptions(Node->getFPFeatures());
1464 }
1465 
1466 void TextNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) {
1467   VisitCastExpr(Node);
1468   if (Node->isPartOfExplicitCast())
1469     OS << " part_of_explicit_cast";
1470 }
1471 
1472 void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
1473   OS << " ";
1474   dumpBareDeclRef(Node->getDecl());
1475   dumpNestedNameSpecifier(Node->getQualifier());
1476   if (Node->getDecl() != Node->getFoundDecl()) {
1477     OS << " (";
1478     dumpBareDeclRef(Node->getFoundDecl());
1479     OS << ")";
1480   }
1481   switch (Node->isNonOdrUse()) {
1482   case NOUR_None: break;
1483   case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break;
1484   case NOUR_Constant: OS << " non_odr_use_constant"; break;
1485   case NOUR_Discarded: OS << " non_odr_use_discarded"; break;
1486   }
1487   if (Node->isCapturedByCopyInLambdaWithExplicitObjectParameter())
1488     OS << " dependent_capture";
1489   else if (Node->refersToEnclosingVariableOrCapture())
1490     OS << " refers_to_enclosing_variable_or_capture";
1491 
1492   if (Node->isImmediateEscalating())
1493     OS << " immediate-escalating";
1494 }
1495 
1496 void clang::TextNodeDumper::VisitDependentScopeDeclRefExpr(
1497     const DependentScopeDeclRefExpr *Node) {
1498 
1499   dumpNestedNameSpecifier(Node->getQualifier());
1500 }
1501 
1502 void TextNodeDumper::VisitUnresolvedLookupExpr(
1503     const UnresolvedLookupExpr *Node) {
1504   OS << " (";
1505   if (!Node->requiresADL())
1506     OS << "no ";
1507   OS << "ADL) = '" << Node->getName() << '\'';
1508 
1509   UnresolvedLookupExpr::decls_iterator I = Node->decls_begin(),
1510                                        E = Node->decls_end();
1511   if (I == E)
1512     OS << " empty";
1513   for (; I != E; ++I)
1514     dumpPointer(*I);
1515 }
1516 
1517 void TextNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) {
1518   {
1519     ColorScope Color(OS, ShowColors, DeclKindNameColor);
1520     OS << " " << Node->getDecl()->getDeclKindName() << "Decl";
1521   }
1522   OS << "='" << *Node->getDecl() << "'";
1523   dumpPointer(Node->getDecl());
1524   if (Node->isFreeIvar())
1525     OS << " isFreeIvar";
1526 }
1527 
1528 void TextNodeDumper::VisitSYCLUniqueStableNameExpr(
1529     const SYCLUniqueStableNameExpr *Node) {
1530   dumpType(Node->getTypeSourceInfo()->getType());
1531 }
1532 
1533 void TextNodeDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
1534   OS << " " << PredefinedExpr::getIdentKindName(Node->getIdentKind());
1535 }
1536 
1537 void TextNodeDumper::VisitCharacterLiteral(const CharacterLiteral *Node) {
1538   ColorScope Color(OS, ShowColors, ValueColor);
1539   OS << " " << Node->getValue();
1540 }
1541 
1542 void TextNodeDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
1543   bool isSigned = Node->getType()->isSignedIntegerType();
1544   ColorScope Color(OS, ShowColors, ValueColor);
1545   OS << " " << toString(Node->getValue(), 10, isSigned);
1546 }
1547 
1548 void TextNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *Node) {
1549   ColorScope Color(OS, ShowColors, ValueColor);
1550   OS << " " << Node->getValueAsString(/*Radix=*/10);
1551 }
1552 
1553 void TextNodeDumper::VisitFloatingLiteral(const FloatingLiteral *Node) {
1554   ColorScope Color(OS, ShowColors, ValueColor);
1555   OS << " " << Node->getValueAsApproximateDouble();
1556 }
1557 
1558 void TextNodeDumper::VisitStringLiteral(const StringLiteral *Str) {
1559   ColorScope Color(OS, ShowColors, ValueColor);
1560   OS << " ";
1561   Str->outputString(OS);
1562 }
1563 
1564 void TextNodeDumper::VisitInitListExpr(const InitListExpr *ILE) {
1565   if (auto *Field = ILE->getInitializedFieldInUnion()) {
1566     OS << " field ";
1567     dumpBareDeclRef(Field);
1568   }
1569 }
1570 
1571 void TextNodeDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
1572   if (E->isResultDependent())
1573     OS << " result_dependent";
1574 }
1575 
1576 void TextNodeDumper::VisitUnaryOperator(const UnaryOperator *Node) {
1577   OS << " " << (Node->isPostfix() ? "postfix" : "prefix") << " '"
1578      << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1579   if (!Node->canOverflow())
1580     OS << " cannot overflow";
1581   if (Node->hasStoredFPFeatures())
1582     printFPOptions(Node->getStoredFPFeatures());
1583 }
1584 
1585 void TextNodeDumper::VisitUnaryExprOrTypeTraitExpr(
1586     const UnaryExprOrTypeTraitExpr *Node) {
1587   OS << " " << getTraitSpelling(Node->getKind());
1588 
1589   if (Node->isArgumentType())
1590     dumpType(Node->getArgumentType());
1591 }
1592 
1593 void TextNodeDumper::VisitMemberExpr(const MemberExpr *Node) {
1594   OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl();
1595   dumpPointer(Node->getMemberDecl());
1596   dumpNestedNameSpecifier(Node->getQualifier());
1597   switch (Node->isNonOdrUse()) {
1598   case NOUR_None: break;
1599   case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break;
1600   case NOUR_Constant: OS << " non_odr_use_constant"; break;
1601   case NOUR_Discarded: OS << " non_odr_use_discarded"; break;
1602   }
1603 }
1604 
1605 void TextNodeDumper::VisitExtVectorElementExpr(
1606     const ExtVectorElementExpr *Node) {
1607   OS << " " << Node->getAccessor().getNameStart();
1608 }
1609 
1610 void TextNodeDumper::VisitBinaryOperator(const BinaryOperator *Node) {
1611   OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1612   if (Node->hasStoredFPFeatures())
1613     printFPOptions(Node->getStoredFPFeatures());
1614 }
1615 
1616 void TextNodeDumper::VisitCompoundAssignOperator(
1617     const CompoundAssignOperator *Node) {
1618   OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
1619      << "' ComputeLHSTy=";
1620   dumpBareType(Node->getComputationLHSType());
1621   OS << " ComputeResultTy=";
1622   dumpBareType(Node->getComputationResultType());
1623   if (Node->hasStoredFPFeatures())
1624     printFPOptions(Node->getStoredFPFeatures());
1625 }
1626 
1627 void TextNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) {
1628   OS << " " << Node->getLabel()->getName();
1629   dumpPointer(Node->getLabel());
1630 }
1631 
1632 void TextNodeDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) {
1633   OS << " " << Node->getCastName() << "<"
1634      << Node->getTypeAsWritten().getAsString() << ">"
1635      << " <" << Node->getCastKindName();
1636   dumpBasePath(OS, Node);
1637   OS << ">";
1638 }
1639 
1640 void TextNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
1641   OS << " " << (Node->getValue() ? "true" : "false");
1642 }
1643 
1644 void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
1645   if (Node->isImplicit())
1646     OS << " implicit";
1647   if (Node->isCapturedByCopyInLambdaWithExplicitObjectParameter())
1648     OS << " dependent_capture";
1649   OS << " this";
1650 }
1651 
1652 void TextNodeDumper::VisitCXXFunctionalCastExpr(
1653     const CXXFunctionalCastExpr *Node) {
1654   OS << " functional cast to " << Node->getTypeAsWritten().getAsString() << " <"
1655      << Node->getCastKindName() << ">";
1656   if (Node->hasStoredFPFeatures())
1657     printFPOptions(Node->getFPFeatures());
1658 }
1659 
1660 void TextNodeDumper::VisitCXXStaticCastExpr(const CXXStaticCastExpr *Node) {
1661   VisitCXXNamedCastExpr(Node);
1662   if (Node->hasStoredFPFeatures())
1663     printFPOptions(Node->getFPFeatures());
1664 }
1665 
1666 void TextNodeDumper::VisitCXXUnresolvedConstructExpr(
1667     const CXXUnresolvedConstructExpr *Node) {
1668   dumpType(Node->getTypeAsWritten());
1669   if (Node->isListInitialization())
1670     OS << " list";
1671 }
1672 
1673 void TextNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
1674   CXXConstructorDecl *Ctor = Node->getConstructor();
1675   dumpType(Ctor->getType());
1676   if (Node->isElidable())
1677     OS << " elidable";
1678   if (Node->isListInitialization())
1679     OS << " list";
1680   if (Node->isStdInitListInitialization())
1681     OS << " std::initializer_list";
1682   if (Node->requiresZeroInitialization())
1683     OS << " zeroing";
1684   if (Node->isImmediateEscalating())
1685     OS << " immediate-escalating";
1686 }
1687 
1688 void TextNodeDumper::VisitCXXBindTemporaryExpr(
1689     const CXXBindTemporaryExpr *Node) {
1690   OS << " (CXXTemporary";
1691   dumpPointer(Node);
1692   OS << ")";
1693 }
1694 
1695 void TextNodeDumper::VisitCXXNewExpr(const CXXNewExpr *Node) {
1696   if (Node->isGlobalNew())
1697     OS << " global";
1698   if (Node->isArray())
1699     OS << " array";
1700   if (Node->getOperatorNew()) {
1701     OS << ' ';
1702     dumpBareDeclRef(Node->getOperatorNew());
1703   }
1704   // We could dump the deallocation function used in case of error, but it's
1705   // usually not that interesting.
1706 }
1707 
1708 void TextNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *Node) {
1709   if (Node->isGlobalDelete())
1710     OS << " global";
1711   if (Node->isArrayForm())
1712     OS << " array";
1713   if (Node->getOperatorDelete()) {
1714     OS << ' ';
1715     dumpBareDeclRef(Node->getOperatorDelete());
1716   }
1717 }
1718 
1719 void TextNodeDumper::VisitTypeTraitExpr(const TypeTraitExpr *Node) {
1720   OS << " " << getTraitSpelling(Node->getTrait());
1721 }
1722 
1723 void TextNodeDumper::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *Node) {
1724   OS << " " << getTraitSpelling(Node->getTrait());
1725 }
1726 
1727 void TextNodeDumper::VisitExpressionTraitExpr(const ExpressionTraitExpr *Node) {
1728   OS << " " << getTraitSpelling(Node->getTrait());
1729 }
1730 
1731 void TextNodeDumper::VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *Node) {
1732   if (Node->hasRewrittenInit())
1733     OS << " has rewritten init";
1734 }
1735 
1736 void TextNodeDumper::VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *Node) {
1737   if (Node->hasRewrittenInit())
1738     OS << " has rewritten init";
1739 }
1740 
1741 void TextNodeDumper::VisitMaterializeTemporaryExpr(
1742     const MaterializeTemporaryExpr *Node) {
1743   if (const ValueDecl *VD = Node->getExtendingDecl()) {
1744     OS << " extended by ";
1745     dumpBareDeclRef(VD);
1746   }
1747 }
1748 
1749 void TextNodeDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) {
1750   for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
1751     dumpCleanupObject(Node->getObject(i));
1752 }
1753 
1754 void TextNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
1755   dumpPointer(Node->getPack());
1756   dumpName(Node->getPack());
1757 }
1758 
1759 void TextNodeDumper::VisitCXXDependentScopeMemberExpr(
1760     const CXXDependentScopeMemberExpr *Node) {
1761   OS << " " << (Node->isArrow() ? "->" : ".") << Node->getMember();
1762 }
1763 
1764 void TextNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
1765   OS << " selector=";
1766   Node->getSelector().print(OS);
1767   switch (Node->getReceiverKind()) {
1768   case ObjCMessageExpr::Instance:
1769     break;
1770 
1771   case ObjCMessageExpr::Class:
1772     OS << " class=";
1773     dumpBareType(Node->getClassReceiver());
1774     break;
1775 
1776   case ObjCMessageExpr::SuperInstance:
1777     OS << " super (instance)";
1778     break;
1779 
1780   case ObjCMessageExpr::SuperClass:
1781     OS << " super (class)";
1782     break;
1783   }
1784 }
1785 
1786 void TextNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
1787   if (auto *BoxingMethod = Node->getBoxingMethod()) {
1788     OS << " selector=";
1789     BoxingMethod->getSelector().print(OS);
1790   }
1791 }
1792 
1793 void TextNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
1794   if (!Node->getCatchParamDecl())
1795     OS << " catch all";
1796 }
1797 
1798 void TextNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
1799   dumpType(Node->getEncodedType());
1800 }
1801 
1802 void TextNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
1803   OS << " ";
1804   Node->getSelector().print(OS);
1805 }
1806 
1807 void TextNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
1808   OS << ' ' << *Node->getProtocol();
1809 }
1810 
1811 void TextNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) {
1812   if (Node->isImplicitProperty()) {
1813     OS << " Kind=MethodRef Getter=\"";
1814     if (Node->getImplicitPropertyGetter())
1815       Node->getImplicitPropertyGetter()->getSelector().print(OS);
1816     else
1817       OS << "(null)";
1818 
1819     OS << "\" Setter=\"";
1820     if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
1821       Setter->getSelector().print(OS);
1822     else
1823       OS << "(null)";
1824     OS << "\"";
1825   } else {
1826     OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty()
1827        << '"';
1828   }
1829 
1830   if (Node->isSuperReceiver())
1831     OS << " super";
1832 
1833   OS << " Messaging=";
1834   if (Node->isMessagingGetter() && Node->isMessagingSetter())
1835     OS << "Getter&Setter";
1836   else if (Node->isMessagingGetter())
1837     OS << "Getter";
1838   else if (Node->isMessagingSetter())
1839     OS << "Setter";
1840 }
1841 
1842 void TextNodeDumper::VisitObjCSubscriptRefExpr(
1843     const ObjCSubscriptRefExpr *Node) {
1844   if (Node->isArraySubscriptRefExpr())
1845     OS << " Kind=ArraySubscript GetterForArray=\"";
1846   else
1847     OS << " Kind=DictionarySubscript GetterForDictionary=\"";
1848   if (Node->getAtIndexMethodDecl())
1849     Node->getAtIndexMethodDecl()->getSelector().print(OS);
1850   else
1851     OS << "(null)";
1852 
1853   if (Node->isArraySubscriptRefExpr())
1854     OS << "\" SetterForArray=\"";
1855   else
1856     OS << "\" SetterForDictionary=\"";
1857   if (Node->setAtIndexMethodDecl())
1858     Node->setAtIndexMethodDecl()->getSelector().print(OS);
1859   else
1860     OS << "(null)";
1861 }
1862 
1863 void TextNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) {
1864   OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
1865 }
1866 
1867 void TextNodeDumper::VisitOMPIteratorExpr(const OMPIteratorExpr *Node) {
1868   OS << " ";
1869   for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) {
1870     Visit(Node->getIteratorDecl(I));
1871     OS << " = ";
1872     const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I);
1873     OS << " begin ";
1874     Visit(Range.Begin);
1875     OS << " end ";
1876     Visit(Range.End);
1877     if (Range.Step) {
1878       OS << " step ";
1879       Visit(Range.Step);
1880     }
1881   }
1882 }
1883 
1884 void TextNodeDumper::VisitConceptSpecializationExpr(
1885     const ConceptSpecializationExpr *Node) {
1886   OS << " ";
1887   dumpBareDeclRef(Node->getFoundDecl());
1888 }
1889 
1890 void TextNodeDumper::VisitRequiresExpr(
1891     const RequiresExpr *Node) {
1892   if (!Node->isValueDependent())
1893     OS << (Node->isSatisfied() ? " satisfied" : " unsatisfied");
1894 }
1895 
1896 void TextNodeDumper::VisitRValueReferenceType(const ReferenceType *T) {
1897   if (T->isSpelledAsLValue())
1898     OS << " written as lvalue reference";
1899 }
1900 
1901 void TextNodeDumper::VisitArrayType(const ArrayType *T) {
1902   switch (T->getSizeModifier()) {
1903   case ArraySizeModifier::Normal:
1904     break;
1905   case ArraySizeModifier::Static:
1906     OS << " static";
1907     break;
1908   case ArraySizeModifier::Star:
1909     OS << " *";
1910     break;
1911   }
1912   OS << " " << T->getIndexTypeQualifiers().getAsString();
1913 }
1914 
1915 void TextNodeDumper::VisitConstantArrayType(const ConstantArrayType *T) {
1916   OS << " " << T->getSize();
1917   VisitArrayType(T);
1918 }
1919 
1920 void TextNodeDumper::VisitVariableArrayType(const VariableArrayType *T) {
1921   OS << " ";
1922   dumpSourceRange(T->getBracketsRange());
1923   VisitArrayType(T);
1924 }
1925 
1926 void TextNodeDumper::VisitDependentSizedArrayType(
1927     const DependentSizedArrayType *T) {
1928   VisitArrayType(T);
1929   OS << " ";
1930   dumpSourceRange(T->getBracketsRange());
1931 }
1932 
1933 void TextNodeDumper::VisitDependentSizedExtVectorType(
1934     const DependentSizedExtVectorType *T) {
1935   OS << " ";
1936   dumpLocation(T->getAttributeLoc());
1937 }
1938 
1939 void TextNodeDumper::VisitVectorType(const VectorType *T) {
1940   switch (T->getVectorKind()) {
1941   case VectorKind::Generic:
1942     break;
1943   case VectorKind::AltiVecVector:
1944     OS << " altivec";
1945     break;
1946   case VectorKind::AltiVecPixel:
1947     OS << " altivec pixel";
1948     break;
1949   case VectorKind::AltiVecBool:
1950     OS << " altivec bool";
1951     break;
1952   case VectorKind::Neon:
1953     OS << " neon";
1954     break;
1955   case VectorKind::NeonPoly:
1956     OS << " neon poly";
1957     break;
1958   case VectorKind::SveFixedLengthData:
1959     OS << " fixed-length sve data vector";
1960     break;
1961   case VectorKind::SveFixedLengthPredicate:
1962     OS << " fixed-length sve predicate vector";
1963     break;
1964   case VectorKind::RVVFixedLengthData:
1965     OS << " fixed-length rvv data vector";
1966     break;
1967   case VectorKind::RVVFixedLengthMask:
1968   case VectorKind::RVVFixedLengthMask_1:
1969   case VectorKind::RVVFixedLengthMask_2:
1970   case VectorKind::RVVFixedLengthMask_4:
1971     OS << " fixed-length rvv mask vector";
1972     break;
1973   }
1974   OS << " " << T->getNumElements();
1975 }
1976 
1977 void TextNodeDumper::VisitFunctionType(const FunctionType *T) {
1978   auto EI = T->getExtInfo();
1979   if (EI.getNoReturn())
1980     OS << " noreturn";
1981   if (EI.getProducesResult())
1982     OS << " produces_result";
1983   if (EI.getHasRegParm())
1984     OS << " regparm " << EI.getRegParm();
1985   OS << " " << FunctionType::getNameForCallConv(EI.getCC());
1986 }
1987 
1988 void TextNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) {
1989   auto EPI = T->getExtProtoInfo();
1990   if (EPI.HasTrailingReturn)
1991     OS << " trailing_return";
1992   if (T->isConst())
1993     OS << " const";
1994   if (T->isVolatile())
1995     OS << " volatile";
1996   if (T->isRestrict())
1997     OS << " restrict";
1998   if (T->getExtProtoInfo().Variadic)
1999     OS << " variadic";
2000   switch (EPI.RefQualifier) {
2001   case RQ_None:
2002     break;
2003   case RQ_LValue:
2004     OS << " &";
2005     break;
2006   case RQ_RValue:
2007     OS << " &&";
2008     break;
2009   }
2010 
2011   switch (EPI.ExceptionSpec.Type) {
2012   case EST_None:
2013     break;
2014   case EST_DynamicNone:
2015     OS << " exceptionspec_dynamic_none";
2016     break;
2017   case EST_Dynamic:
2018     OS << " exceptionspec_dynamic";
2019     break;
2020   case EST_MSAny:
2021     OS << " exceptionspec_ms_any";
2022     break;
2023   case EST_NoThrow:
2024     OS << " exceptionspec_nothrow";
2025     break;
2026   case EST_BasicNoexcept:
2027     OS << " exceptionspec_basic_noexcept";
2028     break;
2029   case EST_DependentNoexcept:
2030     OS << " exceptionspec_dependent_noexcept";
2031     break;
2032   case EST_NoexceptFalse:
2033     OS << " exceptionspec_noexcept_false";
2034     break;
2035   case EST_NoexceptTrue:
2036     OS << " exceptionspec_noexcept_true";
2037     break;
2038   case EST_Unevaluated:
2039     OS << " exceptionspec_unevaluated";
2040     break;
2041   case EST_Uninstantiated:
2042     OS << " exceptionspec_uninstantiated";
2043     break;
2044   case EST_Unparsed:
2045     OS << " exceptionspec_unparsed";
2046     break;
2047   }
2048   if (!EPI.ExceptionSpec.Exceptions.empty()) {
2049     AddChild([=] {
2050       OS << "Exceptions:";
2051       for (unsigned I = 0, N = EPI.ExceptionSpec.Exceptions.size(); I != N;
2052            ++I) {
2053         if (I)
2054           OS << ",";
2055         dumpType(EPI.ExceptionSpec.Exceptions[I]);
2056       }
2057     });
2058   }
2059   if (EPI.ExceptionSpec.NoexceptExpr) {
2060     AddChild([=] {
2061       OS << "NoexceptExpr: ";
2062       Visit(EPI.ExceptionSpec.NoexceptExpr);
2063     });
2064   }
2065   dumpDeclRef(EPI.ExceptionSpec.SourceDecl, "ExceptionSourceDecl");
2066   dumpDeclRef(EPI.ExceptionSpec.SourceTemplate, "ExceptionSourceTemplate");
2067 
2068   // FIXME: Consumed parameters.
2069   VisitFunctionType(T);
2070 }
2071 
2072 void TextNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
2073   dumpDeclRef(T->getDecl());
2074 }
2075 
2076 void TextNodeDumper::VisitUsingType(const UsingType *T) {
2077   dumpDeclRef(T->getFoundDecl());
2078   if (!T->typeMatchesDecl())
2079     OS << " divergent";
2080 }
2081 
2082 void TextNodeDumper::VisitTypedefType(const TypedefType *T) {
2083   dumpDeclRef(T->getDecl());
2084   if (!T->typeMatchesDecl())
2085     OS << " divergent";
2086 }
2087 
2088 void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType *T) {
2089   switch (T->getUTTKind()) {
2090 #define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait)                                  \
2091   case UnaryTransformType::Enum:                                               \
2092     OS << " " #Trait;                                                          \
2093     break;
2094 #include "clang/Basic/TransformTypeTraits.def"
2095   }
2096 }
2097 
2098 void TextNodeDumper::VisitTagType(const TagType *T) {
2099   dumpDeclRef(T->getDecl());
2100 }
2101 
2102 void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
2103   OS << " depth " << T->getDepth() << " index " << T->getIndex();
2104   if (T->isParameterPack())
2105     OS << " pack";
2106   dumpDeclRef(T->getDecl());
2107 }
2108 
2109 void TextNodeDumper::VisitSubstTemplateTypeParmType(
2110     const SubstTemplateTypeParmType *T) {
2111   dumpDeclRef(T->getAssociatedDecl());
2112   VisitTemplateTypeParmDecl(T->getReplacedParameter());
2113   if (auto PackIndex = T->getPackIndex())
2114     OS << " pack_index " << *PackIndex;
2115 }
2116 
2117 void TextNodeDumper::VisitSubstTemplateTypeParmPackType(
2118     const SubstTemplateTypeParmPackType *T) {
2119   dumpDeclRef(T->getAssociatedDecl());
2120   VisitTemplateTypeParmDecl(T->getReplacedParameter());
2121 }
2122 
2123 void TextNodeDumper::VisitAutoType(const AutoType *T) {
2124   if (T->isDecltypeAuto())
2125     OS << " decltype(auto)";
2126   if (!T->isDeduced())
2127     OS << " undeduced";
2128   if (T->isConstrained())
2129     dumpDeclRef(T->getTypeConstraintConcept());
2130 }
2131 
2132 void TextNodeDumper::VisitDeducedTemplateSpecializationType(
2133     const DeducedTemplateSpecializationType *T) {
2134   dumpTemplateName(T->getTemplateName(), "name");
2135 }
2136 
2137 void TextNodeDumper::VisitTemplateSpecializationType(
2138     const TemplateSpecializationType *T) {
2139   if (T->isTypeAlias())
2140     OS << " alias";
2141   dumpTemplateName(T->getTemplateName(), "name");
2142 }
2143 
2144 void TextNodeDumper::VisitInjectedClassNameType(
2145     const InjectedClassNameType *T) {
2146   dumpDeclRef(T->getDecl());
2147 }
2148 
2149 void TextNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
2150   dumpDeclRef(T->getDecl());
2151 }
2152 
2153 void TextNodeDumper::VisitPackExpansionType(const PackExpansionType *T) {
2154   if (auto N = T->getNumExpansions())
2155     OS << " expansions " << *N;
2156 }
2157 
2158 void TextNodeDumper::VisitTypeLoc(TypeLoc TL) {
2159   // By default, add extra Type details with no extra loc info.
2160   TypeVisitor<TextNodeDumper>::Visit(TL.getTypePtr());
2161 }
2162 // FIXME: override behavior for TypeLocs that have interesting location
2163 // information, such as the qualifier in ElaboratedTypeLoc.
2164 
2165 void TextNodeDumper::VisitLabelDecl(const LabelDecl *D) { dumpName(D); }
2166 
2167 void TextNodeDumper::VisitTypedefDecl(const TypedefDecl *D) {
2168   dumpName(D);
2169   dumpType(D->getUnderlyingType());
2170   if (D->isModulePrivate())
2171     OS << " __module_private__";
2172 }
2173 
2174 void TextNodeDumper::VisitEnumDecl(const EnumDecl *D) {
2175   if (D->isScoped()) {
2176     if (D->isScopedUsingClassTag())
2177       OS << " class";
2178     else
2179       OS << " struct";
2180   }
2181   dumpName(D);
2182   if (D->isModulePrivate())
2183     OS << " __module_private__";
2184   if (D->isFixed())
2185     dumpType(D->getIntegerType());
2186 }
2187 
2188 void TextNodeDumper::VisitRecordDecl(const RecordDecl *D) {
2189   OS << ' ' << D->getKindName();
2190   dumpName(D);
2191   if (D->isModulePrivate())
2192     OS << " __module_private__";
2193   if (D->isCompleteDefinition())
2194     OS << " definition";
2195 }
2196 
2197 void TextNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
2198   dumpName(D);
2199   dumpType(D->getType());
2200 }
2201 
2202 void TextNodeDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
2203   dumpName(D);
2204   dumpType(D->getType());
2205 
2206   for (const auto *Child : D->chain())
2207     dumpDeclRef(Child);
2208 }
2209 
2210 void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) {
2211   dumpName(D);
2212   dumpType(D->getType());
2213   dumpTemplateSpecializationKind(D->getTemplateSpecializationKind());
2214 
2215   StorageClass SC = D->getStorageClass();
2216   if (SC != SC_None)
2217     OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
2218   if (D->isInlineSpecified())
2219     OS << " inline";
2220   if (D->isVirtualAsWritten())
2221     OS << " virtual";
2222   if (D->isModulePrivate())
2223     OS << " __module_private__";
2224 
2225   if (D->isPureVirtual())
2226     OS << " pure";
2227   if (D->isDefaulted()) {
2228     OS << " default";
2229     if (D->isDeleted())
2230       OS << "_delete";
2231   }
2232   if (D->isDeletedAsWritten())
2233     OS << " delete";
2234   if (D->isTrivial())
2235     OS << " trivial";
2236 
2237   if (const StringLiteral *M = D->getDeletedMessage())
2238     AddChild("delete message", [=] { Visit(M); });
2239 
2240   if (D->isIneligibleOrNotSelected())
2241     OS << (isa<CXXDestructorDecl>(D) ? " not_selected" : " ineligible");
2242 
2243   if (const auto *FPT = D->getType()->getAs<FunctionProtoType>()) {
2244     FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
2245     switch (EPI.ExceptionSpec.Type) {
2246     default:
2247       break;
2248     case EST_Unevaluated:
2249       OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl;
2250       break;
2251     case EST_Uninstantiated:
2252       OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate;
2253       break;
2254     }
2255   }
2256 
2257   if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
2258     if (MD->size_overridden_methods() != 0) {
2259       auto dumpOverride = [=](const CXXMethodDecl *D) {
2260         SplitQualType T_split = D->getType().split();
2261         OS << D << " " << D->getParent()->getName() << "::" << D->getDeclName()
2262            << " '" << QualType::getAsString(T_split, PrintPolicy) << "'";
2263       };
2264 
2265       AddChild([=] {
2266         auto Overrides = MD->overridden_methods();
2267         OS << "Overrides: [ ";
2268         dumpOverride(*Overrides.begin());
2269         for (const auto *Override : llvm::drop_begin(Overrides)) {
2270           OS << ", ";
2271           dumpOverride(Override);
2272         }
2273         OS << " ]";
2274       });
2275     }
2276   }
2277 
2278   if (!D->isInlineSpecified() && D->isInlined()) {
2279     OS << " implicit-inline";
2280   }
2281   // Since NumParams comes from the FunctionProtoType of the FunctionDecl and
2282   // the Params are set later, it is possible for a dump during debugging to
2283   // encounter a FunctionDecl that has been created but hasn't been assigned
2284   // ParmVarDecls yet.
2285   if (!D->param_empty() && !D->param_begin())
2286     OS << " <<<NULL params x " << D->getNumParams() << ">>>";
2287 
2288   if (const auto *Instance = D->getInstantiatedFromMemberFunction()) {
2289     OS << " instantiated_from";
2290     dumpPointer(Instance);
2291   }
2292 }
2293 
2294 void TextNodeDumper::VisitCXXDeductionGuideDecl(
2295     const CXXDeductionGuideDecl *D) {
2296   VisitFunctionDecl(D);
2297   switch (D->getDeductionCandidateKind()) {
2298   case DeductionCandidate::Normal:
2299   case DeductionCandidate::Copy:
2300     return;
2301   case DeductionCandidate::Aggregate:
2302     OS << " aggregate ";
2303     break;
2304   }
2305 }
2306 
2307 void TextNodeDumper::VisitLifetimeExtendedTemporaryDecl(
2308     const LifetimeExtendedTemporaryDecl *D) {
2309   OS << " extended by ";
2310   dumpBareDeclRef(D->getExtendingDecl());
2311   OS << " mangling ";
2312   {
2313     ColorScope Color(OS, ShowColors, ValueColor);
2314     OS << D->getManglingNumber();
2315   }
2316 }
2317 
2318 void TextNodeDumper::VisitFieldDecl(const FieldDecl *D) {
2319   dumpName(D);
2320   dumpType(D->getType());
2321   if (D->isMutable())
2322     OS << " mutable";
2323   if (D->isModulePrivate())
2324     OS << " __module_private__";
2325 }
2326 
2327 void TextNodeDumper::VisitVarDecl(const VarDecl *D) {
2328   dumpNestedNameSpecifier(D->getQualifier());
2329   dumpName(D);
2330   if (const auto *P = dyn_cast<ParmVarDecl>(D);
2331       P && P->isExplicitObjectParameter())
2332     OS << " this";
2333 
2334   dumpType(D->getType());
2335   dumpTemplateSpecializationKind(D->getTemplateSpecializationKind());
2336   StorageClass SC = D->getStorageClass();
2337   if (SC != SC_None)
2338     OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
2339   switch (D->getTLSKind()) {
2340   case VarDecl::TLS_None:
2341     break;
2342   case VarDecl::TLS_Static:
2343     OS << " tls";
2344     break;
2345   case VarDecl::TLS_Dynamic:
2346     OS << " tls_dynamic";
2347     break;
2348   }
2349   if (D->isModulePrivate())
2350     OS << " __module_private__";
2351   if (D->isNRVOVariable())
2352     OS << " nrvo";
2353   if (D->isInline())
2354     OS << " inline";
2355   if (D->isConstexpr())
2356     OS << " constexpr";
2357   if (D->hasInit()) {
2358     switch (D->getInitStyle()) {
2359     case VarDecl::CInit:
2360       OS << " cinit";
2361       break;
2362     case VarDecl::CallInit:
2363       OS << " callinit";
2364       break;
2365     case VarDecl::ListInit:
2366       OS << " listinit";
2367       break;
2368     case VarDecl::ParenListInit:
2369       OS << " parenlistinit";
2370     }
2371   }
2372   if (D->needsDestruction(D->getASTContext()))
2373     OS << " destroyed";
2374   if (D->isParameterPack())
2375     OS << " pack";
2376 
2377   if (D->hasInit()) {
2378     const Expr *E = D->getInit();
2379     // Only dump the value of constexpr VarDecls for now.
2380     if (E && !E->isValueDependent() && D->isConstexpr() &&
2381         !D->getType()->isDependentType()) {
2382       const APValue *Value = D->evaluateValue();
2383       if (Value)
2384         AddChild("value", [=] { Visit(*Value, E->getType()); });
2385     }
2386   }
2387 }
2388 
2389 void TextNodeDumper::VisitBindingDecl(const BindingDecl *D) {
2390   dumpName(D);
2391   dumpType(D->getType());
2392 }
2393 
2394 void TextNodeDumper::VisitCapturedDecl(const CapturedDecl *D) {
2395   if (D->isNothrow())
2396     OS << " nothrow";
2397 }
2398 
2399 void TextNodeDumper::VisitImportDecl(const ImportDecl *D) {
2400   OS << ' ' << D->getImportedModule()->getFullModuleName();
2401 
2402   for (Decl *InitD :
2403        D->getASTContext().getModuleInitializers(D->getImportedModule()))
2404     dumpDeclRef(InitD, "initializer");
2405 }
2406 
2407 void TextNodeDumper::VisitPragmaCommentDecl(const PragmaCommentDecl *D) {
2408   OS << ' ';
2409   switch (D->getCommentKind()) {
2410   case PCK_Unknown:
2411     llvm_unreachable("unexpected pragma comment kind");
2412   case PCK_Compiler:
2413     OS << "compiler";
2414     break;
2415   case PCK_ExeStr:
2416     OS << "exestr";
2417     break;
2418   case PCK_Lib:
2419     OS << "lib";
2420     break;
2421   case PCK_Linker:
2422     OS << "linker";
2423     break;
2424   case PCK_User:
2425     OS << "user";
2426     break;
2427   }
2428   StringRef Arg = D->getArg();
2429   if (!Arg.empty())
2430     OS << " \"" << Arg << "\"";
2431 }
2432 
2433 void TextNodeDumper::VisitPragmaDetectMismatchDecl(
2434     const PragmaDetectMismatchDecl *D) {
2435   OS << " \"" << D->getName() << "\" \"" << D->getValue() << "\"";
2436 }
2437 
2438 void TextNodeDumper::VisitOMPExecutableDirective(
2439     const OMPExecutableDirective *D) {
2440   if (D->isStandaloneDirective())
2441     OS << " openmp_standalone_directive";
2442 }
2443 
2444 void TextNodeDumper::VisitOMPDeclareReductionDecl(
2445     const OMPDeclareReductionDecl *D) {
2446   dumpName(D);
2447   dumpType(D->getType());
2448   OS << " combiner";
2449   dumpPointer(D->getCombiner());
2450   if (const auto *Initializer = D->getInitializer()) {
2451     OS << " initializer";
2452     dumpPointer(Initializer);
2453     switch (D->getInitializerKind()) {
2454     case OMPDeclareReductionInitKind::Direct:
2455       OS << " omp_priv = ";
2456       break;
2457     case OMPDeclareReductionInitKind::Copy:
2458       OS << " omp_priv ()";
2459       break;
2460     case OMPDeclareReductionInitKind::Call:
2461       break;
2462     }
2463   }
2464 }
2465 
2466 void TextNodeDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) {
2467   for (const auto *C : D->clauselists()) {
2468     AddChild([=] {
2469       if (!C) {
2470         ColorScope Color(OS, ShowColors, NullColor);
2471         OS << "<<<NULL>>> OMPClause";
2472         return;
2473       }
2474       {
2475         ColorScope Color(OS, ShowColors, AttrColor);
2476         StringRef ClauseName(
2477             llvm::omp::getOpenMPClauseName(C->getClauseKind()));
2478         OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
2479            << ClauseName.drop_front() << "Clause";
2480       }
2481       dumpPointer(C);
2482       dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
2483     });
2484   }
2485 }
2486 
2487 void TextNodeDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
2488   dumpName(D);
2489   dumpType(D->getType());
2490 }
2491 
2492 void TextNodeDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
2493   dumpName(D);
2494   if (D->isInline())
2495     OS << " inline";
2496   if (D->isNested())
2497     OS << " nested";
2498   if (!D->isFirstDecl())
2499     dumpDeclRef(D->getFirstDecl(), "original");
2500 }
2501 
2502 void TextNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
2503   OS << ' ';
2504   dumpBareDeclRef(D->getNominatedNamespace());
2505 }
2506 
2507 void TextNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
2508   dumpName(D);
2509   dumpDeclRef(D->getAliasedNamespace());
2510 }
2511 
2512 void TextNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
2513   dumpName(D);
2514   dumpType(D->getUnderlyingType());
2515 }
2516 
2517 void TextNodeDumper::VisitTypeAliasTemplateDecl(
2518     const TypeAliasTemplateDecl *D) {
2519   dumpName(D);
2520 }
2521 
2522 void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
2523   VisitRecordDecl(D);
2524   if (const auto *Instance = D->getInstantiatedFromMemberClass()) {
2525     OS << " instantiated_from";
2526     dumpPointer(Instance);
2527   }
2528   if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D))
2529     dumpTemplateSpecializationKind(CTSD->getSpecializationKind());
2530 
2531   dumpNestedNameSpecifier(D->getQualifier());
2532 
2533   if (!D->isCompleteDefinition())
2534     return;
2535 
2536   AddChild([=] {
2537     {
2538       ColorScope Color(OS, ShowColors, DeclKindNameColor);
2539       OS << "DefinitionData";
2540     }
2541 #define FLAG(fn, name)                                                         \
2542   if (D->fn())                                                                 \
2543     OS << " " #name;
2544     FLAG(isParsingBaseSpecifiers, parsing_base_specifiers);
2545 
2546     FLAG(isGenericLambda, generic);
2547     FLAG(isLambda, lambda);
2548 
2549     FLAG(isAnonymousStructOrUnion, is_anonymous);
2550     FLAG(canPassInRegisters, pass_in_registers);
2551     FLAG(isEmpty, empty);
2552     FLAG(isAggregate, aggregate);
2553     FLAG(isStandardLayout, standard_layout);
2554     FLAG(isTriviallyCopyable, trivially_copyable);
2555     FLAG(isPOD, pod);
2556     FLAG(isTrivial, trivial);
2557     FLAG(isPolymorphic, polymorphic);
2558     FLAG(isAbstract, abstract);
2559     FLAG(isLiteral, literal);
2560 
2561     FLAG(hasUserDeclaredConstructor, has_user_declared_ctor);
2562     FLAG(hasConstexprNonCopyMoveConstructor, has_constexpr_non_copy_move_ctor);
2563     FLAG(hasMutableFields, has_mutable_fields);
2564     FLAG(hasVariantMembers, has_variant_members);
2565     FLAG(allowConstDefaultInit, can_const_default_init);
2566 
2567     AddChild([=] {
2568       {
2569         ColorScope Color(OS, ShowColors, DeclKindNameColor);
2570         OS << "DefaultConstructor";
2571       }
2572       FLAG(hasDefaultConstructor, exists);
2573       FLAG(hasTrivialDefaultConstructor, trivial);
2574       FLAG(hasNonTrivialDefaultConstructor, non_trivial);
2575       FLAG(hasUserProvidedDefaultConstructor, user_provided);
2576       FLAG(hasConstexprDefaultConstructor, constexpr);
2577       FLAG(needsImplicitDefaultConstructor, needs_implicit);
2578       FLAG(defaultedDefaultConstructorIsConstexpr, defaulted_is_constexpr);
2579     });
2580 
2581     AddChild([=] {
2582       {
2583         ColorScope Color(OS, ShowColors, DeclKindNameColor);
2584         OS << "CopyConstructor";
2585       }
2586       FLAG(hasSimpleCopyConstructor, simple);
2587       FLAG(hasTrivialCopyConstructor, trivial);
2588       FLAG(hasNonTrivialCopyConstructor, non_trivial);
2589       FLAG(hasUserDeclaredCopyConstructor, user_declared);
2590       FLAG(hasCopyConstructorWithConstParam, has_const_param);
2591       FLAG(needsImplicitCopyConstructor, needs_implicit);
2592       FLAG(needsOverloadResolutionForCopyConstructor,
2593            needs_overload_resolution);
2594       if (!D->needsOverloadResolutionForCopyConstructor())
2595         FLAG(defaultedCopyConstructorIsDeleted, defaulted_is_deleted);
2596       FLAG(implicitCopyConstructorHasConstParam, implicit_has_const_param);
2597     });
2598 
2599     AddChild([=] {
2600       {
2601         ColorScope Color(OS, ShowColors, DeclKindNameColor);
2602         OS << "MoveConstructor";
2603       }
2604       FLAG(hasMoveConstructor, exists);
2605       FLAG(hasSimpleMoveConstructor, simple);
2606       FLAG(hasTrivialMoveConstructor, trivial);
2607       FLAG(hasNonTrivialMoveConstructor, non_trivial);
2608       FLAG(hasUserDeclaredMoveConstructor, user_declared);
2609       FLAG(needsImplicitMoveConstructor, needs_implicit);
2610       FLAG(needsOverloadResolutionForMoveConstructor,
2611            needs_overload_resolution);
2612       if (!D->needsOverloadResolutionForMoveConstructor())
2613         FLAG(defaultedMoveConstructorIsDeleted, defaulted_is_deleted);
2614     });
2615 
2616     AddChild([=] {
2617       {
2618         ColorScope Color(OS, ShowColors, DeclKindNameColor);
2619         OS << "CopyAssignment";
2620       }
2621       FLAG(hasSimpleCopyAssignment, simple);
2622       FLAG(hasTrivialCopyAssignment, trivial);
2623       FLAG(hasNonTrivialCopyAssignment, non_trivial);
2624       FLAG(hasCopyAssignmentWithConstParam, has_const_param);
2625       FLAG(hasUserDeclaredCopyAssignment, user_declared);
2626       FLAG(needsImplicitCopyAssignment, needs_implicit);
2627       FLAG(needsOverloadResolutionForCopyAssignment, needs_overload_resolution);
2628       FLAG(implicitCopyAssignmentHasConstParam, implicit_has_const_param);
2629     });
2630 
2631     AddChild([=] {
2632       {
2633         ColorScope Color(OS, ShowColors, DeclKindNameColor);
2634         OS << "MoveAssignment";
2635       }
2636       FLAG(hasMoveAssignment, exists);
2637       FLAG(hasSimpleMoveAssignment, simple);
2638       FLAG(hasTrivialMoveAssignment, trivial);
2639       FLAG(hasNonTrivialMoveAssignment, non_trivial);
2640       FLAG(hasUserDeclaredMoveAssignment, user_declared);
2641       FLAG(needsImplicitMoveAssignment, needs_implicit);
2642       FLAG(needsOverloadResolutionForMoveAssignment, needs_overload_resolution);
2643     });
2644 
2645     AddChild([=] {
2646       {
2647         ColorScope Color(OS, ShowColors, DeclKindNameColor);
2648         OS << "Destructor";
2649       }
2650       FLAG(hasSimpleDestructor, simple);
2651       FLAG(hasIrrelevantDestructor, irrelevant);
2652       FLAG(hasTrivialDestructor, trivial);
2653       FLAG(hasNonTrivialDestructor, non_trivial);
2654       FLAG(hasUserDeclaredDestructor, user_declared);
2655       FLAG(hasConstexprDestructor, constexpr);
2656       FLAG(needsImplicitDestructor, needs_implicit);
2657       FLAG(needsOverloadResolutionForDestructor, needs_overload_resolution);
2658       if (!D->needsOverloadResolutionForDestructor())
2659         FLAG(defaultedDestructorIsDeleted, defaulted_is_deleted);
2660     });
2661   });
2662 
2663   for (const auto &I : D->bases()) {
2664     AddChild([=] {
2665       if (I.isVirtual())
2666         OS << "virtual ";
2667       dumpAccessSpecifier(I.getAccessSpecifier());
2668       dumpType(I.getType());
2669       if (I.isPackExpansion())
2670         OS << "...";
2671     });
2672   }
2673 }
2674 
2675 void TextNodeDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
2676   dumpName(D);
2677 }
2678 
2679 void TextNodeDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
2680   dumpName(D);
2681 }
2682 
2683 void TextNodeDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
2684   dumpName(D);
2685 }
2686 
2687 void TextNodeDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
2688   dumpName(D);
2689 }
2690 
2691 void TextNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
2692   if (const auto *TC = D->getTypeConstraint()) {
2693     OS << " ";
2694     dumpBareDeclRef(TC->getNamedConcept());
2695     if (TC->getNamedConcept() != TC->getFoundDecl()) {
2696       OS << " (";
2697       dumpBareDeclRef(TC->getFoundDecl());
2698       OS << ")";
2699     }
2700   } else if (D->wasDeclaredWithTypename())
2701     OS << " typename";
2702   else
2703     OS << " class";
2704   OS << " depth " << D->getDepth() << " index " << D->getIndex();
2705   if (D->isParameterPack())
2706     OS << " ...";
2707   dumpName(D);
2708 }
2709 
2710 void TextNodeDumper::VisitNonTypeTemplateParmDecl(
2711     const NonTypeTemplateParmDecl *D) {
2712   dumpType(D->getType());
2713   OS << " depth " << D->getDepth() << " index " << D->getIndex();
2714   if (D->isParameterPack())
2715     OS << " ...";
2716   dumpName(D);
2717 }
2718 
2719 void TextNodeDumper::VisitTemplateTemplateParmDecl(
2720     const TemplateTemplateParmDecl *D) {
2721   OS << " depth " << D->getDepth() << " index " << D->getIndex();
2722   if (D->isParameterPack())
2723     OS << " ...";
2724   dumpName(D);
2725 }
2726 
2727 void TextNodeDumper::VisitUsingDecl(const UsingDecl *D) {
2728   OS << ' ';
2729   if (D->getQualifier())
2730     D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2731   OS << D->getDeclName();
2732   dumpNestedNameSpecifier(D->getQualifier());
2733 }
2734 
2735 void TextNodeDumper::VisitUsingEnumDecl(const UsingEnumDecl *D) {
2736   OS << ' ';
2737   dumpBareDeclRef(D->getEnumDecl());
2738 }
2739 
2740 void TextNodeDumper::VisitUnresolvedUsingTypenameDecl(
2741     const UnresolvedUsingTypenameDecl *D) {
2742   OS << ' ';
2743   if (D->getQualifier())
2744     D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2745   OS << D->getDeclName();
2746 }
2747 
2748 void TextNodeDumper::VisitUnresolvedUsingValueDecl(
2749     const UnresolvedUsingValueDecl *D) {
2750   OS << ' ';
2751   if (D->getQualifier())
2752     D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2753   OS << D->getDeclName();
2754   dumpType(D->getType());
2755 }
2756 
2757 void TextNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
2758   OS << ' ';
2759   dumpBareDeclRef(D->getTargetDecl());
2760 }
2761 
2762 void TextNodeDumper::VisitConstructorUsingShadowDecl(
2763     const ConstructorUsingShadowDecl *D) {
2764   if (D->constructsVirtualBase())
2765     OS << " virtual";
2766 
2767   AddChild([=] {
2768     OS << "target ";
2769     dumpBareDeclRef(D->getTargetDecl());
2770   });
2771 
2772   AddChild([=] {
2773     OS << "nominated ";
2774     dumpBareDeclRef(D->getNominatedBaseClass());
2775     OS << ' ';
2776     dumpBareDeclRef(D->getNominatedBaseClassShadowDecl());
2777   });
2778 
2779   AddChild([=] {
2780     OS << "constructed ";
2781     dumpBareDeclRef(D->getConstructedBaseClass());
2782     OS << ' ';
2783     dumpBareDeclRef(D->getConstructedBaseClassShadowDecl());
2784   });
2785 }
2786 
2787 void TextNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
2788   switch (D->getLanguage()) {
2789   case LinkageSpecLanguageIDs::C:
2790     OS << " C";
2791     break;
2792   case LinkageSpecLanguageIDs::CXX:
2793     OS << " C++";
2794     break;
2795   }
2796 }
2797 
2798 void TextNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
2799   OS << ' ';
2800   dumpAccessSpecifier(D->getAccess());
2801 }
2802 
2803 void TextNodeDumper::VisitFriendDecl(const FriendDecl *D) {
2804   if (TypeSourceInfo *T = D->getFriendType())
2805     dumpType(T->getType());
2806   if (D->isPackExpansion())
2807     OS << "...";
2808 }
2809 
2810 void TextNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
2811   dumpName(D);
2812   dumpType(D->getType());
2813   if (D->getSynthesize())
2814     OS << " synthesize";
2815 
2816   switch (D->getAccessControl()) {
2817   case ObjCIvarDecl::None:
2818     OS << " none";
2819     break;
2820   case ObjCIvarDecl::Private:
2821     OS << " private";
2822     break;
2823   case ObjCIvarDecl::Protected:
2824     OS << " protected";
2825     break;
2826   case ObjCIvarDecl::Public:
2827     OS << " public";
2828     break;
2829   case ObjCIvarDecl::Package:
2830     OS << " package";
2831     break;
2832   }
2833 }
2834 
2835 void TextNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
2836   if (D->isInstanceMethod())
2837     OS << " -";
2838   else
2839     OS << " +";
2840   dumpName(D);
2841   dumpType(D->getReturnType());
2842 
2843   if (D->isVariadic())
2844     OS << " variadic";
2845 }
2846 
2847 void TextNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
2848   dumpName(D);
2849   switch (D->getVariance()) {
2850   case ObjCTypeParamVariance::Invariant:
2851     break;
2852 
2853   case ObjCTypeParamVariance::Covariant:
2854     OS << " covariant";
2855     break;
2856 
2857   case ObjCTypeParamVariance::Contravariant:
2858     OS << " contravariant";
2859     break;
2860   }
2861 
2862   if (D->hasExplicitBound())
2863     OS << " bounded";
2864   dumpType(D->getUnderlyingType());
2865 }
2866 
2867 void TextNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
2868   dumpName(D);
2869   dumpDeclRef(D->getClassInterface());
2870   dumpDeclRef(D->getImplementation());
2871   for (const auto *P : D->protocols())
2872     dumpDeclRef(P);
2873 }
2874 
2875 void TextNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
2876   dumpName(D);
2877   dumpDeclRef(D->getClassInterface());
2878   dumpDeclRef(D->getCategoryDecl());
2879 }
2880 
2881 void TextNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
2882   dumpName(D);
2883 
2884   for (const auto *Child : D->protocols())
2885     dumpDeclRef(Child);
2886 }
2887 
2888 void TextNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
2889   dumpName(D);
2890   dumpDeclRef(D->getSuperClass(), "super");
2891 
2892   dumpDeclRef(D->getImplementation());
2893   for (const auto *Child : D->protocols())
2894     dumpDeclRef(Child);
2895 }
2896 
2897 void TextNodeDumper::VisitObjCImplementationDecl(
2898     const ObjCImplementationDecl *D) {
2899   dumpName(D);
2900   dumpDeclRef(D->getSuperClass(), "super");
2901   dumpDeclRef(D->getClassInterface());
2902 }
2903 
2904 void TextNodeDumper::VisitObjCCompatibleAliasDecl(
2905     const ObjCCompatibleAliasDecl *D) {
2906   dumpName(D);
2907   dumpDeclRef(D->getClassInterface());
2908 }
2909 
2910 void TextNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
2911   dumpName(D);
2912   dumpType(D->getType());
2913 
2914   if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
2915     OS << " required";
2916   else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
2917     OS << " optional";
2918 
2919   ObjCPropertyAttribute::Kind Attrs = D->getPropertyAttributes();
2920   if (Attrs != ObjCPropertyAttribute::kind_noattr) {
2921     if (Attrs & ObjCPropertyAttribute::kind_readonly)
2922       OS << " readonly";
2923     if (Attrs & ObjCPropertyAttribute::kind_assign)
2924       OS << " assign";
2925     if (Attrs & ObjCPropertyAttribute::kind_readwrite)
2926       OS << " readwrite";
2927     if (Attrs & ObjCPropertyAttribute::kind_retain)
2928       OS << " retain";
2929     if (Attrs & ObjCPropertyAttribute::kind_copy)
2930       OS << " copy";
2931     if (Attrs & ObjCPropertyAttribute::kind_nonatomic)
2932       OS << " nonatomic";
2933     if (Attrs & ObjCPropertyAttribute::kind_atomic)
2934       OS << " atomic";
2935     if (Attrs & ObjCPropertyAttribute::kind_weak)
2936       OS << " weak";
2937     if (Attrs & ObjCPropertyAttribute::kind_strong)
2938       OS << " strong";
2939     if (Attrs & ObjCPropertyAttribute::kind_unsafe_unretained)
2940       OS << " unsafe_unretained";
2941     if (Attrs & ObjCPropertyAttribute::kind_class)
2942       OS << " class";
2943     if (Attrs & ObjCPropertyAttribute::kind_direct)
2944       OS << " direct";
2945     if (Attrs & ObjCPropertyAttribute::kind_getter)
2946       dumpDeclRef(D->getGetterMethodDecl(), "getter");
2947     if (Attrs & ObjCPropertyAttribute::kind_setter)
2948       dumpDeclRef(D->getSetterMethodDecl(), "setter");
2949   }
2950 }
2951 
2952 void TextNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
2953   dumpName(D->getPropertyDecl());
2954   if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
2955     OS << " synthesize";
2956   else
2957     OS << " dynamic";
2958   dumpDeclRef(D->getPropertyDecl());
2959   dumpDeclRef(D->getPropertyIvarDecl());
2960 }
2961 
2962 void TextNodeDumper::VisitBlockDecl(const BlockDecl *D) {
2963   if (D->isVariadic())
2964     OS << " variadic";
2965 
2966   if (D->capturesCXXThis())
2967     OS << " captures_this";
2968 }
2969 
2970 void TextNodeDumper::VisitConceptDecl(const ConceptDecl *D) {
2971   dumpName(D);
2972 }
2973 
2974 void TextNodeDumper::VisitCompoundStmt(const CompoundStmt *S) {
2975   VisitStmt(S);
2976   if (S->hasStoredFPFeatures())
2977     printFPOptions(S->getStoredFPFeatures());
2978 }
2979 
2980 void TextNodeDumper::VisitHLSLBufferDecl(const HLSLBufferDecl *D) {
2981   if (D->isCBuffer())
2982     OS << " cbuffer";
2983   else
2984     OS << " tbuffer";
2985   dumpName(D);
2986 }
2987 
2988 void TextNodeDumper::VisitHLSLOutArgExpr(const HLSLOutArgExpr *E) {
2989   OS << (E->isInOut() ? " inout" : " out");
2990 }
2991 
2992 void TextNodeDumper::VisitOpenACCConstructStmt(const OpenACCConstructStmt *S) {
2993   OS << " " << S->getDirectiveKind();
2994 }
2995 void TextNodeDumper::VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *S) {
2996   if (S->isOrphanedLoopConstruct())
2997     OS << " <orphan>";
2998   else
2999     OS << " parent: " << S->getParentComputeConstructKind();
3000 }
3001 
3002 void TextNodeDumper::VisitOpenACCCombinedConstruct(
3003     const OpenACCCombinedConstruct *S) {
3004   VisitOpenACCConstructStmt(S);
3005 }
3006 
3007 void TextNodeDumper::VisitOpenACCDataConstruct(const OpenACCDataConstruct *S) {
3008   VisitOpenACCConstructStmt(S);
3009 }
3010 
3011 void TextNodeDumper::VisitOpenACCEnterDataConstruct(
3012     const OpenACCEnterDataConstruct *S) {
3013   VisitOpenACCConstructStmt(S);
3014 }
3015 
3016 void TextNodeDumper::VisitOpenACCExitDataConstruct(
3017     const OpenACCExitDataConstruct *S) {
3018   VisitOpenACCConstructStmt(S);
3019 }
3020 
3021 void TextNodeDumper::VisitOpenACCHostDataConstruct(
3022     const OpenACCHostDataConstruct *S) {
3023   VisitOpenACCConstructStmt(S);
3024 }
3025 
3026 void TextNodeDumper::VisitOpenACCWaitConstruct(const OpenACCWaitConstruct *S) {
3027   VisitOpenACCConstructStmt(S);
3028 }
3029 void TextNodeDumper::VisitOpenACCInitConstruct(const OpenACCInitConstruct *S) {
3030   VisitOpenACCConstructStmt(S);
3031 }
3032 void TextNodeDumper::VisitOpenACCShutdownConstruct(
3033     const OpenACCShutdownConstruct *S) {
3034   VisitOpenACCConstructStmt(S);
3035 }
3036 void TextNodeDumper::VisitOpenACCSetConstruct(const OpenACCSetConstruct *S) {
3037   VisitOpenACCConstructStmt(S);
3038 }
3039 void TextNodeDumper::VisitOpenACCUpdateConstruct(
3040     const OpenACCUpdateConstruct *S) {
3041   VisitOpenACCConstructStmt(S);
3042 }
3043 
3044 void TextNodeDumper::VisitEmbedExpr(const EmbedExpr *S) {
3045   AddChild("begin", [=] { OS << S->getStartingElementPos(); });
3046   AddChild("number of elements", [=] { OS << S->getDataElementCount(); });
3047 }
3048 
3049 void TextNodeDumper::VisitAtomicExpr(const AtomicExpr *AE) {
3050   OS << ' ' << AE->getOpAsString();
3051 }
3052