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