10b57cec5SDimitry Andric //===--- TextNodeDumper.cpp - Printing of AST nodes -----------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements AST dumping of components of individual AST nodes.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "clang/AST/TextNodeDumper.h"
145ffd83dbSDimitry Andric #include "clang/AST/APValue.h"
150b57cec5SDimitry Andric #include "clang/AST/DeclFriend.h"
160b57cec5SDimitry Andric #include "clang/AST/DeclOpenMP.h"
170b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h"
180b57cec5SDimitry Andric #include "clang/AST/LocInfoType.h"
195f757f3fSDimitry Andric #include "clang/AST/NestedNameSpecifier.h"
205ffd83dbSDimitry Andric #include "clang/AST/Type.h"
215ffd83dbSDimitry Andric #include "clang/Basic/Module.h"
225ffd83dbSDimitry Andric #include "clang/Basic/SourceManager.h"
235ffd83dbSDimitry Andric #include "clang/Basic/Specifiers.h"
245ffd83dbSDimitry Andric #include "clang/Basic/TypeTraits.h"
25fe6060f1SDimitry Andric #include "llvm/ADT/StringExtras.h"
265ffd83dbSDimitry Andric 
275ffd83dbSDimitry Andric #include <algorithm>
285ffd83dbSDimitry Andric #include <utility>
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric using namespace clang;
310b57cec5SDimitry Andric 
dumpPreviousDeclImpl(raw_ostream & OS,...)320b57cec5SDimitry Andric static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {}
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric template <typename T>
dumpPreviousDeclImpl(raw_ostream & OS,const Mergeable<T> * D)350b57cec5SDimitry Andric static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) {
360b57cec5SDimitry Andric   const T *First = D->getFirstDecl();
370b57cec5SDimitry Andric   if (First != D)
380b57cec5SDimitry Andric     OS << " first " << First;
390b57cec5SDimitry Andric }
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric template <typename T>
dumpPreviousDeclImpl(raw_ostream & OS,const Redeclarable<T> * D)420b57cec5SDimitry Andric static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) {
430b57cec5SDimitry Andric   const T *Prev = D->getPreviousDecl();
440b57cec5SDimitry Andric   if (Prev)
450b57cec5SDimitry Andric     OS << " prev " << Prev;
460b57cec5SDimitry Andric }
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric /// Dump the previous declaration in the redeclaration chain for a declaration,
490b57cec5SDimitry Andric /// if any.
dumpPreviousDecl(raw_ostream & OS,const Decl * D)500b57cec5SDimitry Andric static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) {
510b57cec5SDimitry Andric   switch (D->getKind()) {
520b57cec5SDimitry Andric #define DECL(DERIVED, BASE)                                                    \
530b57cec5SDimitry Andric   case Decl::DERIVED:                                                          \
540b57cec5SDimitry Andric     return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D));
550b57cec5SDimitry Andric #define ABSTRACT_DECL(DECL)
560b57cec5SDimitry Andric #include "clang/AST/DeclNodes.inc"
570b57cec5SDimitry Andric   }
580b57cec5SDimitry Andric   llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
590b57cec5SDimitry Andric }
600b57cec5SDimitry Andric 
TextNodeDumper(raw_ostream & OS,const ASTContext & Context,bool ShowColors)615ffd83dbSDimitry Andric TextNodeDumper::TextNodeDumper(raw_ostream &OS, const ASTContext &Context,
625ffd83dbSDimitry Andric                                bool ShowColors)
635ffd83dbSDimitry Andric     : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors),
645ffd83dbSDimitry Andric       Context(&Context), SM(&Context.getSourceManager()),
655ffd83dbSDimitry Andric       PrintPolicy(Context.getPrintingPolicy()),
665ffd83dbSDimitry Andric       Traits(&Context.getCommentCommandTraits()) {}
675ffd83dbSDimitry Andric 
TextNodeDumper(raw_ostream & OS,bool ShowColors)685ffd83dbSDimitry Andric TextNodeDumper::TextNodeDumper(raw_ostream &OS, bool ShowColors)
695ffd83dbSDimitry Andric     : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors) {}
700b57cec5SDimitry Andric 
Visit(const comments::Comment * C,const comments::FullComment * FC)710b57cec5SDimitry Andric void TextNodeDumper::Visit(const comments::Comment *C,
720b57cec5SDimitry Andric                            const comments::FullComment *FC) {
730b57cec5SDimitry Andric   if (!C) {
740b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, NullColor);
750b57cec5SDimitry Andric     OS << "<<<NULL>>>";
760b57cec5SDimitry Andric     return;
770b57cec5SDimitry Andric   }
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric   {
800b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, CommentColor);
810b57cec5SDimitry Andric     OS << C->getCommentKindName();
820b57cec5SDimitry Andric   }
830b57cec5SDimitry Andric   dumpPointer(C);
840b57cec5SDimitry Andric   dumpSourceRange(C->getSourceRange());
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric   ConstCommentVisitor<TextNodeDumper, void,
870b57cec5SDimitry Andric                       const comments::FullComment *>::visit(C, FC);
880b57cec5SDimitry Andric }
890b57cec5SDimitry Andric 
Visit(const Attr * A)900b57cec5SDimitry Andric void TextNodeDumper::Visit(const Attr *A) {
910b57cec5SDimitry Andric   {
920b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, AttrColor);
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric     switch (A->getKind()) {
950b57cec5SDimitry Andric #define ATTR(X)                                                                \
960b57cec5SDimitry Andric   case attr::X:                                                                \
970b57cec5SDimitry Andric     OS << #X;                                                                  \
980b57cec5SDimitry Andric     break;
990b57cec5SDimitry Andric #include "clang/Basic/AttrList.inc"
1000b57cec5SDimitry Andric     }
1010b57cec5SDimitry Andric     OS << "Attr";
1020b57cec5SDimitry Andric   }
1030b57cec5SDimitry Andric   dumpPointer(A);
1040b57cec5SDimitry Andric   dumpSourceRange(A->getRange());
1050b57cec5SDimitry Andric   if (A->isInherited())
1060b57cec5SDimitry Andric     OS << " Inherited";
1070b57cec5SDimitry Andric   if (A->isImplicit())
1080b57cec5SDimitry Andric     OS << " Implicit";
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric   ConstAttrVisitor<TextNodeDumper>::Visit(A);
1110b57cec5SDimitry Andric }
1120b57cec5SDimitry Andric 
Visit(const TemplateArgument & TA,SourceRange R,const Decl * From,StringRef Label)1130b57cec5SDimitry Andric void TextNodeDumper::Visit(const TemplateArgument &TA, SourceRange R,
1140b57cec5SDimitry Andric                            const Decl *From, StringRef Label) {
1150b57cec5SDimitry Andric   OS << "TemplateArgument";
1160b57cec5SDimitry Andric   if (R.isValid())
1170b57cec5SDimitry Andric     dumpSourceRange(R);
1180b57cec5SDimitry Andric 
1190b57cec5SDimitry Andric   if (From)
1200b57cec5SDimitry Andric     dumpDeclRef(From, Label);
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric   ConstTemplateArgumentVisitor<TextNodeDumper>::Visit(TA);
1230b57cec5SDimitry Andric }
1240b57cec5SDimitry Andric 
Visit(const Stmt * Node)1250b57cec5SDimitry Andric void TextNodeDumper::Visit(const Stmt *Node) {
1260b57cec5SDimitry Andric   if (!Node) {
1270b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, NullColor);
1280b57cec5SDimitry Andric     OS << "<<<NULL>>>";
1290b57cec5SDimitry Andric     return;
1300b57cec5SDimitry Andric   }
1310b57cec5SDimitry Andric   {
1320b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, StmtColor);
1330b57cec5SDimitry Andric     OS << Node->getStmtClassName();
1340b57cec5SDimitry Andric   }
1350b57cec5SDimitry Andric   dumpPointer(Node);
1360b57cec5SDimitry Andric   dumpSourceRange(Node->getSourceRange());
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric   if (const auto *E = dyn_cast<Expr>(Node)) {
1390b57cec5SDimitry Andric     dumpType(E->getType());
1400b57cec5SDimitry Andric 
1415ffd83dbSDimitry Andric     if (E->containsErrors()) {
1425ffd83dbSDimitry Andric       ColorScope Color(OS, ShowColors, ErrorsColor);
1435ffd83dbSDimitry Andric       OS << " contains-errors";
1445ffd83dbSDimitry Andric     }
1455ffd83dbSDimitry Andric 
1460b57cec5SDimitry Andric     {
1470b57cec5SDimitry Andric       ColorScope Color(OS, ShowColors, ValueKindColor);
1480b57cec5SDimitry Andric       switch (E->getValueKind()) {
149fe6060f1SDimitry Andric       case VK_PRValue:
1500b57cec5SDimitry Andric         break;
1510b57cec5SDimitry Andric       case VK_LValue:
1520b57cec5SDimitry Andric         OS << " lvalue";
1530b57cec5SDimitry Andric         break;
1540b57cec5SDimitry Andric       case VK_XValue:
1550b57cec5SDimitry Andric         OS << " xvalue";
1560b57cec5SDimitry Andric         break;
1570b57cec5SDimitry Andric       }
1580b57cec5SDimitry Andric     }
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric     {
1610b57cec5SDimitry Andric       ColorScope Color(OS, ShowColors, ObjectKindColor);
1620b57cec5SDimitry Andric       switch (E->getObjectKind()) {
1630b57cec5SDimitry Andric       case OK_Ordinary:
1640b57cec5SDimitry Andric         break;
1650b57cec5SDimitry Andric       case OK_BitField:
1660b57cec5SDimitry Andric         OS << " bitfield";
1670b57cec5SDimitry Andric         break;
1680b57cec5SDimitry Andric       case OK_ObjCProperty:
1690b57cec5SDimitry Andric         OS << " objcproperty";
1700b57cec5SDimitry Andric         break;
1710b57cec5SDimitry Andric       case OK_ObjCSubscript:
1720b57cec5SDimitry Andric         OS << " objcsubscript";
1730b57cec5SDimitry Andric         break;
1740b57cec5SDimitry Andric       case OK_VectorComponent:
1750b57cec5SDimitry Andric         OS << " vectorcomponent";
1760b57cec5SDimitry Andric         break;
1775ffd83dbSDimitry Andric       case OK_MatrixComponent:
1785ffd83dbSDimitry Andric         OS << " matrixcomponent";
1795ffd83dbSDimitry Andric         break;
1800b57cec5SDimitry Andric       }
1810b57cec5SDimitry Andric     }
1820b57cec5SDimitry Andric   }
1830b57cec5SDimitry Andric 
1840b57cec5SDimitry Andric   ConstStmtVisitor<TextNodeDumper>::Visit(Node);
1850b57cec5SDimitry Andric }
1860b57cec5SDimitry Andric 
Visit(const Type * T)1870b57cec5SDimitry Andric void TextNodeDumper::Visit(const Type *T) {
1880b57cec5SDimitry Andric   if (!T) {
1890b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, NullColor);
1900b57cec5SDimitry Andric     OS << "<<<NULL>>>";
1910b57cec5SDimitry Andric     return;
1920b57cec5SDimitry Andric   }
1930b57cec5SDimitry Andric   if (isa<LocInfoType>(T)) {
1940b57cec5SDimitry Andric     {
1950b57cec5SDimitry Andric       ColorScope Color(OS, ShowColors, TypeColor);
1960b57cec5SDimitry Andric       OS << "LocInfo Type";
1970b57cec5SDimitry Andric     }
1980b57cec5SDimitry Andric     dumpPointer(T);
1990b57cec5SDimitry Andric     return;
2000b57cec5SDimitry Andric   }
2010b57cec5SDimitry Andric 
2020b57cec5SDimitry Andric   {
2030b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, TypeColor);
2040b57cec5SDimitry Andric     OS << T->getTypeClassName() << "Type";
2050b57cec5SDimitry Andric   }
2060b57cec5SDimitry Andric   dumpPointer(T);
2070b57cec5SDimitry Andric   OS << " ";
2080b57cec5SDimitry Andric   dumpBareType(QualType(T, 0), false);
2090b57cec5SDimitry Andric 
2100b57cec5SDimitry Andric   QualType SingleStepDesugar =
2110b57cec5SDimitry Andric       T->getLocallyUnqualifiedSingleStepDesugaredType();
2120b57cec5SDimitry Andric   if (SingleStepDesugar != QualType(T, 0))
2130b57cec5SDimitry Andric     OS << " sugar";
2140b57cec5SDimitry Andric 
2155ffd83dbSDimitry Andric   if (T->containsErrors()) {
2165ffd83dbSDimitry Andric     ColorScope Color(OS, ShowColors, ErrorsColor);
2175ffd83dbSDimitry Andric     OS << " contains-errors";
2185ffd83dbSDimitry Andric   }
2195ffd83dbSDimitry Andric 
2200b57cec5SDimitry Andric   if (T->isDependentType())
2210b57cec5SDimitry Andric     OS << " dependent";
2220b57cec5SDimitry Andric   else if (T->isInstantiationDependentType())
2230b57cec5SDimitry Andric     OS << " instantiation_dependent";
2240b57cec5SDimitry Andric 
2250b57cec5SDimitry Andric   if (T->isVariablyModifiedType())
2260b57cec5SDimitry Andric     OS << " variably_modified";
2270b57cec5SDimitry Andric   if (T->containsUnexpandedParameterPack())
2280b57cec5SDimitry Andric     OS << " contains_unexpanded_pack";
2290b57cec5SDimitry Andric   if (T->isFromAST())
2300b57cec5SDimitry Andric     OS << " imported";
2310b57cec5SDimitry Andric 
2320b57cec5SDimitry Andric   TypeVisitor<TextNodeDumper>::Visit(T);
2330b57cec5SDimitry Andric }
2340b57cec5SDimitry Andric 
Visit(QualType T)2350b57cec5SDimitry Andric void TextNodeDumper::Visit(QualType T) {
2360b57cec5SDimitry Andric   OS << "QualType";
2370b57cec5SDimitry Andric   dumpPointer(T.getAsOpaquePtr());
2380b57cec5SDimitry Andric   OS << " ";
2390b57cec5SDimitry Andric   dumpBareType(T, false);
2400b57cec5SDimitry Andric   OS << " " << T.split().Quals.getAsString();
2410b57cec5SDimitry Andric }
2420b57cec5SDimitry Andric 
Visit(const Decl * D)2430b57cec5SDimitry Andric void TextNodeDumper::Visit(const Decl *D) {
2440b57cec5SDimitry Andric   if (!D) {
2450b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, NullColor);
2460b57cec5SDimitry Andric     OS << "<<<NULL>>>";
2470b57cec5SDimitry Andric     return;
2480b57cec5SDimitry Andric   }
2490b57cec5SDimitry Andric 
2500b57cec5SDimitry Andric   {
2510b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, DeclKindNameColor);
2520b57cec5SDimitry Andric     OS << D->getDeclKindName() << "Decl";
2530b57cec5SDimitry Andric   }
2540b57cec5SDimitry Andric   dumpPointer(D);
2550b57cec5SDimitry Andric   if (D->getLexicalDeclContext() != D->getDeclContext())
2560b57cec5SDimitry Andric     OS << " parent " << cast<Decl>(D->getDeclContext());
2570b57cec5SDimitry Andric   dumpPreviousDecl(OS, D);
2580b57cec5SDimitry Andric   dumpSourceRange(D->getSourceRange());
2590b57cec5SDimitry Andric   OS << ' ';
2600b57cec5SDimitry Andric   dumpLocation(D->getLocation());
2610b57cec5SDimitry Andric   if (D->isFromASTFile())
2620b57cec5SDimitry Andric     OS << " imported";
2630b57cec5SDimitry Andric   if (Module *M = D->getOwningModule())
2640b57cec5SDimitry Andric     OS << " in " << M->getFullModuleName();
2650b57cec5SDimitry Andric   if (auto *ND = dyn_cast<NamedDecl>(D))
2660b57cec5SDimitry Andric     for (Module *M : D->getASTContext().getModulesWithMergedDefinition(
2670b57cec5SDimitry Andric              const_cast<NamedDecl *>(ND)))
2680b57cec5SDimitry Andric       AddChild([=] { OS << "also in " << M->getFullModuleName(); });
2690b57cec5SDimitry Andric   if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
2705ffd83dbSDimitry Andric     if (!ND->isUnconditionallyVisible())
2710b57cec5SDimitry Andric       OS << " hidden";
2720b57cec5SDimitry Andric   if (D->isImplicit())
2730b57cec5SDimitry Andric     OS << " implicit";
2740b57cec5SDimitry Andric 
2750b57cec5SDimitry Andric   if (D->isUsed())
2760b57cec5SDimitry Andric     OS << " used";
2770b57cec5SDimitry Andric   else if (D->isThisDeclarationReferenced())
2780b57cec5SDimitry Andric     OS << " referenced";
2790b57cec5SDimitry Andric 
2800b57cec5SDimitry Andric   if (D->isInvalidDecl())
2810b57cec5SDimitry Andric     OS << " invalid";
2820b57cec5SDimitry Andric   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
2830b57cec5SDimitry Andric     if (FD->isConstexprSpecified())
2840b57cec5SDimitry Andric       OS << " constexpr";
2850b57cec5SDimitry Andric     if (FD->isConsteval())
2860b57cec5SDimitry Andric       OS << " consteval";
28706c3fb27SDimitry Andric     else if (FD->isImmediateFunction())
28806c3fb27SDimitry Andric       OS << " immediate";
28981ad6265SDimitry Andric     if (FD->isMultiVersion())
29081ad6265SDimitry Andric       OS << " multiversion";
2910b57cec5SDimitry Andric   }
2920b57cec5SDimitry Andric 
2930b57cec5SDimitry Andric   if (!isa<FunctionDecl>(*D)) {
2940b57cec5SDimitry Andric     const auto *MD = dyn_cast<ObjCMethodDecl>(D);
2950b57cec5SDimitry Andric     if (!MD || !MD->isThisDeclarationADefinition()) {
2960b57cec5SDimitry Andric       const auto *DC = dyn_cast<DeclContext>(D);
2970b57cec5SDimitry Andric       if (DC && DC->hasExternalLexicalStorage()) {
2980b57cec5SDimitry Andric         ColorScope Color(OS, ShowColors, UndeserializedColor);
2990b57cec5SDimitry Andric         OS << " <undeserialized declarations>";
3000b57cec5SDimitry Andric       }
3010b57cec5SDimitry Andric     }
3020b57cec5SDimitry Andric   }
3030b57cec5SDimitry Andric 
3045f757f3fSDimitry Andric   switch (D->getFriendObjectKind()) {
3055f757f3fSDimitry Andric   case Decl::FOK_None:
3065f757f3fSDimitry Andric     break;
3075f757f3fSDimitry Andric   case Decl::FOK_Declared:
3085f757f3fSDimitry Andric     OS << " friend";
3095f757f3fSDimitry Andric     break;
3105f757f3fSDimitry Andric   case Decl::FOK_Undeclared:
3115f757f3fSDimitry Andric     OS << " friend_undeclared";
3125f757f3fSDimitry Andric     break;
3135f757f3fSDimitry Andric   }
3145f757f3fSDimitry Andric 
3150b57cec5SDimitry Andric   ConstDeclVisitor<TextNodeDumper>::Visit(D);
3160b57cec5SDimitry Andric }
3170b57cec5SDimitry Andric 
Visit(const CXXCtorInitializer * Init)3180b57cec5SDimitry Andric void TextNodeDumper::Visit(const CXXCtorInitializer *Init) {
3190b57cec5SDimitry Andric   OS << "CXXCtorInitializer";
3200b57cec5SDimitry Andric   if (Init->isAnyMemberInitializer()) {
3210b57cec5SDimitry Andric     OS << ' ';
3220b57cec5SDimitry Andric     dumpBareDeclRef(Init->getAnyMember());
3230b57cec5SDimitry Andric   } else if (Init->isBaseInitializer()) {
3240b57cec5SDimitry Andric     dumpType(QualType(Init->getBaseClass(), 0));
3250b57cec5SDimitry Andric   } else if (Init->isDelegatingInitializer()) {
3260b57cec5SDimitry Andric     dumpType(Init->getTypeSourceInfo()->getType());
3270b57cec5SDimitry Andric   } else {
3280b57cec5SDimitry Andric     llvm_unreachable("Unknown initializer type");
3290b57cec5SDimitry Andric   }
3300b57cec5SDimitry Andric }
3310b57cec5SDimitry Andric 
Visit(const BlockDecl::Capture & C)3320b57cec5SDimitry Andric void TextNodeDumper::Visit(const BlockDecl::Capture &C) {
3330b57cec5SDimitry Andric   OS << "capture";
3340b57cec5SDimitry Andric   if (C.isByRef())
3350b57cec5SDimitry Andric     OS << " byref";
3360b57cec5SDimitry Andric   if (C.isNested())
3370b57cec5SDimitry Andric     OS << " nested";
3380b57cec5SDimitry Andric   if (C.getVariable()) {
3390b57cec5SDimitry Andric     OS << ' ';
3400b57cec5SDimitry Andric     dumpBareDeclRef(C.getVariable());
3410b57cec5SDimitry Andric   }
3420b57cec5SDimitry Andric }
3430b57cec5SDimitry Andric 
Visit(const OMPClause * C)3440b57cec5SDimitry Andric void TextNodeDumper::Visit(const OMPClause *C) {
3450b57cec5SDimitry Andric   if (!C) {
3460b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, NullColor);
3470b57cec5SDimitry Andric     OS << "<<<NULL>>> OMPClause";
3480b57cec5SDimitry Andric     return;
3490b57cec5SDimitry Andric   }
3500b57cec5SDimitry Andric   {
3510b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, AttrColor);
3525ffd83dbSDimitry Andric     StringRef ClauseName(llvm::omp::getOpenMPClauseName(C->getClauseKind()));
3530b57cec5SDimitry Andric     OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
3540b57cec5SDimitry Andric        << ClauseName.drop_front() << "Clause";
3550b57cec5SDimitry Andric   }
3560b57cec5SDimitry Andric   dumpPointer(C);
3570b57cec5SDimitry Andric   dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
3580b57cec5SDimitry Andric   if (C->isImplicit())
3590b57cec5SDimitry Andric     OS << " <implicit>";
3600b57cec5SDimitry Andric }
3610b57cec5SDimitry Andric 
Visit(const GenericSelectionExpr::ConstAssociation & A)3620b57cec5SDimitry Andric void TextNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) {
3630b57cec5SDimitry Andric   const TypeSourceInfo *TSI = A.getTypeSourceInfo();
3640b57cec5SDimitry Andric   if (TSI) {
3650b57cec5SDimitry Andric     OS << "case ";
3660b57cec5SDimitry Andric     dumpType(TSI->getType());
3670b57cec5SDimitry Andric   } else {
3680b57cec5SDimitry Andric     OS << "default";
3690b57cec5SDimitry Andric   }
3700b57cec5SDimitry Andric 
3710b57cec5SDimitry Andric   if (A.isSelected())
3720b57cec5SDimitry Andric     OS << " selected";
3730b57cec5SDimitry Andric }
3740b57cec5SDimitry Andric 
Visit(const ConceptReference * R)3755f757f3fSDimitry Andric void TextNodeDumper::Visit(const ConceptReference *R) {
3765f757f3fSDimitry Andric   if (!R) {
3775f757f3fSDimitry Andric     ColorScope Color(OS, ShowColors, NullColor);
3785f757f3fSDimitry Andric     OS << "<<<NULL>>> ConceptReference";
3795f757f3fSDimitry Andric     return;
3805f757f3fSDimitry Andric   }
3815f757f3fSDimitry Andric 
3825f757f3fSDimitry Andric   OS << "ConceptReference";
3835f757f3fSDimitry Andric   dumpPointer(R);
3845f757f3fSDimitry Andric   dumpSourceRange(R->getSourceRange());
3855f757f3fSDimitry Andric   OS << ' ';
3865f757f3fSDimitry Andric   dumpBareDeclRef(R->getNamedConcept());
3875f757f3fSDimitry Andric }
3885f757f3fSDimitry Andric 
Visit(const concepts::Requirement * R)389fe6060f1SDimitry Andric void TextNodeDumper::Visit(const concepts::Requirement *R) {
390fe6060f1SDimitry Andric   if (!R) {
391fe6060f1SDimitry Andric     ColorScope Color(OS, ShowColors, NullColor);
392fe6060f1SDimitry Andric     OS << "<<<NULL>>> Requirement";
393fe6060f1SDimitry Andric     return;
394fe6060f1SDimitry Andric   }
395fe6060f1SDimitry Andric 
396fe6060f1SDimitry Andric   {
397fe6060f1SDimitry Andric     ColorScope Color(OS, ShowColors, StmtColor);
398fe6060f1SDimitry Andric     switch (R->getKind()) {
399fe6060f1SDimitry Andric     case concepts::Requirement::RK_Type:
400fe6060f1SDimitry Andric       OS << "TypeRequirement";
401fe6060f1SDimitry Andric       break;
402fe6060f1SDimitry Andric     case concepts::Requirement::RK_Simple:
403fe6060f1SDimitry Andric       OS << "SimpleRequirement";
404fe6060f1SDimitry Andric       break;
405fe6060f1SDimitry Andric     case concepts::Requirement::RK_Compound:
406fe6060f1SDimitry Andric       OS << "CompoundRequirement";
407fe6060f1SDimitry Andric       break;
408fe6060f1SDimitry Andric     case concepts::Requirement::RK_Nested:
409fe6060f1SDimitry Andric       OS << "NestedRequirement";
410fe6060f1SDimitry Andric       break;
411fe6060f1SDimitry Andric     }
412fe6060f1SDimitry Andric   }
413fe6060f1SDimitry Andric 
414fe6060f1SDimitry Andric   dumpPointer(R);
415fe6060f1SDimitry Andric 
416fe6060f1SDimitry Andric   if (auto *ER = dyn_cast<concepts::ExprRequirement>(R)) {
417fe6060f1SDimitry Andric     if (ER->hasNoexceptRequirement())
418fe6060f1SDimitry Andric       OS << " noexcept";
419fe6060f1SDimitry Andric   }
420fe6060f1SDimitry Andric 
421fe6060f1SDimitry Andric   if (R->isDependent())
422fe6060f1SDimitry Andric     OS << " dependent";
423fe6060f1SDimitry Andric   else
424fe6060f1SDimitry Andric     OS << (R->isSatisfied() ? " satisfied" : " unsatisfied");
425fe6060f1SDimitry Andric   if (R->containsUnexpandedParameterPack())
426fe6060f1SDimitry Andric     OS << " contains_unexpanded_pack";
427fe6060f1SDimitry Andric }
428fe6060f1SDimitry Andric 
GetApproxValue(const llvm::APFloat & F)4295ffd83dbSDimitry Andric static double GetApproxValue(const llvm::APFloat &F) {
4305ffd83dbSDimitry Andric   llvm::APFloat V = F;
4315ffd83dbSDimitry Andric   bool ignored;
4325ffd83dbSDimitry Andric   V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven,
4335ffd83dbSDimitry Andric             &ignored);
4345ffd83dbSDimitry Andric   return V.convertToDouble();
4355ffd83dbSDimitry Andric }
4365ffd83dbSDimitry Andric 
4375ffd83dbSDimitry Andric /// True if the \p APValue \p Value can be folded onto the current line.
isSimpleAPValue(const APValue & Value)4385ffd83dbSDimitry Andric static bool isSimpleAPValue(const APValue &Value) {
4395ffd83dbSDimitry Andric   switch (Value.getKind()) {
4405ffd83dbSDimitry Andric   case APValue::None:
4415ffd83dbSDimitry Andric   case APValue::Indeterminate:
4425ffd83dbSDimitry Andric   case APValue::Int:
4435ffd83dbSDimitry Andric   case APValue::Float:
4445ffd83dbSDimitry Andric   case APValue::FixedPoint:
4455ffd83dbSDimitry Andric   case APValue::ComplexInt:
4465ffd83dbSDimitry Andric   case APValue::ComplexFloat:
4475ffd83dbSDimitry Andric   case APValue::LValue:
4485ffd83dbSDimitry Andric   case APValue::MemberPointer:
4495ffd83dbSDimitry Andric   case APValue::AddrLabelDiff:
4505ffd83dbSDimitry Andric     return true;
4515ffd83dbSDimitry Andric   case APValue::Vector:
4525ffd83dbSDimitry Andric   case APValue::Array:
4535ffd83dbSDimitry Andric   case APValue::Struct:
4545ffd83dbSDimitry Andric     return false;
4555ffd83dbSDimitry Andric   case APValue::Union:
4565ffd83dbSDimitry Andric     return isSimpleAPValue(Value.getUnionValue());
4575ffd83dbSDimitry Andric   }
4585ffd83dbSDimitry Andric   llvm_unreachable("unexpected APValue kind!");
4595ffd83dbSDimitry Andric }
4605ffd83dbSDimitry Andric 
4615ffd83dbSDimitry Andric /// Dump the children of the \p APValue \p Value.
4625ffd83dbSDimitry Andric ///
4635ffd83dbSDimitry Andric /// \param[in] Value          The \p APValue to visit
4645ffd83dbSDimitry Andric /// \param[in] Ty             The \p QualType passed to \p Visit
4655ffd83dbSDimitry Andric ///
4665ffd83dbSDimitry Andric /// \param[in] IdxToChildFun  A function mapping an \p APValue and an index
4675ffd83dbSDimitry Andric ///                           to one of the child of the \p APValue
4685ffd83dbSDimitry Andric ///
4695ffd83dbSDimitry Andric /// \param[in] NumChildren    \p IdxToChildFun will be called on \p Value with
4705ffd83dbSDimitry Andric ///                           the indices in the range \p [0,NumChildren(
4715ffd83dbSDimitry Andric ///
4725ffd83dbSDimitry Andric /// \param[in] LabelSingular  The label to use on a line with a single child
4735ffd83dbSDimitry Andric /// \param[in] LabelPlurial   The label to use on a line with multiple children
dumpAPValueChildren(const APValue & Value,QualType Ty,const APValue & (* IdxToChildFun)(const APValue &,unsigned),unsigned NumChildren,StringRef LabelSingular,StringRef LabelPlurial)4745ffd83dbSDimitry Andric void TextNodeDumper::dumpAPValueChildren(
4755ffd83dbSDimitry Andric     const APValue &Value, QualType Ty,
4765ffd83dbSDimitry Andric     const APValue &(*IdxToChildFun)(const APValue &, unsigned),
4775ffd83dbSDimitry Andric     unsigned NumChildren, StringRef LabelSingular, StringRef LabelPlurial) {
4785ffd83dbSDimitry Andric   // To save some vertical space we print up to MaxChildrenPerLine APValues
4795ffd83dbSDimitry Andric   // considered to be simple (by isSimpleAPValue) on a single line.
4805ffd83dbSDimitry Andric   constexpr unsigned MaxChildrenPerLine = 4;
4815ffd83dbSDimitry Andric   unsigned I = 0;
4825ffd83dbSDimitry Andric   while (I < NumChildren) {
4835ffd83dbSDimitry Andric     unsigned J = I;
4845ffd83dbSDimitry Andric     while (J < NumChildren) {
4855ffd83dbSDimitry Andric       if (isSimpleAPValue(IdxToChildFun(Value, J)) &&
4865ffd83dbSDimitry Andric           (J - I < MaxChildrenPerLine)) {
4875ffd83dbSDimitry Andric         ++J;
4885ffd83dbSDimitry Andric         continue;
4895ffd83dbSDimitry Andric       }
4905ffd83dbSDimitry Andric       break;
4915ffd83dbSDimitry Andric     }
4925ffd83dbSDimitry Andric 
4935ffd83dbSDimitry Andric     J = std::max(I + 1, J);
4945ffd83dbSDimitry Andric 
4955ffd83dbSDimitry Andric     // Print [I,J) on a single line.
4965ffd83dbSDimitry Andric     AddChild(J - I > 1 ? LabelPlurial : LabelSingular, [=]() {
4975ffd83dbSDimitry Andric       for (unsigned X = I; X < J; ++X) {
4985ffd83dbSDimitry Andric         Visit(IdxToChildFun(Value, X), Ty);
4995ffd83dbSDimitry Andric         if (X + 1 != J)
5005ffd83dbSDimitry Andric           OS << ", ";
5015ffd83dbSDimitry Andric       }
5025ffd83dbSDimitry Andric     });
5035ffd83dbSDimitry Andric     I = J;
5045ffd83dbSDimitry Andric   }
5055ffd83dbSDimitry Andric }
5065ffd83dbSDimitry Andric 
Visit(const APValue & Value,QualType Ty)5075ffd83dbSDimitry Andric void TextNodeDumper::Visit(const APValue &Value, QualType Ty) {
5085ffd83dbSDimitry Andric   ColorScope Color(OS, ShowColors, ValueKindColor);
5095ffd83dbSDimitry Andric   switch (Value.getKind()) {
5105ffd83dbSDimitry Andric   case APValue::None:
5115ffd83dbSDimitry Andric     OS << "None";
5125ffd83dbSDimitry Andric     return;
5135ffd83dbSDimitry Andric   case APValue::Indeterminate:
5145ffd83dbSDimitry Andric     OS << "Indeterminate";
5155ffd83dbSDimitry Andric     return;
5165ffd83dbSDimitry Andric   case APValue::Int:
5175ffd83dbSDimitry Andric     OS << "Int ";
5185ffd83dbSDimitry Andric     {
5195ffd83dbSDimitry Andric       ColorScope Color(OS, ShowColors, ValueColor);
5205ffd83dbSDimitry Andric       OS << Value.getInt();
5215ffd83dbSDimitry Andric     }
5225ffd83dbSDimitry Andric     return;
5235ffd83dbSDimitry Andric   case APValue::Float:
5245ffd83dbSDimitry Andric     OS << "Float ";
5255ffd83dbSDimitry Andric     {
5265ffd83dbSDimitry Andric       ColorScope Color(OS, ShowColors, ValueColor);
5275ffd83dbSDimitry Andric       OS << GetApproxValue(Value.getFloat());
5285ffd83dbSDimitry Andric     }
5295ffd83dbSDimitry Andric     return;
5305ffd83dbSDimitry Andric   case APValue::FixedPoint:
5315ffd83dbSDimitry Andric     OS << "FixedPoint ";
5325ffd83dbSDimitry Andric     {
5335ffd83dbSDimitry Andric       ColorScope Color(OS, ShowColors, ValueColor);
5345ffd83dbSDimitry Andric       OS << Value.getFixedPoint();
5355ffd83dbSDimitry Andric     }
5365ffd83dbSDimitry Andric     return;
5375ffd83dbSDimitry Andric   case APValue::Vector: {
5385ffd83dbSDimitry Andric     unsigned VectorLength = Value.getVectorLength();
5395ffd83dbSDimitry Andric     OS << "Vector length=" << VectorLength;
5405ffd83dbSDimitry Andric 
5415ffd83dbSDimitry Andric     dumpAPValueChildren(
5425ffd83dbSDimitry Andric         Value, Ty,
5435ffd83dbSDimitry Andric         [](const APValue &Value, unsigned Index) -> const APValue & {
5445ffd83dbSDimitry Andric           return Value.getVectorElt(Index);
5455ffd83dbSDimitry Andric         },
5465ffd83dbSDimitry Andric         VectorLength, "element", "elements");
5475ffd83dbSDimitry Andric     return;
5485ffd83dbSDimitry Andric   }
5495ffd83dbSDimitry Andric   case APValue::ComplexInt:
5505ffd83dbSDimitry Andric     OS << "ComplexInt ";
5515ffd83dbSDimitry Andric     {
5525ffd83dbSDimitry Andric       ColorScope Color(OS, ShowColors, ValueColor);
5535ffd83dbSDimitry Andric       OS << Value.getComplexIntReal() << " + " << Value.getComplexIntImag()
5545ffd83dbSDimitry Andric          << 'i';
5555ffd83dbSDimitry Andric     }
5565ffd83dbSDimitry Andric     return;
5575ffd83dbSDimitry Andric   case APValue::ComplexFloat:
5585ffd83dbSDimitry Andric     OS << "ComplexFloat ";
5595ffd83dbSDimitry Andric     {
5605ffd83dbSDimitry Andric       ColorScope Color(OS, ShowColors, ValueColor);
5615ffd83dbSDimitry Andric       OS << GetApproxValue(Value.getComplexFloatReal()) << " + "
5625ffd83dbSDimitry Andric          << GetApproxValue(Value.getComplexFloatImag()) << 'i';
5635ffd83dbSDimitry Andric     }
5645ffd83dbSDimitry Andric     return;
5655ffd83dbSDimitry Andric   case APValue::LValue:
5665ffd83dbSDimitry Andric     (void)Context;
5675ffd83dbSDimitry Andric     OS << "LValue <todo>";
5685ffd83dbSDimitry Andric     return;
5695ffd83dbSDimitry Andric   case APValue::Array: {
5705ffd83dbSDimitry Andric     unsigned ArraySize = Value.getArraySize();
5715ffd83dbSDimitry Andric     unsigned NumInitializedElements = Value.getArrayInitializedElts();
5725ffd83dbSDimitry Andric     OS << "Array size=" << ArraySize;
5735ffd83dbSDimitry Andric 
5745ffd83dbSDimitry Andric     dumpAPValueChildren(
5755ffd83dbSDimitry Andric         Value, Ty,
5765ffd83dbSDimitry Andric         [](const APValue &Value, unsigned Index) -> const APValue & {
5775ffd83dbSDimitry Andric           return Value.getArrayInitializedElt(Index);
5785ffd83dbSDimitry Andric         },
5795ffd83dbSDimitry Andric         NumInitializedElements, "element", "elements");
5805ffd83dbSDimitry Andric 
5815ffd83dbSDimitry Andric     if (Value.hasArrayFiller()) {
5825ffd83dbSDimitry Andric       AddChild("filler", [=] {
5835ffd83dbSDimitry Andric         {
5845ffd83dbSDimitry Andric           ColorScope Color(OS, ShowColors, ValueColor);
5855ffd83dbSDimitry Andric           OS << ArraySize - NumInitializedElements << " x ";
5865ffd83dbSDimitry Andric         }
5875ffd83dbSDimitry Andric         Visit(Value.getArrayFiller(), Ty);
5885ffd83dbSDimitry Andric       });
5895ffd83dbSDimitry Andric     }
5905ffd83dbSDimitry Andric 
5915ffd83dbSDimitry Andric     return;
5925ffd83dbSDimitry Andric   }
5935ffd83dbSDimitry Andric   case APValue::Struct: {
5945ffd83dbSDimitry Andric     OS << "Struct";
5955ffd83dbSDimitry Andric 
5965ffd83dbSDimitry Andric     dumpAPValueChildren(
5975ffd83dbSDimitry Andric         Value, Ty,
5985ffd83dbSDimitry Andric         [](const APValue &Value, unsigned Index) -> const APValue & {
5995ffd83dbSDimitry Andric           return Value.getStructBase(Index);
6005ffd83dbSDimitry Andric         },
6015ffd83dbSDimitry Andric         Value.getStructNumBases(), "base", "bases");
6025ffd83dbSDimitry Andric 
6035ffd83dbSDimitry Andric     dumpAPValueChildren(
6045ffd83dbSDimitry Andric         Value, Ty,
6055ffd83dbSDimitry Andric         [](const APValue &Value, unsigned Index) -> const APValue & {
6065ffd83dbSDimitry Andric           return Value.getStructField(Index);
6075ffd83dbSDimitry Andric         },
6085ffd83dbSDimitry Andric         Value.getStructNumFields(), "field", "fields");
6095ffd83dbSDimitry Andric 
6105ffd83dbSDimitry Andric     return;
6115ffd83dbSDimitry Andric   }
6125ffd83dbSDimitry Andric   case APValue::Union: {
6135ffd83dbSDimitry Andric     OS << "Union";
6145ffd83dbSDimitry Andric     {
6155ffd83dbSDimitry Andric       ColorScope Color(OS, ShowColors, ValueColor);
6165ffd83dbSDimitry Andric       if (const FieldDecl *FD = Value.getUnionField())
6175ffd83dbSDimitry Andric         OS << " ." << *cast<NamedDecl>(FD);
6185ffd83dbSDimitry Andric     }
6195ffd83dbSDimitry Andric     // If the union value is considered to be simple, fold it into the
6205ffd83dbSDimitry Andric     // current line to save some vertical space.
6215ffd83dbSDimitry Andric     const APValue &UnionValue = Value.getUnionValue();
6225ffd83dbSDimitry Andric     if (isSimpleAPValue(UnionValue)) {
6235ffd83dbSDimitry Andric       OS << ' ';
6245ffd83dbSDimitry Andric       Visit(UnionValue, Ty);
6255ffd83dbSDimitry Andric     } else {
6265ffd83dbSDimitry Andric       AddChild([=] { Visit(UnionValue, Ty); });
6275ffd83dbSDimitry Andric     }
6285ffd83dbSDimitry Andric 
6295ffd83dbSDimitry Andric     return;
6305ffd83dbSDimitry Andric   }
6315ffd83dbSDimitry Andric   case APValue::MemberPointer:
6325ffd83dbSDimitry Andric     OS << "MemberPointer <todo>";
6335ffd83dbSDimitry Andric     return;
6345ffd83dbSDimitry Andric   case APValue::AddrLabelDiff:
6355ffd83dbSDimitry Andric     OS << "AddrLabelDiff <todo>";
6365ffd83dbSDimitry Andric     return;
6375ffd83dbSDimitry Andric   }
6385ffd83dbSDimitry Andric   llvm_unreachable("Unknown APValue kind!");
6395ffd83dbSDimitry Andric }
6405ffd83dbSDimitry Andric 
dumpPointer(const void * Ptr)6410b57cec5SDimitry Andric void TextNodeDumper::dumpPointer(const void *Ptr) {
6420b57cec5SDimitry Andric   ColorScope Color(OS, ShowColors, AddressColor);
6430b57cec5SDimitry Andric   OS << ' ' << Ptr;
6440b57cec5SDimitry Andric }
6450b57cec5SDimitry Andric 
dumpLocation(SourceLocation Loc)6460b57cec5SDimitry Andric void TextNodeDumper::dumpLocation(SourceLocation Loc) {
6470b57cec5SDimitry Andric   if (!SM)
6480b57cec5SDimitry Andric     return;
6490b57cec5SDimitry Andric 
6500b57cec5SDimitry Andric   ColorScope Color(OS, ShowColors, LocationColor);
6510b57cec5SDimitry Andric   SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
6520b57cec5SDimitry Andric 
6530b57cec5SDimitry Andric   // The general format we print out is filename:line:col, but we drop pieces
6540b57cec5SDimitry Andric   // that haven't changed since the last loc printed.
6550b57cec5SDimitry Andric   PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
6560b57cec5SDimitry Andric 
6570b57cec5SDimitry Andric   if (PLoc.isInvalid()) {
6580b57cec5SDimitry Andric     OS << "<invalid sloc>";
6590b57cec5SDimitry Andric     return;
6600b57cec5SDimitry Andric   }
6610b57cec5SDimitry Andric 
6620b57cec5SDimitry Andric   if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
6630b57cec5SDimitry Andric     OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':'
6640b57cec5SDimitry Andric        << PLoc.getColumn();
6650b57cec5SDimitry Andric     LastLocFilename = PLoc.getFilename();
6660b57cec5SDimitry Andric     LastLocLine = PLoc.getLine();
6670b57cec5SDimitry Andric   } else if (PLoc.getLine() != LastLocLine) {
6680b57cec5SDimitry Andric     OS << "line" << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
6690b57cec5SDimitry Andric     LastLocLine = PLoc.getLine();
6700b57cec5SDimitry Andric   } else {
6710b57cec5SDimitry Andric     OS << "col" << ':' << PLoc.getColumn();
6720b57cec5SDimitry Andric   }
6730b57cec5SDimitry Andric }
6740b57cec5SDimitry Andric 
dumpSourceRange(SourceRange R)6750b57cec5SDimitry Andric void TextNodeDumper::dumpSourceRange(SourceRange R) {
6760b57cec5SDimitry Andric   // Can't translate locations if a SourceManager isn't available.
6770b57cec5SDimitry Andric   if (!SM)
6780b57cec5SDimitry Andric     return;
6790b57cec5SDimitry Andric 
6800b57cec5SDimitry Andric   OS << " <";
6810b57cec5SDimitry Andric   dumpLocation(R.getBegin());
6820b57cec5SDimitry Andric   if (R.getBegin() != R.getEnd()) {
6830b57cec5SDimitry Andric     OS << ", ";
6840b57cec5SDimitry Andric     dumpLocation(R.getEnd());
6850b57cec5SDimitry Andric   }
6860b57cec5SDimitry Andric   OS << ">";
6870b57cec5SDimitry Andric 
6880b57cec5SDimitry Andric   // <t2.c:123:421[blah], t2.c:412:321>
6890b57cec5SDimitry Andric }
6900b57cec5SDimitry Andric 
dumpBareType(QualType T,bool Desugar)6910b57cec5SDimitry Andric void TextNodeDumper::dumpBareType(QualType T, bool Desugar) {
6920b57cec5SDimitry Andric   ColorScope Color(OS, ShowColors, TypeColor);
6930b57cec5SDimitry Andric 
6940b57cec5SDimitry Andric   SplitQualType T_split = T.split();
6955f757f3fSDimitry Andric   std::string T_str = QualType::getAsString(T_split, PrintPolicy);
6965f757f3fSDimitry Andric   OS << "'" << T_str << "'";
6970b57cec5SDimitry Andric 
6980b57cec5SDimitry Andric   if (Desugar && !T.isNull()) {
6995f757f3fSDimitry Andric     // If the type is sugared, also dump a (shallow) desugared type when
7005f757f3fSDimitry Andric     // it is visibly different.
7010b57cec5SDimitry Andric     SplitQualType D_split = T.getSplitDesugaredType();
7025f757f3fSDimitry Andric     if (T_split != D_split) {
7035f757f3fSDimitry Andric       std::string D_str = QualType::getAsString(D_split, PrintPolicy);
7045f757f3fSDimitry Andric       if (T_str != D_str)
7050b57cec5SDimitry Andric         OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'";
7060b57cec5SDimitry Andric     }
7070b57cec5SDimitry Andric   }
7085f757f3fSDimitry Andric }
7090b57cec5SDimitry Andric 
dumpType(QualType T)7100b57cec5SDimitry Andric void TextNodeDumper::dumpType(QualType T) {
7110b57cec5SDimitry Andric   OS << ' ';
7120b57cec5SDimitry Andric   dumpBareType(T);
7130b57cec5SDimitry Andric }
7140b57cec5SDimitry Andric 
dumpBareDeclRef(const Decl * D)7150b57cec5SDimitry Andric void TextNodeDumper::dumpBareDeclRef(const Decl *D) {
7160b57cec5SDimitry Andric   if (!D) {
7170b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, NullColor);
7180b57cec5SDimitry Andric     OS << "<<<NULL>>>";
7190b57cec5SDimitry Andric     return;
7200b57cec5SDimitry Andric   }
7210b57cec5SDimitry Andric 
7220b57cec5SDimitry Andric   {
7230b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, DeclKindNameColor);
7240b57cec5SDimitry Andric     OS << D->getDeclKindName();
7250b57cec5SDimitry Andric   }
7260b57cec5SDimitry Andric   dumpPointer(D);
7270b57cec5SDimitry Andric 
7280b57cec5SDimitry Andric   if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
7290b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, DeclNameColor);
7300b57cec5SDimitry Andric     OS << " '" << ND->getDeclName() << '\'';
7310b57cec5SDimitry Andric   }
7320b57cec5SDimitry Andric 
7330b57cec5SDimitry Andric   if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
7340b57cec5SDimitry Andric     dumpType(VD->getType());
7350b57cec5SDimitry Andric }
7360b57cec5SDimitry Andric 
dumpName(const NamedDecl * ND)7370b57cec5SDimitry Andric void TextNodeDumper::dumpName(const NamedDecl *ND) {
7380b57cec5SDimitry Andric   if (ND->getDeclName()) {
7390b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, DeclNameColor);
740e8d8bef9SDimitry Andric     OS << ' ' << ND->getDeclName();
7410b57cec5SDimitry Andric   }
7420b57cec5SDimitry Andric }
7430b57cec5SDimitry Andric 
dumpAccessSpecifier(AccessSpecifier AS)7440b57cec5SDimitry Andric void TextNodeDumper::dumpAccessSpecifier(AccessSpecifier AS) {
7455ffd83dbSDimitry Andric   const auto AccessSpelling = getAccessSpelling(AS);
7465ffd83dbSDimitry Andric   if (AccessSpelling.empty())
7475ffd83dbSDimitry Andric     return;
7485ffd83dbSDimitry Andric   OS << AccessSpelling;
7490b57cec5SDimitry Andric }
7505ffd83dbSDimitry Andric 
dumpCleanupObject(const ExprWithCleanups::CleanupObject & C)7515ffd83dbSDimitry Andric void TextNodeDumper::dumpCleanupObject(
7525ffd83dbSDimitry Andric     const ExprWithCleanups::CleanupObject &C) {
7535ffd83dbSDimitry Andric   if (auto *BD = C.dyn_cast<BlockDecl *>())
7545ffd83dbSDimitry Andric     dumpDeclRef(BD, "cleanup");
7555ffd83dbSDimitry Andric   else if (auto *CLE = C.dyn_cast<CompoundLiteralExpr *>())
7565ffd83dbSDimitry Andric     AddChild([=] {
7575ffd83dbSDimitry Andric       OS << "cleanup ";
7585ffd83dbSDimitry Andric       {
7595ffd83dbSDimitry Andric         ColorScope Color(OS, ShowColors, StmtColor);
7605ffd83dbSDimitry Andric         OS << CLE->getStmtClassName();
7615ffd83dbSDimitry Andric       }
7625ffd83dbSDimitry Andric       dumpPointer(CLE);
7635ffd83dbSDimitry Andric     });
7645ffd83dbSDimitry Andric   else
7655ffd83dbSDimitry Andric     llvm_unreachable("unexpected cleanup type");
7660b57cec5SDimitry Andric }
7670b57cec5SDimitry Andric 
dumpTemplateSpecializationKind(TemplateSpecializationKind TSK)7685f757f3fSDimitry Andric void clang::TextNodeDumper::dumpTemplateSpecializationKind(
7695f757f3fSDimitry Andric     TemplateSpecializationKind TSK) {
7705f757f3fSDimitry Andric   switch (TSK) {
7715f757f3fSDimitry Andric   case TSK_Undeclared:
7725f757f3fSDimitry Andric     break;
7735f757f3fSDimitry Andric   case TSK_ImplicitInstantiation:
7745f757f3fSDimitry Andric     OS << " implicit_instantiation";
7755f757f3fSDimitry Andric     break;
7765f757f3fSDimitry Andric   case TSK_ExplicitSpecialization:
7775f757f3fSDimitry Andric     OS << " explicit_specialization";
7785f757f3fSDimitry Andric     break;
7795f757f3fSDimitry Andric   case TSK_ExplicitInstantiationDeclaration:
7805f757f3fSDimitry Andric     OS << " explicit_instantiation_declaration";
7815f757f3fSDimitry Andric     break;
7825f757f3fSDimitry Andric   case TSK_ExplicitInstantiationDefinition:
7835f757f3fSDimitry Andric     OS << " explicit_instantiation_definition";
7845f757f3fSDimitry Andric     break;
7855f757f3fSDimitry Andric   }
7865f757f3fSDimitry Andric }
7875f757f3fSDimitry Andric 
dumpNestedNameSpecifier(const NestedNameSpecifier * NNS)7885f757f3fSDimitry Andric void clang::TextNodeDumper::dumpNestedNameSpecifier(const NestedNameSpecifier *NNS) {
7895f757f3fSDimitry Andric   if (!NNS)
7905f757f3fSDimitry Andric     return;
7915f757f3fSDimitry Andric 
7925f757f3fSDimitry Andric   AddChild([=] {
7935f757f3fSDimitry Andric     OS << "NestedNameSpecifier";
7945f757f3fSDimitry Andric 
7955f757f3fSDimitry Andric     switch (NNS->getKind()) {
7965f757f3fSDimitry Andric     case NestedNameSpecifier::Identifier:
7975f757f3fSDimitry Andric       OS << " Identifier";
7985f757f3fSDimitry Andric       OS << " '" << NNS->getAsIdentifier()->getName() << "'";
7995f757f3fSDimitry Andric       break;
8005f757f3fSDimitry Andric     case NestedNameSpecifier::Namespace:
8015f757f3fSDimitry Andric       OS << " "; // "Namespace" is printed as the decl kind.
8025f757f3fSDimitry Andric       dumpBareDeclRef(NNS->getAsNamespace());
8035f757f3fSDimitry Andric       break;
8045f757f3fSDimitry Andric     case NestedNameSpecifier::NamespaceAlias:
8055f757f3fSDimitry Andric       OS << " "; // "NamespaceAlias" is printed as the decl kind.
8065f757f3fSDimitry Andric       dumpBareDeclRef(NNS->getAsNamespaceAlias());
8075f757f3fSDimitry Andric       break;
8085f757f3fSDimitry Andric     case NestedNameSpecifier::TypeSpec:
8095f757f3fSDimitry Andric       OS << " TypeSpec";
8105f757f3fSDimitry Andric       dumpType(QualType(NNS->getAsType(), 0));
8115f757f3fSDimitry Andric       break;
8125f757f3fSDimitry Andric     case NestedNameSpecifier::TypeSpecWithTemplate:
8135f757f3fSDimitry Andric       OS << " TypeSpecWithTemplate";
8145f757f3fSDimitry Andric       dumpType(QualType(NNS->getAsType(), 0));
8155f757f3fSDimitry Andric       break;
8165f757f3fSDimitry Andric     case NestedNameSpecifier::Global:
8175f757f3fSDimitry Andric       OS << " Global";
8185f757f3fSDimitry Andric       break;
8195f757f3fSDimitry Andric     case NestedNameSpecifier::Super:
8205f757f3fSDimitry Andric       OS << " Super";
8215f757f3fSDimitry Andric       break;
8225f757f3fSDimitry Andric     }
8235f757f3fSDimitry Andric 
8245f757f3fSDimitry Andric     dumpNestedNameSpecifier(NNS->getPrefix());
8255f757f3fSDimitry Andric   });
8265f757f3fSDimitry Andric }
8275f757f3fSDimitry Andric 
dumpDeclRef(const Decl * D,StringRef Label)8280b57cec5SDimitry Andric void TextNodeDumper::dumpDeclRef(const Decl *D, StringRef Label) {
8290b57cec5SDimitry Andric   if (!D)
8300b57cec5SDimitry Andric     return;
8310b57cec5SDimitry Andric 
8320b57cec5SDimitry Andric   AddChild([=] {
8330b57cec5SDimitry Andric     if (!Label.empty())
8340b57cec5SDimitry Andric       OS << Label << ' ';
8350b57cec5SDimitry Andric     dumpBareDeclRef(D);
8360b57cec5SDimitry Andric   });
8370b57cec5SDimitry Andric }
8380b57cec5SDimitry Andric 
getCommandName(unsigned CommandID)8390b57cec5SDimitry Andric const char *TextNodeDumper::getCommandName(unsigned CommandID) {
8400b57cec5SDimitry Andric   if (Traits)
8410b57cec5SDimitry Andric     return Traits->getCommandInfo(CommandID)->Name;
8420b57cec5SDimitry Andric   const comments::CommandInfo *Info =
8430b57cec5SDimitry Andric       comments::CommandTraits::getBuiltinCommandInfo(CommandID);
8440b57cec5SDimitry Andric   if (Info)
8450b57cec5SDimitry Andric     return Info->Name;
8460b57cec5SDimitry Andric   return "<not a builtin command>";
8470b57cec5SDimitry Andric }
8480b57cec5SDimitry Andric 
printFPOptions(FPOptionsOverride FPO)849e8d8bef9SDimitry Andric void TextNodeDumper::printFPOptions(FPOptionsOverride FPO) {
850e8d8bef9SDimitry Andric #define OPTION(NAME, TYPE, WIDTH, PREVIOUS)                                    \
851e8d8bef9SDimitry Andric   if (FPO.has##NAME##Override())                                               \
852e8d8bef9SDimitry Andric     OS << " " #NAME "=" << FPO.get##NAME##Override();
853e8d8bef9SDimitry Andric #include "clang/Basic/FPOptions.def"
854e8d8bef9SDimitry Andric }
855e8d8bef9SDimitry Andric 
visitTextComment(const comments::TextComment * C,const comments::FullComment *)8560b57cec5SDimitry Andric void TextNodeDumper::visitTextComment(const comments::TextComment *C,
8570b57cec5SDimitry Andric                                       const comments::FullComment *) {
8580b57cec5SDimitry Andric   OS << " Text=\"" << C->getText() << "\"";
8590b57cec5SDimitry Andric }
8600b57cec5SDimitry Andric 
visitInlineCommandComment(const comments::InlineCommandComment * C,const comments::FullComment *)8610b57cec5SDimitry Andric void TextNodeDumper::visitInlineCommandComment(
8620b57cec5SDimitry Andric     const comments::InlineCommandComment *C, const comments::FullComment *) {
8630b57cec5SDimitry Andric   OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
8640b57cec5SDimitry Andric   switch (C->getRenderKind()) {
8655f757f3fSDimitry Andric   case comments::InlineCommandRenderKind::Normal:
8660b57cec5SDimitry Andric     OS << " RenderNormal";
8670b57cec5SDimitry Andric     break;
8685f757f3fSDimitry Andric   case comments::InlineCommandRenderKind::Bold:
8690b57cec5SDimitry Andric     OS << " RenderBold";
8700b57cec5SDimitry Andric     break;
8715f757f3fSDimitry Andric   case comments::InlineCommandRenderKind::Monospaced:
8720b57cec5SDimitry Andric     OS << " RenderMonospaced";
8730b57cec5SDimitry Andric     break;
8745f757f3fSDimitry Andric   case comments::InlineCommandRenderKind::Emphasized:
8750b57cec5SDimitry Andric     OS << " RenderEmphasized";
8760b57cec5SDimitry Andric     break;
8775f757f3fSDimitry Andric   case comments::InlineCommandRenderKind::Anchor:
878480093f4SDimitry Andric     OS << " RenderAnchor";
879480093f4SDimitry Andric     break;
8800b57cec5SDimitry Andric   }
8810b57cec5SDimitry Andric 
8820b57cec5SDimitry Andric   for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
8830b57cec5SDimitry Andric     OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
8840b57cec5SDimitry Andric }
8850b57cec5SDimitry Andric 
visitHTMLStartTagComment(const comments::HTMLStartTagComment * C,const comments::FullComment *)8860b57cec5SDimitry Andric void TextNodeDumper::visitHTMLStartTagComment(
8870b57cec5SDimitry Andric     const comments::HTMLStartTagComment *C, const comments::FullComment *) {
8880b57cec5SDimitry Andric   OS << " Name=\"" << C->getTagName() << "\"";
8890b57cec5SDimitry Andric   if (C->getNumAttrs() != 0) {
8900b57cec5SDimitry Andric     OS << " Attrs: ";
8910b57cec5SDimitry Andric     for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
8920b57cec5SDimitry Andric       const comments::HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
8930b57cec5SDimitry Andric       OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
8940b57cec5SDimitry Andric     }
8950b57cec5SDimitry Andric   }
8960b57cec5SDimitry Andric   if (C->isSelfClosing())
8970b57cec5SDimitry Andric     OS << " SelfClosing";
8980b57cec5SDimitry Andric }
8990b57cec5SDimitry Andric 
visitHTMLEndTagComment(const comments::HTMLEndTagComment * C,const comments::FullComment *)9000b57cec5SDimitry Andric void TextNodeDumper::visitHTMLEndTagComment(
9010b57cec5SDimitry Andric     const comments::HTMLEndTagComment *C, const comments::FullComment *) {
9020b57cec5SDimitry Andric   OS << " Name=\"" << C->getTagName() << "\"";
9030b57cec5SDimitry Andric }
9040b57cec5SDimitry Andric 
visitBlockCommandComment(const comments::BlockCommandComment * C,const comments::FullComment *)9050b57cec5SDimitry Andric void TextNodeDumper::visitBlockCommandComment(
9060b57cec5SDimitry Andric     const comments::BlockCommandComment *C, const comments::FullComment *) {
9070b57cec5SDimitry Andric   OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
9080b57cec5SDimitry Andric   for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
9090b57cec5SDimitry Andric     OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
9100b57cec5SDimitry Andric }
9110b57cec5SDimitry Andric 
visitParamCommandComment(const comments::ParamCommandComment * C,const comments::FullComment * FC)9120b57cec5SDimitry Andric void TextNodeDumper::visitParamCommandComment(
9130b57cec5SDimitry Andric     const comments::ParamCommandComment *C, const comments::FullComment *FC) {
9140b57cec5SDimitry Andric   OS << " "
9150b57cec5SDimitry Andric      << comments::ParamCommandComment::getDirectionAsString(C->getDirection());
9160b57cec5SDimitry Andric 
9170b57cec5SDimitry Andric   if (C->isDirectionExplicit())
9180b57cec5SDimitry Andric     OS << " explicitly";
9190b57cec5SDimitry Andric   else
9200b57cec5SDimitry Andric     OS << " implicitly";
9210b57cec5SDimitry Andric 
9220b57cec5SDimitry Andric   if (C->hasParamName()) {
9230b57cec5SDimitry Andric     if (C->isParamIndexValid())
9240b57cec5SDimitry Andric       OS << " Param=\"" << C->getParamName(FC) << "\"";
9250b57cec5SDimitry Andric     else
9260b57cec5SDimitry Andric       OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
9270b57cec5SDimitry Andric   }
9280b57cec5SDimitry Andric 
9290b57cec5SDimitry Andric   if (C->isParamIndexValid() && !C->isVarArgParam())
9300b57cec5SDimitry Andric     OS << " ParamIndex=" << C->getParamIndex();
9310b57cec5SDimitry Andric }
9320b57cec5SDimitry Andric 
visitTParamCommandComment(const comments::TParamCommandComment * C,const comments::FullComment * FC)9330b57cec5SDimitry Andric void TextNodeDumper::visitTParamCommandComment(
9340b57cec5SDimitry Andric     const comments::TParamCommandComment *C, const comments::FullComment *FC) {
9350b57cec5SDimitry Andric   if (C->hasParamName()) {
9360b57cec5SDimitry Andric     if (C->isPositionValid())
9370b57cec5SDimitry Andric       OS << " Param=\"" << C->getParamName(FC) << "\"";
9380b57cec5SDimitry Andric     else
9390b57cec5SDimitry Andric       OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
9400b57cec5SDimitry Andric   }
9410b57cec5SDimitry Andric 
9420b57cec5SDimitry Andric   if (C->isPositionValid()) {
9430b57cec5SDimitry Andric     OS << " Position=<";
9440b57cec5SDimitry Andric     for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
9450b57cec5SDimitry Andric       OS << C->getIndex(i);
9460b57cec5SDimitry Andric       if (i != e - 1)
9470b57cec5SDimitry Andric         OS << ", ";
9480b57cec5SDimitry Andric     }
9490b57cec5SDimitry Andric     OS << ">";
9500b57cec5SDimitry Andric   }
9510b57cec5SDimitry Andric }
9520b57cec5SDimitry Andric 
visitVerbatimBlockComment(const comments::VerbatimBlockComment * C,const comments::FullComment *)9530b57cec5SDimitry Andric void TextNodeDumper::visitVerbatimBlockComment(
9540b57cec5SDimitry Andric     const comments::VerbatimBlockComment *C, const comments::FullComment *) {
9550b57cec5SDimitry Andric   OS << " Name=\"" << getCommandName(C->getCommandID())
9560b57cec5SDimitry Andric      << "\""
9570b57cec5SDimitry Andric         " CloseName=\""
9580b57cec5SDimitry Andric      << C->getCloseName() << "\"";
9590b57cec5SDimitry Andric }
9600b57cec5SDimitry Andric 
visitVerbatimBlockLineComment(const comments::VerbatimBlockLineComment * C,const comments::FullComment *)9610b57cec5SDimitry Andric void TextNodeDumper::visitVerbatimBlockLineComment(
9620b57cec5SDimitry Andric     const comments::VerbatimBlockLineComment *C,
9630b57cec5SDimitry Andric     const comments::FullComment *) {
9640b57cec5SDimitry Andric   OS << " Text=\"" << C->getText() << "\"";
9650b57cec5SDimitry Andric }
9660b57cec5SDimitry Andric 
visitVerbatimLineComment(const comments::VerbatimLineComment * C,const comments::FullComment *)9670b57cec5SDimitry Andric void TextNodeDumper::visitVerbatimLineComment(
9680b57cec5SDimitry Andric     const comments::VerbatimLineComment *C, const comments::FullComment *) {
9690b57cec5SDimitry Andric   OS << " Text=\"" << C->getText() << "\"";
9700b57cec5SDimitry Andric }
9710b57cec5SDimitry Andric 
VisitNullTemplateArgument(const TemplateArgument &)9720b57cec5SDimitry Andric void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument &) {
9730b57cec5SDimitry Andric   OS << " null";
9740b57cec5SDimitry Andric }
9750b57cec5SDimitry Andric 
VisitTypeTemplateArgument(const TemplateArgument & TA)9760b57cec5SDimitry Andric void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) {
9770b57cec5SDimitry Andric   OS << " type";
9780b57cec5SDimitry Andric   dumpType(TA.getAsType());
9790b57cec5SDimitry Andric }
9800b57cec5SDimitry Andric 
VisitDeclarationTemplateArgument(const TemplateArgument & TA)9810b57cec5SDimitry Andric void TextNodeDumper::VisitDeclarationTemplateArgument(
9820b57cec5SDimitry Andric     const TemplateArgument &TA) {
9830b57cec5SDimitry Andric   OS << " decl";
9840b57cec5SDimitry Andric   dumpDeclRef(TA.getAsDecl());
9850b57cec5SDimitry Andric }
9860b57cec5SDimitry Andric 
VisitNullPtrTemplateArgument(const TemplateArgument &)9870b57cec5SDimitry Andric void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &) {
9880b57cec5SDimitry Andric   OS << " nullptr";
9890b57cec5SDimitry Andric }
9900b57cec5SDimitry Andric 
VisitIntegralTemplateArgument(const TemplateArgument & TA)9910b57cec5SDimitry Andric void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) {
9920b57cec5SDimitry Andric   OS << " integral " << TA.getAsIntegral();
9930b57cec5SDimitry Andric }
9940b57cec5SDimitry Andric 
VisitTemplateTemplateArgument(const TemplateArgument & TA)9950b57cec5SDimitry Andric void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) {
99681ad6265SDimitry Andric   if (TA.getAsTemplate().getKind() == TemplateName::UsingTemplate)
99781ad6265SDimitry Andric     OS << " using";
9980b57cec5SDimitry Andric   OS << " template ";
9990b57cec5SDimitry Andric   TA.getAsTemplate().dump(OS);
10000b57cec5SDimitry Andric }
10010b57cec5SDimitry Andric 
VisitTemplateExpansionTemplateArgument(const TemplateArgument & TA)10020b57cec5SDimitry Andric void TextNodeDumper::VisitTemplateExpansionTemplateArgument(
10030b57cec5SDimitry Andric     const TemplateArgument &TA) {
100481ad6265SDimitry Andric   if (TA.getAsTemplateOrTemplatePattern().getKind() ==
100581ad6265SDimitry Andric       TemplateName::UsingTemplate)
100681ad6265SDimitry Andric     OS << " using";
10070b57cec5SDimitry Andric   OS << " template expansion ";
10080b57cec5SDimitry Andric   TA.getAsTemplateOrTemplatePattern().dump(OS);
10090b57cec5SDimitry Andric }
10100b57cec5SDimitry Andric 
VisitExpressionTemplateArgument(const TemplateArgument &)10110b57cec5SDimitry Andric void TextNodeDumper::VisitExpressionTemplateArgument(const TemplateArgument &) {
10120b57cec5SDimitry Andric   OS << " expr";
10130b57cec5SDimitry Andric }
10140b57cec5SDimitry Andric 
VisitPackTemplateArgument(const TemplateArgument &)10150b57cec5SDimitry Andric void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &) {
10160b57cec5SDimitry Andric   OS << " pack";
10170b57cec5SDimitry Andric }
10180b57cec5SDimitry Andric 
dumpBasePath(raw_ostream & OS,const CastExpr * Node)10190b57cec5SDimitry Andric static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
10200b57cec5SDimitry Andric   if (Node->path_empty())
10210b57cec5SDimitry Andric     return;
10220b57cec5SDimitry Andric 
10230b57cec5SDimitry Andric   OS << " (";
10240b57cec5SDimitry Andric   bool First = true;
10250b57cec5SDimitry Andric   for (CastExpr::path_const_iterator I = Node->path_begin(),
10260b57cec5SDimitry Andric                                      E = Node->path_end();
10270b57cec5SDimitry Andric        I != E; ++I) {
10280b57cec5SDimitry Andric     const CXXBaseSpecifier *Base = *I;
10290b57cec5SDimitry Andric     if (!First)
10300b57cec5SDimitry Andric       OS << " -> ";
10310b57cec5SDimitry Andric 
1032a7dea167SDimitry Andric     const auto *RD =
1033a7dea167SDimitry Andric         cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl());
10340b57cec5SDimitry Andric 
10350b57cec5SDimitry Andric     if (Base->isVirtual())
10360b57cec5SDimitry Andric       OS << "virtual ";
10370b57cec5SDimitry Andric     OS << RD->getName();
10380b57cec5SDimitry Andric     First = false;
10390b57cec5SDimitry Andric   }
10400b57cec5SDimitry Andric 
10410b57cec5SDimitry Andric   OS << ')';
10420b57cec5SDimitry Andric }
10430b57cec5SDimitry Andric 
VisitIfStmt(const IfStmt * Node)10440b57cec5SDimitry Andric void TextNodeDumper::VisitIfStmt(const IfStmt *Node) {
10450b57cec5SDimitry Andric   if (Node->hasInitStorage())
10460b57cec5SDimitry Andric     OS << " has_init";
10470b57cec5SDimitry Andric   if (Node->hasVarStorage())
10480b57cec5SDimitry Andric     OS << " has_var";
10490b57cec5SDimitry Andric   if (Node->hasElseStorage())
10500b57cec5SDimitry Andric     OS << " has_else";
1051349cc55cSDimitry Andric   if (Node->isConstexpr())
1052349cc55cSDimitry Andric     OS << " constexpr";
1053349cc55cSDimitry Andric   if (Node->isConsteval()) {
1054349cc55cSDimitry Andric     OS << " ";
1055349cc55cSDimitry Andric     if (Node->isNegatedConsteval())
1056349cc55cSDimitry Andric       OS << "!";
1057349cc55cSDimitry Andric     OS << "consteval";
1058349cc55cSDimitry Andric   }
10590b57cec5SDimitry Andric }
10600b57cec5SDimitry Andric 
VisitSwitchStmt(const SwitchStmt * Node)10610b57cec5SDimitry Andric void TextNodeDumper::VisitSwitchStmt(const SwitchStmt *Node) {
10620b57cec5SDimitry Andric   if (Node->hasInitStorage())
10630b57cec5SDimitry Andric     OS << " has_init";
10640b57cec5SDimitry Andric   if (Node->hasVarStorage())
10650b57cec5SDimitry Andric     OS << " has_var";
10660b57cec5SDimitry Andric }
10670b57cec5SDimitry Andric 
VisitWhileStmt(const WhileStmt * Node)10680b57cec5SDimitry Andric void TextNodeDumper::VisitWhileStmt(const WhileStmt *Node) {
10690b57cec5SDimitry Andric   if (Node->hasVarStorage())
10700b57cec5SDimitry Andric     OS << " has_var";
10710b57cec5SDimitry Andric }
10720b57cec5SDimitry Andric 
VisitLabelStmt(const LabelStmt * Node)10730b57cec5SDimitry Andric void TextNodeDumper::VisitLabelStmt(const LabelStmt *Node) {
10740b57cec5SDimitry Andric   OS << " '" << Node->getName() << "'";
1075fe6060f1SDimitry Andric   if (Node->isSideEntry())
1076fe6060f1SDimitry Andric     OS << " side_entry";
10770b57cec5SDimitry Andric }
10780b57cec5SDimitry Andric 
VisitGotoStmt(const GotoStmt * Node)10790b57cec5SDimitry Andric void TextNodeDumper::VisitGotoStmt(const GotoStmt *Node) {
10800b57cec5SDimitry Andric   OS << " '" << Node->getLabel()->getName() << "'";
10810b57cec5SDimitry Andric   dumpPointer(Node->getLabel());
10820b57cec5SDimitry Andric }
10830b57cec5SDimitry Andric 
VisitCaseStmt(const CaseStmt * Node)10840b57cec5SDimitry Andric void TextNodeDumper::VisitCaseStmt(const CaseStmt *Node) {
10850b57cec5SDimitry Andric   if (Node->caseStmtIsGNURange())
10860b57cec5SDimitry Andric     OS << " gnu_range";
10870b57cec5SDimitry Andric }
10880b57cec5SDimitry Andric 
VisitReturnStmt(const ReturnStmt * Node)10895f757f3fSDimitry Andric void clang::TextNodeDumper::VisitReturnStmt(const ReturnStmt *Node) {
10905f757f3fSDimitry Andric   if (const VarDecl *Cand = Node->getNRVOCandidate()) {
10915f757f3fSDimitry Andric     OS << " nrvo_candidate(";
10925f757f3fSDimitry Andric     dumpBareDeclRef(Cand);
10935f757f3fSDimitry Andric     OS << ")";
10945f757f3fSDimitry Andric   }
10955f757f3fSDimitry Andric }
10965f757f3fSDimitry Andric 
VisitCoawaitExpr(const CoawaitExpr * Node)10971db9f3b2SDimitry Andric void clang::TextNodeDumper::VisitCoawaitExpr(const CoawaitExpr *Node) {
10981db9f3b2SDimitry Andric   if (Node->isImplicit())
10991db9f3b2SDimitry Andric     OS << " implicit";
11001db9f3b2SDimitry Andric }
11011db9f3b2SDimitry Andric 
VisitCoreturnStmt(const CoreturnStmt * Node)11021db9f3b2SDimitry Andric void clang::TextNodeDumper::VisitCoreturnStmt(const CoreturnStmt *Node) {
11031db9f3b2SDimitry Andric   if (Node->isImplicit())
11041db9f3b2SDimitry Andric     OS << " implicit";
11051db9f3b2SDimitry Andric }
11061db9f3b2SDimitry Andric 
VisitConstantExpr(const ConstantExpr * Node)11070b57cec5SDimitry Andric void TextNodeDumper::VisitConstantExpr(const ConstantExpr *Node) {
11085ffd83dbSDimitry Andric   if (Node->hasAPValueResult())
11095ffd83dbSDimitry Andric     AddChild("value",
11105ffd83dbSDimitry Andric              [=] { Visit(Node->getAPValueResult(), Node->getType()); });
11110b57cec5SDimitry Andric }
11120b57cec5SDimitry Andric 
VisitCallExpr(const CallExpr * Node)11130b57cec5SDimitry Andric void TextNodeDumper::VisitCallExpr(const CallExpr *Node) {
11140b57cec5SDimitry Andric   if (Node->usesADL())
11150b57cec5SDimitry Andric     OS << " adl";
1116e8d8bef9SDimitry Andric   if (Node->hasStoredFPFeatures())
1117e8d8bef9SDimitry Andric     printFPOptions(Node->getFPFeatures());
11180b57cec5SDimitry Andric }
11190b57cec5SDimitry Andric 
VisitCXXOperatorCallExpr(const CXXOperatorCallExpr * Node)11205ffd83dbSDimitry Andric void TextNodeDumper::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *Node) {
11215ffd83dbSDimitry Andric   const char *OperatorSpelling = clang::getOperatorSpelling(Node->getOperator());
11225ffd83dbSDimitry Andric   if (OperatorSpelling)
11235ffd83dbSDimitry Andric     OS << " '" << OperatorSpelling << "'";
11245ffd83dbSDimitry Andric 
11255ffd83dbSDimitry Andric   VisitCallExpr(Node);
11265ffd83dbSDimitry Andric }
11275ffd83dbSDimitry Andric 
VisitCastExpr(const CastExpr * Node)11280b57cec5SDimitry Andric void TextNodeDumper::VisitCastExpr(const CastExpr *Node) {
11290b57cec5SDimitry Andric   OS << " <";
11300b57cec5SDimitry Andric   {
11310b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, CastColor);
11320b57cec5SDimitry Andric     OS << Node->getCastKindName();
11330b57cec5SDimitry Andric   }
11340b57cec5SDimitry Andric   dumpBasePath(OS, Node);
11350b57cec5SDimitry Andric   OS << ">";
1136e8d8bef9SDimitry Andric   if (Node->hasStoredFPFeatures())
1137e8d8bef9SDimitry Andric     printFPOptions(Node->getFPFeatures());
11380b57cec5SDimitry Andric }
11390b57cec5SDimitry Andric 
VisitImplicitCastExpr(const ImplicitCastExpr * Node)11400b57cec5SDimitry Andric void TextNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) {
11410b57cec5SDimitry Andric   VisitCastExpr(Node);
11420b57cec5SDimitry Andric   if (Node->isPartOfExplicitCast())
11430b57cec5SDimitry Andric     OS << " part_of_explicit_cast";
11440b57cec5SDimitry Andric }
11450b57cec5SDimitry Andric 
VisitDeclRefExpr(const DeclRefExpr * Node)11460b57cec5SDimitry Andric void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
11470b57cec5SDimitry Andric   OS << " ";
11480b57cec5SDimitry Andric   dumpBareDeclRef(Node->getDecl());
11495f757f3fSDimitry Andric   dumpNestedNameSpecifier(Node->getQualifier());
11500b57cec5SDimitry Andric   if (Node->getDecl() != Node->getFoundDecl()) {
11510b57cec5SDimitry Andric     OS << " (";
11520b57cec5SDimitry Andric     dumpBareDeclRef(Node->getFoundDecl());
11530b57cec5SDimitry Andric     OS << ")";
11540b57cec5SDimitry Andric   }
11550b57cec5SDimitry Andric   switch (Node->isNonOdrUse()) {
11560b57cec5SDimitry Andric   case NOUR_None: break;
11570b57cec5SDimitry Andric   case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break;
11580b57cec5SDimitry Andric   case NOUR_Constant: OS << " non_odr_use_constant"; break;
11590b57cec5SDimitry Andric   case NOUR_Discarded: OS << " non_odr_use_discarded"; break;
11600b57cec5SDimitry Andric   }
11615f757f3fSDimitry Andric   if (Node->refersToEnclosingVariableOrCapture())
11625f757f3fSDimitry Andric     OS << " refers_to_enclosing_variable_or_capture";
116306c3fb27SDimitry Andric   if (Node->isImmediateEscalating())
116406c3fb27SDimitry Andric     OS << " immediate-escalating";
11650b57cec5SDimitry Andric }
11660b57cec5SDimitry Andric 
VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr * Node)11675f757f3fSDimitry Andric void clang::TextNodeDumper::VisitDependentScopeDeclRefExpr(
11685f757f3fSDimitry Andric     const DependentScopeDeclRefExpr *Node) {
11695f757f3fSDimitry Andric 
11705f757f3fSDimitry Andric   dumpNestedNameSpecifier(Node->getQualifier());
11715f757f3fSDimitry Andric }
11725f757f3fSDimitry Andric 
VisitUnresolvedLookupExpr(const UnresolvedLookupExpr * Node)11730b57cec5SDimitry Andric void TextNodeDumper::VisitUnresolvedLookupExpr(
11740b57cec5SDimitry Andric     const UnresolvedLookupExpr *Node) {
11750b57cec5SDimitry Andric   OS << " (";
11760b57cec5SDimitry Andric   if (!Node->requiresADL())
11770b57cec5SDimitry Andric     OS << "no ";
11780b57cec5SDimitry Andric   OS << "ADL) = '" << Node->getName() << '\'';
11790b57cec5SDimitry Andric 
11800b57cec5SDimitry Andric   UnresolvedLookupExpr::decls_iterator I = Node->decls_begin(),
11810b57cec5SDimitry Andric                                        E = Node->decls_end();
11820b57cec5SDimitry Andric   if (I == E)
11830b57cec5SDimitry Andric     OS << " empty";
11840b57cec5SDimitry Andric   for (; I != E; ++I)
11850b57cec5SDimitry Andric     dumpPointer(*I);
11860b57cec5SDimitry Andric }
11870b57cec5SDimitry Andric 
VisitObjCIvarRefExpr(const ObjCIvarRefExpr * Node)11880b57cec5SDimitry Andric void TextNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) {
11890b57cec5SDimitry Andric   {
11900b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, DeclKindNameColor);
11910b57cec5SDimitry Andric     OS << " " << Node->getDecl()->getDeclKindName() << "Decl";
11920b57cec5SDimitry Andric   }
11930b57cec5SDimitry Andric   OS << "='" << *Node->getDecl() << "'";
11940b57cec5SDimitry Andric   dumpPointer(Node->getDecl());
11950b57cec5SDimitry Andric   if (Node->isFreeIvar())
11960b57cec5SDimitry Andric     OS << " isFreeIvar";
11970b57cec5SDimitry Andric }
11980b57cec5SDimitry Andric 
VisitSYCLUniqueStableNameExpr(const SYCLUniqueStableNameExpr * Node)1199fe6060f1SDimitry Andric void TextNodeDumper::VisitSYCLUniqueStableNameExpr(
1200fe6060f1SDimitry Andric     const SYCLUniqueStableNameExpr *Node) {
1201fe6060f1SDimitry Andric   dumpType(Node->getTypeSourceInfo()->getType());
1202fe6060f1SDimitry Andric }
1203fe6060f1SDimitry Andric 
VisitPredefinedExpr(const PredefinedExpr * Node)12040b57cec5SDimitry Andric void TextNodeDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
12050b57cec5SDimitry Andric   OS << " " << PredefinedExpr::getIdentKindName(Node->getIdentKind());
12060b57cec5SDimitry Andric }
12070b57cec5SDimitry Andric 
VisitCharacterLiteral(const CharacterLiteral * Node)12080b57cec5SDimitry Andric void TextNodeDumper::VisitCharacterLiteral(const CharacterLiteral *Node) {
12090b57cec5SDimitry Andric   ColorScope Color(OS, ShowColors, ValueColor);
12100b57cec5SDimitry Andric   OS << " " << Node->getValue();
12110b57cec5SDimitry Andric }
12120b57cec5SDimitry Andric 
VisitIntegerLiteral(const IntegerLiteral * Node)12130b57cec5SDimitry Andric void TextNodeDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
12140b57cec5SDimitry Andric   bool isSigned = Node->getType()->isSignedIntegerType();
12150b57cec5SDimitry Andric   ColorScope Color(OS, ShowColors, ValueColor);
1216fe6060f1SDimitry Andric   OS << " " << toString(Node->getValue(), 10, isSigned);
12170b57cec5SDimitry Andric }
12180b57cec5SDimitry Andric 
VisitFixedPointLiteral(const FixedPointLiteral * Node)12190b57cec5SDimitry Andric void TextNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *Node) {
12200b57cec5SDimitry Andric   ColorScope Color(OS, ShowColors, ValueColor);
12210b57cec5SDimitry Andric   OS << " " << Node->getValueAsString(/*Radix=*/10);
12220b57cec5SDimitry Andric }
12230b57cec5SDimitry Andric 
VisitFloatingLiteral(const FloatingLiteral * Node)12240b57cec5SDimitry Andric void TextNodeDumper::VisitFloatingLiteral(const FloatingLiteral *Node) {
12250b57cec5SDimitry Andric   ColorScope Color(OS, ShowColors, ValueColor);
12260b57cec5SDimitry Andric   OS << " " << Node->getValueAsApproximateDouble();
12270b57cec5SDimitry Andric }
12280b57cec5SDimitry Andric 
VisitStringLiteral(const StringLiteral * Str)12290b57cec5SDimitry Andric void TextNodeDumper::VisitStringLiteral(const StringLiteral *Str) {
12300b57cec5SDimitry Andric   ColorScope Color(OS, ShowColors, ValueColor);
12310b57cec5SDimitry Andric   OS << " ";
12320b57cec5SDimitry Andric   Str->outputString(OS);
12330b57cec5SDimitry Andric }
12340b57cec5SDimitry Andric 
VisitInitListExpr(const InitListExpr * ILE)12350b57cec5SDimitry Andric void TextNodeDumper::VisitInitListExpr(const InitListExpr *ILE) {
12360b57cec5SDimitry Andric   if (auto *Field = ILE->getInitializedFieldInUnion()) {
12370b57cec5SDimitry Andric     OS << " field ";
12380b57cec5SDimitry Andric     dumpBareDeclRef(Field);
12390b57cec5SDimitry Andric   }
12400b57cec5SDimitry Andric }
12410b57cec5SDimitry Andric 
VisitGenericSelectionExpr(const GenericSelectionExpr * E)12420b57cec5SDimitry Andric void TextNodeDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
12430b57cec5SDimitry Andric   if (E->isResultDependent())
12440b57cec5SDimitry Andric     OS << " result_dependent";
12450b57cec5SDimitry Andric }
12460b57cec5SDimitry Andric 
VisitUnaryOperator(const UnaryOperator * Node)12470b57cec5SDimitry Andric void TextNodeDumper::VisitUnaryOperator(const UnaryOperator *Node) {
12480b57cec5SDimitry Andric   OS << " " << (Node->isPostfix() ? "postfix" : "prefix") << " '"
12490b57cec5SDimitry Andric      << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
12500b57cec5SDimitry Andric   if (!Node->canOverflow())
12510b57cec5SDimitry Andric     OS << " cannot overflow";
1252e8d8bef9SDimitry Andric   if (Node->hasStoredFPFeatures())
1253e8d8bef9SDimitry Andric     printFPOptions(Node->getStoredFPFeatures());
12540b57cec5SDimitry Andric }
12550b57cec5SDimitry Andric 
VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr * Node)12560b57cec5SDimitry Andric void TextNodeDumper::VisitUnaryExprOrTypeTraitExpr(
12570b57cec5SDimitry Andric     const UnaryExprOrTypeTraitExpr *Node) {
12585ffd83dbSDimitry Andric   OS << " " << getTraitSpelling(Node->getKind());
12595ffd83dbSDimitry Andric 
12600b57cec5SDimitry Andric   if (Node->isArgumentType())
12610b57cec5SDimitry Andric     dumpType(Node->getArgumentType());
12620b57cec5SDimitry Andric }
12630b57cec5SDimitry Andric 
VisitMemberExpr(const MemberExpr * Node)12640b57cec5SDimitry Andric void TextNodeDumper::VisitMemberExpr(const MemberExpr *Node) {
12650b57cec5SDimitry Andric   OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl();
12660b57cec5SDimitry Andric   dumpPointer(Node->getMemberDecl());
12675f757f3fSDimitry Andric   dumpNestedNameSpecifier(Node->getQualifier());
12680b57cec5SDimitry Andric   switch (Node->isNonOdrUse()) {
12690b57cec5SDimitry Andric   case NOUR_None: break;
12700b57cec5SDimitry Andric   case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break;
12710b57cec5SDimitry Andric   case NOUR_Constant: OS << " non_odr_use_constant"; break;
12720b57cec5SDimitry Andric   case NOUR_Discarded: OS << " non_odr_use_discarded"; break;
12730b57cec5SDimitry Andric   }
12740b57cec5SDimitry Andric }
12750b57cec5SDimitry Andric 
VisitExtVectorElementExpr(const ExtVectorElementExpr * Node)12760b57cec5SDimitry Andric void TextNodeDumper::VisitExtVectorElementExpr(
12770b57cec5SDimitry Andric     const ExtVectorElementExpr *Node) {
12780b57cec5SDimitry Andric   OS << " " << Node->getAccessor().getNameStart();
12790b57cec5SDimitry Andric }
12800b57cec5SDimitry Andric 
VisitBinaryOperator(const BinaryOperator * Node)12810b57cec5SDimitry Andric void TextNodeDumper::VisitBinaryOperator(const BinaryOperator *Node) {
12820b57cec5SDimitry Andric   OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1283e8d8bef9SDimitry Andric   if (Node->hasStoredFPFeatures())
1284e8d8bef9SDimitry Andric     printFPOptions(Node->getStoredFPFeatures());
12850b57cec5SDimitry Andric }
12860b57cec5SDimitry Andric 
VisitCompoundAssignOperator(const CompoundAssignOperator * Node)12870b57cec5SDimitry Andric void TextNodeDumper::VisitCompoundAssignOperator(
12880b57cec5SDimitry Andric     const CompoundAssignOperator *Node) {
12890b57cec5SDimitry Andric   OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
12900b57cec5SDimitry Andric      << "' ComputeLHSTy=";
12910b57cec5SDimitry Andric   dumpBareType(Node->getComputationLHSType());
12920b57cec5SDimitry Andric   OS << " ComputeResultTy=";
12930b57cec5SDimitry Andric   dumpBareType(Node->getComputationResultType());
1294e8d8bef9SDimitry Andric   if (Node->hasStoredFPFeatures())
1295e8d8bef9SDimitry Andric     printFPOptions(Node->getStoredFPFeatures());
12960b57cec5SDimitry Andric }
12970b57cec5SDimitry Andric 
VisitAddrLabelExpr(const AddrLabelExpr * Node)12980b57cec5SDimitry Andric void TextNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) {
12990b57cec5SDimitry Andric   OS << " " << Node->getLabel()->getName();
13000b57cec5SDimitry Andric   dumpPointer(Node->getLabel());
13010b57cec5SDimitry Andric }
13020b57cec5SDimitry Andric 
VisitCXXNamedCastExpr(const CXXNamedCastExpr * Node)13030b57cec5SDimitry Andric void TextNodeDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) {
13040b57cec5SDimitry Andric   OS << " " << Node->getCastName() << "<"
13050b57cec5SDimitry Andric      << Node->getTypeAsWritten().getAsString() << ">"
13060b57cec5SDimitry Andric      << " <" << Node->getCastKindName();
13070b57cec5SDimitry Andric   dumpBasePath(OS, Node);
13080b57cec5SDimitry Andric   OS << ">";
13090b57cec5SDimitry Andric }
13100b57cec5SDimitry Andric 
VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr * Node)13110b57cec5SDimitry Andric void TextNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
13120b57cec5SDimitry Andric   OS << " " << (Node->getValue() ? "true" : "false");
13130b57cec5SDimitry Andric }
13140b57cec5SDimitry Andric 
VisitCXXThisExpr(const CXXThisExpr * Node)13150b57cec5SDimitry Andric void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
13160b57cec5SDimitry Andric   if (Node->isImplicit())
13170b57cec5SDimitry Andric     OS << " implicit";
13180b57cec5SDimitry Andric   OS << " this";
13190b57cec5SDimitry Andric }
13200b57cec5SDimitry Andric 
VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr * Node)13210b57cec5SDimitry Andric void TextNodeDumper::VisitCXXFunctionalCastExpr(
13220b57cec5SDimitry Andric     const CXXFunctionalCastExpr *Node) {
13230b57cec5SDimitry Andric   OS << " functional cast to " << Node->getTypeAsWritten().getAsString() << " <"
13240b57cec5SDimitry Andric      << Node->getCastKindName() << ">";
1325e8d8bef9SDimitry Andric   if (Node->hasStoredFPFeatures())
1326e8d8bef9SDimitry Andric     printFPOptions(Node->getFPFeatures());
1327e8d8bef9SDimitry Andric }
1328e8d8bef9SDimitry Andric 
VisitCXXStaticCastExpr(const CXXStaticCastExpr * Node)1329e8d8bef9SDimitry Andric void TextNodeDumper::VisitCXXStaticCastExpr(const CXXStaticCastExpr *Node) {
1330e8d8bef9SDimitry Andric   VisitCXXNamedCastExpr(Node);
1331e8d8bef9SDimitry Andric   if (Node->hasStoredFPFeatures())
1332e8d8bef9SDimitry Andric     printFPOptions(Node->getFPFeatures());
13330b57cec5SDimitry Andric }
13340b57cec5SDimitry Andric 
VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr * Node)13350b57cec5SDimitry Andric void TextNodeDumper::VisitCXXUnresolvedConstructExpr(
13360b57cec5SDimitry Andric     const CXXUnresolvedConstructExpr *Node) {
13370b57cec5SDimitry Andric   dumpType(Node->getTypeAsWritten());
13380b57cec5SDimitry Andric   if (Node->isListInitialization())
13390b57cec5SDimitry Andric     OS << " list";
13400b57cec5SDimitry Andric }
13410b57cec5SDimitry Andric 
VisitCXXConstructExpr(const CXXConstructExpr * Node)13420b57cec5SDimitry Andric void TextNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
13430b57cec5SDimitry Andric   CXXConstructorDecl *Ctor = Node->getConstructor();
13440b57cec5SDimitry Andric   dumpType(Ctor->getType());
13450b57cec5SDimitry Andric   if (Node->isElidable())
13460b57cec5SDimitry Andric     OS << " elidable";
13470b57cec5SDimitry Andric   if (Node->isListInitialization())
13480b57cec5SDimitry Andric     OS << " list";
13490b57cec5SDimitry Andric   if (Node->isStdInitListInitialization())
13500b57cec5SDimitry Andric     OS << " std::initializer_list";
13510b57cec5SDimitry Andric   if (Node->requiresZeroInitialization())
13520b57cec5SDimitry Andric     OS << " zeroing";
135306c3fb27SDimitry Andric   if (Node->isImmediateEscalating())
135406c3fb27SDimitry Andric     OS << " immediate-escalating";
13550b57cec5SDimitry Andric }
13560b57cec5SDimitry Andric 
VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr * Node)13570b57cec5SDimitry Andric void TextNodeDumper::VisitCXXBindTemporaryExpr(
13580b57cec5SDimitry Andric     const CXXBindTemporaryExpr *Node) {
13590b57cec5SDimitry Andric   OS << " (CXXTemporary";
13600b57cec5SDimitry Andric   dumpPointer(Node);
13610b57cec5SDimitry Andric   OS << ")";
13620b57cec5SDimitry Andric }
13630b57cec5SDimitry Andric 
VisitCXXNewExpr(const CXXNewExpr * Node)13640b57cec5SDimitry Andric void TextNodeDumper::VisitCXXNewExpr(const CXXNewExpr *Node) {
13650b57cec5SDimitry Andric   if (Node->isGlobalNew())
13660b57cec5SDimitry Andric     OS << " global";
13670b57cec5SDimitry Andric   if (Node->isArray())
13680b57cec5SDimitry Andric     OS << " array";
13690b57cec5SDimitry Andric   if (Node->getOperatorNew()) {
13700b57cec5SDimitry Andric     OS << ' ';
13710b57cec5SDimitry Andric     dumpBareDeclRef(Node->getOperatorNew());
13720b57cec5SDimitry Andric   }
13730b57cec5SDimitry Andric   // We could dump the deallocation function used in case of error, but it's
13740b57cec5SDimitry Andric   // usually not that interesting.
13750b57cec5SDimitry Andric }
13760b57cec5SDimitry Andric 
VisitCXXDeleteExpr(const CXXDeleteExpr * Node)13770b57cec5SDimitry Andric void TextNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *Node) {
13780b57cec5SDimitry Andric   if (Node->isGlobalDelete())
13790b57cec5SDimitry Andric     OS << " global";
13800b57cec5SDimitry Andric   if (Node->isArrayForm())
13810b57cec5SDimitry Andric     OS << " array";
13820b57cec5SDimitry Andric   if (Node->getOperatorDelete()) {
13830b57cec5SDimitry Andric     OS << ' ';
13840b57cec5SDimitry Andric     dumpBareDeclRef(Node->getOperatorDelete());
13850b57cec5SDimitry Andric   }
13860b57cec5SDimitry Andric }
13870b57cec5SDimitry Andric 
VisitTypeTraitExpr(const TypeTraitExpr * Node)13885ffd83dbSDimitry Andric void TextNodeDumper::VisitTypeTraitExpr(const TypeTraitExpr *Node) {
13895ffd83dbSDimitry Andric   OS << " " << getTraitSpelling(Node->getTrait());
13905ffd83dbSDimitry Andric }
13915ffd83dbSDimitry Andric 
VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr * Node)13925ffd83dbSDimitry Andric void TextNodeDumper::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *Node) {
13935ffd83dbSDimitry Andric   OS << " " << getTraitSpelling(Node->getTrait());
13945ffd83dbSDimitry Andric }
13955ffd83dbSDimitry Andric 
VisitExpressionTraitExpr(const ExpressionTraitExpr * Node)13965ffd83dbSDimitry Andric void TextNodeDumper::VisitExpressionTraitExpr(const ExpressionTraitExpr *Node) {
13975ffd83dbSDimitry Andric   OS << " " << getTraitSpelling(Node->getTrait());
13985ffd83dbSDimitry Andric }
13995ffd83dbSDimitry Andric 
VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr * Node)14000b57cec5SDimitry Andric void TextNodeDumper::VisitMaterializeTemporaryExpr(
14010b57cec5SDimitry Andric     const MaterializeTemporaryExpr *Node) {
14020b57cec5SDimitry Andric   if (const ValueDecl *VD = Node->getExtendingDecl()) {
14030b57cec5SDimitry Andric     OS << " extended by ";
14040b57cec5SDimitry Andric     dumpBareDeclRef(VD);
14050b57cec5SDimitry Andric   }
14060b57cec5SDimitry Andric }
14070b57cec5SDimitry Andric 
VisitExprWithCleanups(const ExprWithCleanups * Node)14080b57cec5SDimitry Andric void TextNodeDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) {
14090b57cec5SDimitry Andric   for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
14105ffd83dbSDimitry Andric     dumpCleanupObject(Node->getObject(i));
14110b57cec5SDimitry Andric }
14120b57cec5SDimitry Andric 
VisitSizeOfPackExpr(const SizeOfPackExpr * Node)14130b57cec5SDimitry Andric void TextNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
14140b57cec5SDimitry Andric   dumpPointer(Node->getPack());
14150b57cec5SDimitry Andric   dumpName(Node->getPack());
14160b57cec5SDimitry Andric }
14170b57cec5SDimitry Andric 
VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr * Node)14180b57cec5SDimitry Andric void TextNodeDumper::VisitCXXDependentScopeMemberExpr(
14190b57cec5SDimitry Andric     const CXXDependentScopeMemberExpr *Node) {
14200b57cec5SDimitry Andric   OS << " " << (Node->isArrow() ? "->" : ".") << Node->getMember();
14210b57cec5SDimitry Andric }
14220b57cec5SDimitry Andric 
VisitObjCMessageExpr(const ObjCMessageExpr * Node)14230b57cec5SDimitry Andric void TextNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
14240b57cec5SDimitry Andric   OS << " selector=";
14250b57cec5SDimitry Andric   Node->getSelector().print(OS);
14260b57cec5SDimitry Andric   switch (Node->getReceiverKind()) {
14270b57cec5SDimitry Andric   case ObjCMessageExpr::Instance:
14280b57cec5SDimitry Andric     break;
14290b57cec5SDimitry Andric 
14300b57cec5SDimitry Andric   case ObjCMessageExpr::Class:
14310b57cec5SDimitry Andric     OS << " class=";
14320b57cec5SDimitry Andric     dumpBareType(Node->getClassReceiver());
14330b57cec5SDimitry Andric     break;
14340b57cec5SDimitry Andric 
14350b57cec5SDimitry Andric   case ObjCMessageExpr::SuperInstance:
14360b57cec5SDimitry Andric     OS << " super (instance)";
14370b57cec5SDimitry Andric     break;
14380b57cec5SDimitry Andric 
14390b57cec5SDimitry Andric   case ObjCMessageExpr::SuperClass:
14400b57cec5SDimitry Andric     OS << " super (class)";
14410b57cec5SDimitry Andric     break;
14420b57cec5SDimitry Andric   }
14430b57cec5SDimitry Andric }
14440b57cec5SDimitry Andric 
VisitObjCBoxedExpr(const ObjCBoxedExpr * Node)14450b57cec5SDimitry Andric void TextNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
14460b57cec5SDimitry Andric   if (auto *BoxingMethod = Node->getBoxingMethod()) {
14470b57cec5SDimitry Andric     OS << " selector=";
14480b57cec5SDimitry Andric     BoxingMethod->getSelector().print(OS);
14490b57cec5SDimitry Andric   }
14500b57cec5SDimitry Andric }
14510b57cec5SDimitry Andric 
VisitObjCAtCatchStmt(const ObjCAtCatchStmt * Node)14520b57cec5SDimitry Andric void TextNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
14530b57cec5SDimitry Andric   if (!Node->getCatchParamDecl())
14540b57cec5SDimitry Andric     OS << " catch all";
14550b57cec5SDimitry Andric }
14560b57cec5SDimitry Andric 
VisitObjCEncodeExpr(const ObjCEncodeExpr * Node)14570b57cec5SDimitry Andric void TextNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
14580b57cec5SDimitry Andric   dumpType(Node->getEncodedType());
14590b57cec5SDimitry Andric }
14600b57cec5SDimitry Andric 
VisitObjCSelectorExpr(const ObjCSelectorExpr * Node)14610b57cec5SDimitry Andric void TextNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
14620b57cec5SDimitry Andric   OS << " ";
14630b57cec5SDimitry Andric   Node->getSelector().print(OS);
14640b57cec5SDimitry Andric }
14650b57cec5SDimitry Andric 
VisitObjCProtocolExpr(const ObjCProtocolExpr * Node)14660b57cec5SDimitry Andric void TextNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
14670b57cec5SDimitry Andric   OS << ' ' << *Node->getProtocol();
14680b57cec5SDimitry Andric }
14690b57cec5SDimitry Andric 
VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr * Node)14700b57cec5SDimitry Andric void TextNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) {
14710b57cec5SDimitry Andric   if (Node->isImplicitProperty()) {
14720b57cec5SDimitry Andric     OS << " Kind=MethodRef Getter=\"";
14730b57cec5SDimitry Andric     if (Node->getImplicitPropertyGetter())
14740b57cec5SDimitry Andric       Node->getImplicitPropertyGetter()->getSelector().print(OS);
14750b57cec5SDimitry Andric     else
14760b57cec5SDimitry Andric       OS << "(null)";
14770b57cec5SDimitry Andric 
14780b57cec5SDimitry Andric     OS << "\" Setter=\"";
14790b57cec5SDimitry Andric     if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
14800b57cec5SDimitry Andric       Setter->getSelector().print(OS);
14810b57cec5SDimitry Andric     else
14820b57cec5SDimitry Andric       OS << "(null)";
14830b57cec5SDimitry Andric     OS << "\"";
14840b57cec5SDimitry Andric   } else {
14850b57cec5SDimitry Andric     OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty()
14860b57cec5SDimitry Andric        << '"';
14870b57cec5SDimitry Andric   }
14880b57cec5SDimitry Andric 
14890b57cec5SDimitry Andric   if (Node->isSuperReceiver())
14900b57cec5SDimitry Andric     OS << " super";
14910b57cec5SDimitry Andric 
14920b57cec5SDimitry Andric   OS << " Messaging=";
14930b57cec5SDimitry Andric   if (Node->isMessagingGetter() && Node->isMessagingSetter())
14940b57cec5SDimitry Andric     OS << "Getter&Setter";
14950b57cec5SDimitry Andric   else if (Node->isMessagingGetter())
14960b57cec5SDimitry Andric     OS << "Getter";
14970b57cec5SDimitry Andric   else if (Node->isMessagingSetter())
14980b57cec5SDimitry Andric     OS << "Setter";
14990b57cec5SDimitry Andric }
15000b57cec5SDimitry Andric 
VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr * Node)15010b57cec5SDimitry Andric void TextNodeDumper::VisitObjCSubscriptRefExpr(
15020b57cec5SDimitry Andric     const ObjCSubscriptRefExpr *Node) {
15030b57cec5SDimitry Andric   if (Node->isArraySubscriptRefExpr())
15040b57cec5SDimitry Andric     OS << " Kind=ArraySubscript GetterForArray=\"";
15050b57cec5SDimitry Andric   else
15060b57cec5SDimitry Andric     OS << " Kind=DictionarySubscript GetterForDictionary=\"";
15070b57cec5SDimitry Andric   if (Node->getAtIndexMethodDecl())
15080b57cec5SDimitry Andric     Node->getAtIndexMethodDecl()->getSelector().print(OS);
15090b57cec5SDimitry Andric   else
15100b57cec5SDimitry Andric     OS << "(null)";
15110b57cec5SDimitry Andric 
15120b57cec5SDimitry Andric   if (Node->isArraySubscriptRefExpr())
15130b57cec5SDimitry Andric     OS << "\" SetterForArray=\"";
15140b57cec5SDimitry Andric   else
15150b57cec5SDimitry Andric     OS << "\" SetterForDictionary=\"";
15160b57cec5SDimitry Andric   if (Node->setAtIndexMethodDecl())
15170b57cec5SDimitry Andric     Node->setAtIndexMethodDecl()->getSelector().print(OS);
15180b57cec5SDimitry Andric   else
15190b57cec5SDimitry Andric     OS << "(null)";
15200b57cec5SDimitry Andric }
15210b57cec5SDimitry Andric 
VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr * Node)15220b57cec5SDimitry Andric void TextNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) {
15230b57cec5SDimitry Andric   OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
15240b57cec5SDimitry Andric }
15250b57cec5SDimitry Andric 
VisitOMPIteratorExpr(const OMPIteratorExpr * Node)15265ffd83dbSDimitry Andric void TextNodeDumper::VisitOMPIteratorExpr(const OMPIteratorExpr *Node) {
15275ffd83dbSDimitry Andric   OS << " ";
15285ffd83dbSDimitry Andric   for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) {
15295ffd83dbSDimitry Andric     Visit(Node->getIteratorDecl(I));
15305ffd83dbSDimitry Andric     OS << " = ";
15315ffd83dbSDimitry Andric     const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I);
15325ffd83dbSDimitry Andric     OS << " begin ";
15335ffd83dbSDimitry Andric     Visit(Range.Begin);
15345ffd83dbSDimitry Andric     OS << " end ";
15355ffd83dbSDimitry Andric     Visit(Range.End);
15365ffd83dbSDimitry Andric     if (Range.Step) {
15375ffd83dbSDimitry Andric       OS << " step ";
15385ffd83dbSDimitry Andric       Visit(Range.Step);
15395ffd83dbSDimitry Andric     }
15405ffd83dbSDimitry Andric   }
15415ffd83dbSDimitry Andric }
15425ffd83dbSDimitry Andric 
VisitConceptSpecializationExpr(const ConceptSpecializationExpr * Node)1543e8d8bef9SDimitry Andric void TextNodeDumper::VisitConceptSpecializationExpr(
1544e8d8bef9SDimitry Andric     const ConceptSpecializationExpr *Node) {
1545e8d8bef9SDimitry Andric   OS << " ";
1546e8d8bef9SDimitry Andric   dumpBareDeclRef(Node->getFoundDecl());
1547e8d8bef9SDimitry Andric }
1548e8d8bef9SDimitry Andric 
VisitRequiresExpr(const RequiresExpr * Node)1549fe6060f1SDimitry Andric void TextNodeDumper::VisitRequiresExpr(
1550fe6060f1SDimitry Andric     const RequiresExpr *Node) {
1551fe6060f1SDimitry Andric   if (!Node->isValueDependent())
1552fe6060f1SDimitry Andric     OS << (Node->isSatisfied() ? " satisfied" : " unsatisfied");
1553fe6060f1SDimitry Andric }
1554fe6060f1SDimitry Andric 
VisitRValueReferenceType(const ReferenceType * T)15550b57cec5SDimitry Andric void TextNodeDumper::VisitRValueReferenceType(const ReferenceType *T) {
15560b57cec5SDimitry Andric   if (T->isSpelledAsLValue())
15570b57cec5SDimitry Andric     OS << " written as lvalue reference";
15580b57cec5SDimitry Andric }
15590b57cec5SDimitry Andric 
VisitArrayType(const ArrayType * T)15600b57cec5SDimitry Andric void TextNodeDumper::VisitArrayType(const ArrayType *T) {
15610b57cec5SDimitry Andric   switch (T->getSizeModifier()) {
15625f757f3fSDimitry Andric   case ArraySizeModifier::Normal:
15630b57cec5SDimitry Andric     break;
15645f757f3fSDimitry Andric   case ArraySizeModifier::Static:
15650b57cec5SDimitry Andric     OS << " static";
15660b57cec5SDimitry Andric     break;
15675f757f3fSDimitry Andric   case ArraySizeModifier::Star:
15680b57cec5SDimitry Andric     OS << " *";
15690b57cec5SDimitry Andric     break;
15700b57cec5SDimitry Andric   }
15710b57cec5SDimitry Andric   OS << " " << T->getIndexTypeQualifiers().getAsString();
15720b57cec5SDimitry Andric }
15730b57cec5SDimitry Andric 
VisitConstantArrayType(const ConstantArrayType * T)15740b57cec5SDimitry Andric void TextNodeDumper::VisitConstantArrayType(const ConstantArrayType *T) {
15750b57cec5SDimitry Andric   OS << " " << T->getSize();
15760b57cec5SDimitry Andric   VisitArrayType(T);
15770b57cec5SDimitry Andric }
15780b57cec5SDimitry Andric 
VisitVariableArrayType(const VariableArrayType * T)15790b57cec5SDimitry Andric void TextNodeDumper::VisitVariableArrayType(const VariableArrayType *T) {
15800b57cec5SDimitry Andric   OS << " ";
15810b57cec5SDimitry Andric   dumpSourceRange(T->getBracketsRange());
15820b57cec5SDimitry Andric   VisitArrayType(T);
15830b57cec5SDimitry Andric }
15840b57cec5SDimitry Andric 
VisitDependentSizedArrayType(const DependentSizedArrayType * T)15850b57cec5SDimitry Andric void TextNodeDumper::VisitDependentSizedArrayType(
15860b57cec5SDimitry Andric     const DependentSizedArrayType *T) {
15870b57cec5SDimitry Andric   VisitArrayType(T);
15880b57cec5SDimitry Andric   OS << " ";
15890b57cec5SDimitry Andric   dumpSourceRange(T->getBracketsRange());
15900b57cec5SDimitry Andric }
15910b57cec5SDimitry Andric 
VisitDependentSizedExtVectorType(const DependentSizedExtVectorType * T)15920b57cec5SDimitry Andric void TextNodeDumper::VisitDependentSizedExtVectorType(
15930b57cec5SDimitry Andric     const DependentSizedExtVectorType *T) {
15940b57cec5SDimitry Andric   OS << " ";
15950b57cec5SDimitry Andric   dumpLocation(T->getAttributeLoc());
15960b57cec5SDimitry Andric }
15970b57cec5SDimitry Andric 
VisitVectorType(const VectorType * T)15980b57cec5SDimitry Andric void TextNodeDumper::VisitVectorType(const VectorType *T) {
15990b57cec5SDimitry Andric   switch (T->getVectorKind()) {
16005f757f3fSDimitry Andric   case VectorKind::Generic:
16010b57cec5SDimitry Andric     break;
16025f757f3fSDimitry Andric   case VectorKind::AltiVecVector:
16030b57cec5SDimitry Andric     OS << " altivec";
16040b57cec5SDimitry Andric     break;
16055f757f3fSDimitry Andric   case VectorKind::AltiVecPixel:
16060b57cec5SDimitry Andric     OS << " altivec pixel";
16070b57cec5SDimitry Andric     break;
16085f757f3fSDimitry Andric   case VectorKind::AltiVecBool:
16090b57cec5SDimitry Andric     OS << " altivec bool";
16100b57cec5SDimitry Andric     break;
16115f757f3fSDimitry Andric   case VectorKind::Neon:
16120b57cec5SDimitry Andric     OS << " neon";
16130b57cec5SDimitry Andric     break;
16145f757f3fSDimitry Andric   case VectorKind::NeonPoly:
16150b57cec5SDimitry Andric     OS << " neon poly";
16160b57cec5SDimitry Andric     break;
16175f757f3fSDimitry Andric   case VectorKind::SveFixedLengthData:
1618e8d8bef9SDimitry Andric     OS << " fixed-length sve data vector";
1619e8d8bef9SDimitry Andric     break;
16205f757f3fSDimitry Andric   case VectorKind::SveFixedLengthPredicate:
1621e8d8bef9SDimitry Andric     OS << " fixed-length sve predicate vector";
1622e8d8bef9SDimitry Andric     break;
16235f757f3fSDimitry Andric   case VectorKind::RVVFixedLengthData:
162406c3fb27SDimitry Andric     OS << " fixed-length rvv data vector";
162506c3fb27SDimitry Andric     break;
1626b3edf446SDimitry Andric   case VectorKind::RVVFixedLengthMask:
1627b3edf446SDimitry Andric     OS << " fixed-length rvv mask vector";
1628b3edf446SDimitry Andric     break;
16290b57cec5SDimitry Andric   }
16300b57cec5SDimitry Andric   OS << " " << T->getNumElements();
16310b57cec5SDimitry Andric }
16320b57cec5SDimitry Andric 
VisitFunctionType(const FunctionType * T)16330b57cec5SDimitry Andric void TextNodeDumper::VisitFunctionType(const FunctionType *T) {
16340b57cec5SDimitry Andric   auto EI = T->getExtInfo();
16350b57cec5SDimitry Andric   if (EI.getNoReturn())
16360b57cec5SDimitry Andric     OS << " noreturn";
16370b57cec5SDimitry Andric   if (EI.getProducesResult())
16380b57cec5SDimitry Andric     OS << " produces_result";
16390b57cec5SDimitry Andric   if (EI.getHasRegParm())
16400b57cec5SDimitry Andric     OS << " regparm " << EI.getRegParm();
16410b57cec5SDimitry Andric   OS << " " << FunctionType::getNameForCallConv(EI.getCC());
16420b57cec5SDimitry Andric }
16430b57cec5SDimitry Andric 
VisitFunctionProtoType(const FunctionProtoType * T)16440b57cec5SDimitry Andric void TextNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) {
16450b57cec5SDimitry Andric   auto EPI = T->getExtProtoInfo();
16460b57cec5SDimitry Andric   if (EPI.HasTrailingReturn)
16470b57cec5SDimitry Andric     OS << " trailing_return";
16480b57cec5SDimitry Andric   if (T->isConst())
16490b57cec5SDimitry Andric     OS << " const";
16500b57cec5SDimitry Andric   if (T->isVolatile())
16510b57cec5SDimitry Andric     OS << " volatile";
16520b57cec5SDimitry Andric   if (T->isRestrict())
16530b57cec5SDimitry Andric     OS << " restrict";
16540b57cec5SDimitry Andric   if (T->getExtProtoInfo().Variadic)
16550b57cec5SDimitry Andric     OS << " variadic";
16560b57cec5SDimitry Andric   switch (EPI.RefQualifier) {
16570b57cec5SDimitry Andric   case RQ_None:
16580b57cec5SDimitry Andric     break;
16590b57cec5SDimitry Andric   case RQ_LValue:
16600b57cec5SDimitry Andric     OS << " &";
16610b57cec5SDimitry Andric     break;
16620b57cec5SDimitry Andric   case RQ_RValue:
16630b57cec5SDimitry Andric     OS << " &&";
16640b57cec5SDimitry Andric     break;
16650b57cec5SDimitry Andric   }
16665f757f3fSDimitry Andric 
16675f757f3fSDimitry Andric   switch (EPI.ExceptionSpec.Type) {
16685f757f3fSDimitry Andric   case EST_None:
16695f757f3fSDimitry Andric     break;
16705f757f3fSDimitry Andric   case EST_DynamicNone:
16715f757f3fSDimitry Andric     OS << " exceptionspec_dynamic_none";
16725f757f3fSDimitry Andric     break;
16735f757f3fSDimitry Andric   case EST_Dynamic:
16745f757f3fSDimitry Andric     OS << " exceptionspec_dynamic";
16755f757f3fSDimitry Andric     break;
16765f757f3fSDimitry Andric   case EST_MSAny:
16775f757f3fSDimitry Andric     OS << " exceptionspec_ms_any";
16785f757f3fSDimitry Andric     break;
16795f757f3fSDimitry Andric   case EST_NoThrow:
16805f757f3fSDimitry Andric     OS << " exceptionspec_nothrow";
16815f757f3fSDimitry Andric     break;
16825f757f3fSDimitry Andric   case EST_BasicNoexcept:
16835f757f3fSDimitry Andric     OS << " exceptionspec_basic_noexcept";
16845f757f3fSDimitry Andric     break;
16855f757f3fSDimitry Andric   case EST_DependentNoexcept:
16865f757f3fSDimitry Andric     OS << " exceptionspec_dependent_noexcept";
16875f757f3fSDimitry Andric     break;
16885f757f3fSDimitry Andric   case EST_NoexceptFalse:
16895f757f3fSDimitry Andric     OS << " exceptionspec_noexcept_false";
16905f757f3fSDimitry Andric     break;
16915f757f3fSDimitry Andric   case EST_NoexceptTrue:
16925f757f3fSDimitry Andric     OS << " exceptionspec_noexcept_true";
16935f757f3fSDimitry Andric     break;
16945f757f3fSDimitry Andric   case EST_Unevaluated:
16955f757f3fSDimitry Andric     OS << " exceptionspec_unevaluated";
16965f757f3fSDimitry Andric     break;
16975f757f3fSDimitry Andric   case EST_Uninstantiated:
16985f757f3fSDimitry Andric     OS << " exceptionspec_uninstantiated";
16995f757f3fSDimitry Andric     break;
17005f757f3fSDimitry Andric   case EST_Unparsed:
17015f757f3fSDimitry Andric     OS << " exceptionspec_unparsed";
17025f757f3fSDimitry Andric     break;
17035f757f3fSDimitry Andric   }
17045f757f3fSDimitry Andric   if (!EPI.ExceptionSpec.Exceptions.empty()) {
17055f757f3fSDimitry Andric     AddChild([=] {
17065f757f3fSDimitry Andric       OS << "Exceptions:";
17075f757f3fSDimitry Andric       for (unsigned I = 0, N = EPI.ExceptionSpec.Exceptions.size(); I != N;
17085f757f3fSDimitry Andric            ++I) {
17095f757f3fSDimitry Andric         if (I)
17105f757f3fSDimitry Andric           OS << ",";
17115f757f3fSDimitry Andric         dumpType(EPI.ExceptionSpec.Exceptions[I]);
17125f757f3fSDimitry Andric       }
17135f757f3fSDimitry Andric     });
17145f757f3fSDimitry Andric   }
17155f757f3fSDimitry Andric   if (EPI.ExceptionSpec.NoexceptExpr) {
17165f757f3fSDimitry Andric     AddChild([=] {
17175f757f3fSDimitry Andric       OS << "NoexceptExpr: ";
17185f757f3fSDimitry Andric       Visit(EPI.ExceptionSpec.NoexceptExpr);
17195f757f3fSDimitry Andric     });
17205f757f3fSDimitry Andric   }
17215f757f3fSDimitry Andric   dumpDeclRef(EPI.ExceptionSpec.SourceDecl, "ExceptionSourceDecl");
17225f757f3fSDimitry Andric   dumpDeclRef(EPI.ExceptionSpec.SourceTemplate, "ExceptionSourceTemplate");
17235f757f3fSDimitry Andric 
17240b57cec5SDimitry Andric   // FIXME: Consumed parameters.
17250b57cec5SDimitry Andric   VisitFunctionType(T);
17260b57cec5SDimitry Andric }
17270b57cec5SDimitry Andric 
VisitUnresolvedUsingType(const UnresolvedUsingType * T)17280b57cec5SDimitry Andric void TextNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
17290b57cec5SDimitry Andric   dumpDeclRef(T->getDecl());
17300b57cec5SDimitry Andric }
17310b57cec5SDimitry Andric 
VisitUsingType(const UsingType * T)17320eae32dcSDimitry Andric void TextNodeDumper::VisitUsingType(const UsingType *T) {
17330eae32dcSDimitry Andric   dumpDeclRef(T->getFoundDecl());
1734bdd1243dSDimitry Andric   if (!T->typeMatchesDecl())
1735bdd1243dSDimitry Andric     OS << " divergent";
17360eae32dcSDimitry Andric }
17370eae32dcSDimitry Andric 
VisitTypedefType(const TypedefType * T)17380b57cec5SDimitry Andric void TextNodeDumper::VisitTypedefType(const TypedefType *T) {
17390b57cec5SDimitry Andric   dumpDeclRef(T->getDecl());
1740bdd1243dSDimitry Andric   if (!T->typeMatchesDecl())
1741bdd1243dSDimitry Andric     OS << " divergent";
17420b57cec5SDimitry Andric }
17430b57cec5SDimitry Andric 
VisitUnaryTransformType(const UnaryTransformType * T)17440b57cec5SDimitry Andric void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType *T) {
17450b57cec5SDimitry Andric   switch (T->getUTTKind()) {
1746bdd1243dSDimitry Andric #define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait)                                  \
1747bdd1243dSDimitry Andric   case UnaryTransformType::Enum:                                               \
1748bdd1243dSDimitry Andric     OS << " " #Trait;                                                          \
17490b57cec5SDimitry Andric     break;
1750bdd1243dSDimitry Andric #include "clang/Basic/TransformTypeTraits.def"
17510b57cec5SDimitry Andric   }
17520b57cec5SDimitry Andric }
17530b57cec5SDimitry Andric 
VisitTagType(const TagType * T)17540b57cec5SDimitry Andric void TextNodeDumper::VisitTagType(const TagType *T) {
17550b57cec5SDimitry Andric   dumpDeclRef(T->getDecl());
17560b57cec5SDimitry Andric }
17570b57cec5SDimitry Andric 
VisitTemplateTypeParmType(const TemplateTypeParmType * T)17580b57cec5SDimitry Andric void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
17590b57cec5SDimitry Andric   OS << " depth " << T->getDepth() << " index " << T->getIndex();
17600b57cec5SDimitry Andric   if (T->isParameterPack())
17610b57cec5SDimitry Andric     OS << " pack";
17620b57cec5SDimitry Andric   dumpDeclRef(T->getDecl());
17630b57cec5SDimitry Andric }
17640b57cec5SDimitry Andric 
VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType * T)1765bdd1243dSDimitry Andric void TextNodeDumper::VisitSubstTemplateTypeParmType(
1766bdd1243dSDimitry Andric     const SubstTemplateTypeParmType *T) {
1767bdd1243dSDimitry Andric   dumpDeclRef(T->getAssociatedDecl());
1768bdd1243dSDimitry Andric   VisitTemplateTypeParmDecl(T->getReplacedParameter());
1769bdd1243dSDimitry Andric   if (auto PackIndex = T->getPackIndex())
1770bdd1243dSDimitry Andric     OS << " pack_index " << *PackIndex;
1771bdd1243dSDimitry Andric }
1772bdd1243dSDimitry Andric 
VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType * T)1773bdd1243dSDimitry Andric void TextNodeDumper::VisitSubstTemplateTypeParmPackType(
1774bdd1243dSDimitry Andric     const SubstTemplateTypeParmPackType *T) {
1775bdd1243dSDimitry Andric   dumpDeclRef(T->getAssociatedDecl());
1776bdd1243dSDimitry Andric   VisitTemplateTypeParmDecl(T->getReplacedParameter());
1777bdd1243dSDimitry Andric }
1778bdd1243dSDimitry Andric 
VisitAutoType(const AutoType * T)17790b57cec5SDimitry Andric void TextNodeDumper::VisitAutoType(const AutoType *T) {
17800b57cec5SDimitry Andric   if (T->isDecltypeAuto())
17810b57cec5SDimitry Andric     OS << " decltype(auto)";
17820b57cec5SDimitry Andric   if (!T->isDeduced())
17830b57cec5SDimitry Andric     OS << " undeduced";
178455e4f9d5SDimitry Andric   if (T->isConstrained()) {
178555e4f9d5SDimitry Andric     dumpDeclRef(T->getTypeConstraintConcept());
178655e4f9d5SDimitry Andric     for (const auto &Arg : T->getTypeConstraintArguments())
178755e4f9d5SDimitry Andric       VisitTemplateArgument(Arg);
178855e4f9d5SDimitry Andric   }
17890b57cec5SDimitry Andric }
17900b57cec5SDimitry Andric 
VisitDeducedTemplateSpecializationType(const DeducedTemplateSpecializationType * T)179181ad6265SDimitry Andric void TextNodeDumper::VisitDeducedTemplateSpecializationType(
179281ad6265SDimitry Andric     const DeducedTemplateSpecializationType *T) {
179381ad6265SDimitry Andric   if (T->getTemplateName().getKind() == TemplateName::UsingTemplate)
179481ad6265SDimitry Andric     OS << " using";
179581ad6265SDimitry Andric }
179681ad6265SDimitry Andric 
VisitTemplateSpecializationType(const TemplateSpecializationType * T)17970b57cec5SDimitry Andric void TextNodeDumper::VisitTemplateSpecializationType(
17980b57cec5SDimitry Andric     const TemplateSpecializationType *T) {
17990b57cec5SDimitry Andric   if (T->isTypeAlias())
18000b57cec5SDimitry Andric     OS << " alias";
180181ad6265SDimitry Andric   if (T->getTemplateName().getKind() == TemplateName::UsingTemplate)
180281ad6265SDimitry Andric     OS << " using";
18030b57cec5SDimitry Andric   OS << " ";
18040b57cec5SDimitry Andric   T->getTemplateName().dump(OS);
18050b57cec5SDimitry Andric }
18060b57cec5SDimitry Andric 
VisitInjectedClassNameType(const InjectedClassNameType * T)18070b57cec5SDimitry Andric void TextNodeDumper::VisitInjectedClassNameType(
18080b57cec5SDimitry Andric     const InjectedClassNameType *T) {
18090b57cec5SDimitry Andric   dumpDeclRef(T->getDecl());
18100b57cec5SDimitry Andric }
18110b57cec5SDimitry Andric 
VisitObjCInterfaceType(const ObjCInterfaceType * T)18120b57cec5SDimitry Andric void TextNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
18130b57cec5SDimitry Andric   dumpDeclRef(T->getDecl());
18140b57cec5SDimitry Andric }
18150b57cec5SDimitry Andric 
VisitPackExpansionType(const PackExpansionType * T)18160b57cec5SDimitry Andric void TextNodeDumper::VisitPackExpansionType(const PackExpansionType *T) {
18170b57cec5SDimitry Andric   if (auto N = T->getNumExpansions())
18180b57cec5SDimitry Andric     OS << " expansions " << *N;
18190b57cec5SDimitry Andric }
18200b57cec5SDimitry Andric 
VisitLabelDecl(const LabelDecl * D)18210b57cec5SDimitry Andric void TextNodeDumper::VisitLabelDecl(const LabelDecl *D) { dumpName(D); }
18220b57cec5SDimitry Andric 
VisitTypedefDecl(const TypedefDecl * D)18230b57cec5SDimitry Andric void TextNodeDumper::VisitTypedefDecl(const TypedefDecl *D) {
18240b57cec5SDimitry Andric   dumpName(D);
18250b57cec5SDimitry Andric   dumpType(D->getUnderlyingType());
18260b57cec5SDimitry Andric   if (D->isModulePrivate())
18270b57cec5SDimitry Andric     OS << " __module_private__";
18280b57cec5SDimitry Andric }
18290b57cec5SDimitry Andric 
VisitEnumDecl(const EnumDecl * D)18300b57cec5SDimitry Andric void TextNodeDumper::VisitEnumDecl(const EnumDecl *D) {
18310b57cec5SDimitry Andric   if (D->isScoped()) {
18320b57cec5SDimitry Andric     if (D->isScopedUsingClassTag())
18330b57cec5SDimitry Andric       OS << " class";
18340b57cec5SDimitry Andric     else
18350b57cec5SDimitry Andric       OS << " struct";
18360b57cec5SDimitry Andric   }
18370b57cec5SDimitry Andric   dumpName(D);
18380b57cec5SDimitry Andric   if (D->isModulePrivate())
18390b57cec5SDimitry Andric     OS << " __module_private__";
18400b57cec5SDimitry Andric   if (D->isFixed())
18410b57cec5SDimitry Andric     dumpType(D->getIntegerType());
18420b57cec5SDimitry Andric }
18430b57cec5SDimitry Andric 
VisitRecordDecl(const RecordDecl * D)18440b57cec5SDimitry Andric void TextNodeDumper::VisitRecordDecl(const RecordDecl *D) {
18450b57cec5SDimitry Andric   OS << ' ' << D->getKindName();
18460b57cec5SDimitry Andric   dumpName(D);
18470b57cec5SDimitry Andric   if (D->isModulePrivate())
18480b57cec5SDimitry Andric     OS << " __module_private__";
18490b57cec5SDimitry Andric   if (D->isCompleteDefinition())
18500b57cec5SDimitry Andric     OS << " definition";
18510b57cec5SDimitry Andric }
18520b57cec5SDimitry Andric 
VisitEnumConstantDecl(const EnumConstantDecl * D)18530b57cec5SDimitry Andric void TextNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
18540b57cec5SDimitry Andric   dumpName(D);
18550b57cec5SDimitry Andric   dumpType(D->getType());
18560b57cec5SDimitry Andric }
18570b57cec5SDimitry Andric 
VisitIndirectFieldDecl(const IndirectFieldDecl * D)18580b57cec5SDimitry Andric void TextNodeDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
18590b57cec5SDimitry Andric   dumpName(D);
18600b57cec5SDimitry Andric   dumpType(D->getType());
18610b57cec5SDimitry Andric 
18620b57cec5SDimitry Andric   for (const auto *Child : D->chain())
18630b57cec5SDimitry Andric     dumpDeclRef(Child);
18640b57cec5SDimitry Andric }
18650b57cec5SDimitry Andric 
VisitFunctionDecl(const FunctionDecl * D)18660b57cec5SDimitry Andric void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) {
18670b57cec5SDimitry Andric   dumpName(D);
18680b57cec5SDimitry Andric   dumpType(D->getType());
18695f757f3fSDimitry Andric   dumpTemplateSpecializationKind(D->getTemplateSpecializationKind());
18700b57cec5SDimitry Andric 
18710b57cec5SDimitry Andric   StorageClass SC = D->getStorageClass();
18720b57cec5SDimitry Andric   if (SC != SC_None)
18730b57cec5SDimitry Andric     OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
18740b57cec5SDimitry Andric   if (D->isInlineSpecified())
18750b57cec5SDimitry Andric     OS << " inline";
18760b57cec5SDimitry Andric   if (D->isVirtualAsWritten())
18770b57cec5SDimitry Andric     OS << " virtual";
18780b57cec5SDimitry Andric   if (D->isModulePrivate())
18790b57cec5SDimitry Andric     OS << " __module_private__";
18800b57cec5SDimitry Andric 
18817a6dacacSDimitry Andric   if (D->isPureVirtual())
18820b57cec5SDimitry Andric     OS << " pure";
18830b57cec5SDimitry Andric   if (D->isDefaulted()) {
18840b57cec5SDimitry Andric     OS << " default";
18850b57cec5SDimitry Andric     if (D->isDeleted())
18860b57cec5SDimitry Andric       OS << "_delete";
18870b57cec5SDimitry Andric   }
18880b57cec5SDimitry Andric   if (D->isDeletedAsWritten())
18890b57cec5SDimitry Andric     OS << " delete";
18900b57cec5SDimitry Andric   if (D->isTrivial())
18910b57cec5SDimitry Andric     OS << " trivial";
18920b57cec5SDimitry Andric 
189381ad6265SDimitry Andric   if (D->isIneligibleOrNotSelected())
189481ad6265SDimitry Andric     OS << (isa<CXXDestructorDecl>(D) ? " not_selected" : " ineligible");
189581ad6265SDimitry Andric 
18960b57cec5SDimitry Andric   if (const auto *FPT = D->getType()->getAs<FunctionProtoType>()) {
18970b57cec5SDimitry Andric     FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
18980b57cec5SDimitry Andric     switch (EPI.ExceptionSpec.Type) {
18990b57cec5SDimitry Andric     default:
19000b57cec5SDimitry Andric       break;
19010b57cec5SDimitry Andric     case EST_Unevaluated:
19020b57cec5SDimitry Andric       OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl;
19030b57cec5SDimitry Andric       break;
19040b57cec5SDimitry Andric     case EST_Uninstantiated:
19050b57cec5SDimitry Andric       OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate;
19060b57cec5SDimitry Andric       break;
19070b57cec5SDimitry Andric     }
19080b57cec5SDimitry Andric   }
19090b57cec5SDimitry Andric 
19100b57cec5SDimitry Andric   if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
19110b57cec5SDimitry Andric     if (MD->size_overridden_methods() != 0) {
19120b57cec5SDimitry Andric       auto dumpOverride = [=](const CXXMethodDecl *D) {
19130b57cec5SDimitry Andric         SplitQualType T_split = D->getType().split();
1914e8d8bef9SDimitry Andric         OS << D << " " << D->getParent()->getName() << "::" << D->getDeclName()
1915e8d8bef9SDimitry Andric            << " '" << QualType::getAsString(T_split, PrintPolicy) << "'";
19160b57cec5SDimitry Andric       };
19170b57cec5SDimitry Andric 
19180b57cec5SDimitry Andric       AddChild([=] {
19190b57cec5SDimitry Andric         auto Overrides = MD->overridden_methods();
19200b57cec5SDimitry Andric         OS << "Overrides: [ ";
19210b57cec5SDimitry Andric         dumpOverride(*Overrides.begin());
19225f757f3fSDimitry Andric         for (const auto *Override : llvm::drop_begin(Overrides)) {
19230b57cec5SDimitry Andric           OS << ", ";
19240b57cec5SDimitry Andric           dumpOverride(Override);
19250b57cec5SDimitry Andric         }
19260b57cec5SDimitry Andric         OS << " ]";
19270b57cec5SDimitry Andric       });
19280b57cec5SDimitry Andric     }
19290b57cec5SDimitry Andric   }
19300b57cec5SDimitry Andric 
1931fcaf7f86SDimitry Andric   if (!D->isInlineSpecified() && D->isInlined()) {
1932fcaf7f86SDimitry Andric     OS << " implicit-inline";
1933fcaf7f86SDimitry Andric   }
19340b57cec5SDimitry Andric   // Since NumParams comes from the FunctionProtoType of the FunctionDecl and
19350b57cec5SDimitry Andric   // the Params are set later, it is possible for a dump during debugging to
19360b57cec5SDimitry Andric   // encounter a FunctionDecl that has been created but hasn't been assigned
19370b57cec5SDimitry Andric   // ParmVarDecls yet.
19380b57cec5SDimitry Andric   if (!D->param_empty() && !D->param_begin())
19390b57cec5SDimitry Andric     OS << " <<<NULL params x " << D->getNumParams() << ">>>";
19405f757f3fSDimitry Andric 
19415f757f3fSDimitry Andric   if (const auto *Instance = D->getInstantiatedFromMemberFunction()) {
19425f757f3fSDimitry Andric     OS << " instantiated_from";
19435f757f3fSDimitry Andric     dumpPointer(Instance);
19445f757f3fSDimitry Andric   }
19450b57cec5SDimitry Andric }
19460b57cec5SDimitry Andric 
VisitLifetimeExtendedTemporaryDecl(const LifetimeExtendedTemporaryDecl * D)1947480093f4SDimitry Andric void TextNodeDumper::VisitLifetimeExtendedTemporaryDecl(
1948480093f4SDimitry Andric     const LifetimeExtendedTemporaryDecl *D) {
1949480093f4SDimitry Andric   OS << " extended by ";
1950480093f4SDimitry Andric   dumpBareDeclRef(D->getExtendingDecl());
1951480093f4SDimitry Andric   OS << " mangling ";
1952480093f4SDimitry Andric   {
1953480093f4SDimitry Andric     ColorScope Color(OS, ShowColors, ValueColor);
1954480093f4SDimitry Andric     OS << D->getManglingNumber();
1955480093f4SDimitry Andric   }
1956480093f4SDimitry Andric }
1957480093f4SDimitry Andric 
VisitFieldDecl(const FieldDecl * D)19580b57cec5SDimitry Andric void TextNodeDumper::VisitFieldDecl(const FieldDecl *D) {
19590b57cec5SDimitry Andric   dumpName(D);
19600b57cec5SDimitry Andric   dumpType(D->getType());
19610b57cec5SDimitry Andric   if (D->isMutable())
19620b57cec5SDimitry Andric     OS << " mutable";
19630b57cec5SDimitry Andric   if (D->isModulePrivate())
19640b57cec5SDimitry Andric     OS << " __module_private__";
19650b57cec5SDimitry Andric }
19660b57cec5SDimitry Andric 
VisitVarDecl(const VarDecl * D)19670b57cec5SDimitry Andric void TextNodeDumper::VisitVarDecl(const VarDecl *D) {
19685f757f3fSDimitry Andric   dumpNestedNameSpecifier(D->getQualifier());
19690b57cec5SDimitry Andric   dumpName(D);
19705f757f3fSDimitry Andric   if (const auto *P = dyn_cast<ParmVarDecl>(D);
19715f757f3fSDimitry Andric       P && P->isExplicitObjectParameter())
19725f757f3fSDimitry Andric     OS << " this";
19735f757f3fSDimitry Andric 
19740b57cec5SDimitry Andric   dumpType(D->getType());
19755f757f3fSDimitry Andric   dumpTemplateSpecializationKind(D->getTemplateSpecializationKind());
19760b57cec5SDimitry Andric   StorageClass SC = D->getStorageClass();
19770b57cec5SDimitry Andric   if (SC != SC_None)
19780b57cec5SDimitry Andric     OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
19790b57cec5SDimitry Andric   switch (D->getTLSKind()) {
19800b57cec5SDimitry Andric   case VarDecl::TLS_None:
19810b57cec5SDimitry Andric     break;
19820b57cec5SDimitry Andric   case VarDecl::TLS_Static:
19830b57cec5SDimitry Andric     OS << " tls";
19840b57cec5SDimitry Andric     break;
19850b57cec5SDimitry Andric   case VarDecl::TLS_Dynamic:
19860b57cec5SDimitry Andric     OS << " tls_dynamic";
19870b57cec5SDimitry Andric     break;
19880b57cec5SDimitry Andric   }
19890b57cec5SDimitry Andric   if (D->isModulePrivate())
19900b57cec5SDimitry Andric     OS << " __module_private__";
19910b57cec5SDimitry Andric   if (D->isNRVOVariable())
19920b57cec5SDimitry Andric     OS << " nrvo";
19930b57cec5SDimitry Andric   if (D->isInline())
19940b57cec5SDimitry Andric     OS << " inline";
19950b57cec5SDimitry Andric   if (D->isConstexpr())
19960b57cec5SDimitry Andric     OS << " constexpr";
19970b57cec5SDimitry Andric   if (D->hasInit()) {
19980b57cec5SDimitry Andric     switch (D->getInitStyle()) {
19990b57cec5SDimitry Andric     case VarDecl::CInit:
20000b57cec5SDimitry Andric       OS << " cinit";
20010b57cec5SDimitry Andric       break;
20020b57cec5SDimitry Andric     case VarDecl::CallInit:
20030b57cec5SDimitry Andric       OS << " callinit";
20040b57cec5SDimitry Andric       break;
20050b57cec5SDimitry Andric     case VarDecl::ListInit:
20060b57cec5SDimitry Andric       OS << " listinit";
20070b57cec5SDimitry Andric       break;
2008bdd1243dSDimitry Andric     case VarDecl::ParenListInit:
2009bdd1243dSDimitry Andric       OS << " parenlistinit";
20100b57cec5SDimitry Andric     }
20110b57cec5SDimitry Andric   }
2012a7dea167SDimitry Andric   if (D->needsDestruction(D->getASTContext()))
2013a7dea167SDimitry Andric     OS << " destroyed";
20140b57cec5SDimitry Andric   if (D->isParameterPack())
20150b57cec5SDimitry Andric     OS << " pack";
20165ffd83dbSDimitry Andric 
20175ffd83dbSDimitry Andric   if (D->hasInit()) {
20185ffd83dbSDimitry Andric     const Expr *E = D->getInit();
20195ffd83dbSDimitry Andric     // Only dump the value of constexpr VarDecls for now.
202006c3fb27SDimitry Andric     if (E && !E->isValueDependent() && D->isConstexpr() &&
202106c3fb27SDimitry Andric         !D->getType()->isDependentType()) {
20225ffd83dbSDimitry Andric       const APValue *Value = D->evaluateValue();
20235ffd83dbSDimitry Andric       if (Value)
20245ffd83dbSDimitry Andric         AddChild("value", [=] { Visit(*Value, E->getType()); });
20255ffd83dbSDimitry Andric     }
20265ffd83dbSDimitry Andric   }
20270b57cec5SDimitry Andric }
20280b57cec5SDimitry Andric 
VisitBindingDecl(const BindingDecl * D)20290b57cec5SDimitry Andric void TextNodeDumper::VisitBindingDecl(const BindingDecl *D) {
20300b57cec5SDimitry Andric   dumpName(D);
20310b57cec5SDimitry Andric   dumpType(D->getType());
20320b57cec5SDimitry Andric }
20330b57cec5SDimitry Andric 
VisitCapturedDecl(const CapturedDecl * D)20340b57cec5SDimitry Andric void TextNodeDumper::VisitCapturedDecl(const CapturedDecl *D) {
20350b57cec5SDimitry Andric   if (D->isNothrow())
20360b57cec5SDimitry Andric     OS << " nothrow";
20370b57cec5SDimitry Andric }
20380b57cec5SDimitry Andric 
VisitImportDecl(const ImportDecl * D)20390b57cec5SDimitry Andric void TextNodeDumper::VisitImportDecl(const ImportDecl *D) {
20400b57cec5SDimitry Andric   OS << ' ' << D->getImportedModule()->getFullModuleName();
20410b57cec5SDimitry Andric 
20420b57cec5SDimitry Andric   for (Decl *InitD :
20430b57cec5SDimitry Andric        D->getASTContext().getModuleInitializers(D->getImportedModule()))
20440b57cec5SDimitry Andric     dumpDeclRef(InitD, "initializer");
20450b57cec5SDimitry Andric }
20460b57cec5SDimitry Andric 
VisitPragmaCommentDecl(const PragmaCommentDecl * D)20470b57cec5SDimitry Andric void TextNodeDumper::VisitPragmaCommentDecl(const PragmaCommentDecl *D) {
20480b57cec5SDimitry Andric   OS << ' ';
20490b57cec5SDimitry Andric   switch (D->getCommentKind()) {
20500b57cec5SDimitry Andric   case PCK_Unknown:
20510b57cec5SDimitry Andric     llvm_unreachable("unexpected pragma comment kind");
20520b57cec5SDimitry Andric   case PCK_Compiler:
20530b57cec5SDimitry Andric     OS << "compiler";
20540b57cec5SDimitry Andric     break;
20550b57cec5SDimitry Andric   case PCK_ExeStr:
20560b57cec5SDimitry Andric     OS << "exestr";
20570b57cec5SDimitry Andric     break;
20580b57cec5SDimitry Andric   case PCK_Lib:
20590b57cec5SDimitry Andric     OS << "lib";
20600b57cec5SDimitry Andric     break;
20610b57cec5SDimitry Andric   case PCK_Linker:
20620b57cec5SDimitry Andric     OS << "linker";
20630b57cec5SDimitry Andric     break;
20640b57cec5SDimitry Andric   case PCK_User:
20650b57cec5SDimitry Andric     OS << "user";
20660b57cec5SDimitry Andric     break;
20670b57cec5SDimitry Andric   }
20680b57cec5SDimitry Andric   StringRef Arg = D->getArg();
20690b57cec5SDimitry Andric   if (!Arg.empty())
20700b57cec5SDimitry Andric     OS << " \"" << Arg << "\"";
20710b57cec5SDimitry Andric }
20720b57cec5SDimitry Andric 
VisitPragmaDetectMismatchDecl(const PragmaDetectMismatchDecl * D)20730b57cec5SDimitry Andric void TextNodeDumper::VisitPragmaDetectMismatchDecl(
20740b57cec5SDimitry Andric     const PragmaDetectMismatchDecl *D) {
20750b57cec5SDimitry Andric   OS << " \"" << D->getName() << "\" \"" << D->getValue() << "\"";
20760b57cec5SDimitry Andric }
20770b57cec5SDimitry Andric 
VisitOMPExecutableDirective(const OMPExecutableDirective * D)20780b57cec5SDimitry Andric void TextNodeDumper::VisitOMPExecutableDirective(
20790b57cec5SDimitry Andric     const OMPExecutableDirective *D) {
20800b57cec5SDimitry Andric   if (D->isStandaloneDirective())
20810b57cec5SDimitry Andric     OS << " openmp_standalone_directive";
20820b57cec5SDimitry Andric }
20830b57cec5SDimitry Andric 
VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl * D)20840b57cec5SDimitry Andric void TextNodeDumper::VisitOMPDeclareReductionDecl(
20850b57cec5SDimitry Andric     const OMPDeclareReductionDecl *D) {
20860b57cec5SDimitry Andric   dumpName(D);
20870b57cec5SDimitry Andric   dumpType(D->getType());
20880b57cec5SDimitry Andric   OS << " combiner";
20890b57cec5SDimitry Andric   dumpPointer(D->getCombiner());
20900b57cec5SDimitry Andric   if (const auto *Initializer = D->getInitializer()) {
20910b57cec5SDimitry Andric     OS << " initializer";
20920b57cec5SDimitry Andric     dumpPointer(Initializer);
20930b57cec5SDimitry Andric     switch (D->getInitializerKind()) {
20945f757f3fSDimitry Andric     case OMPDeclareReductionInitKind::Direct:
20950b57cec5SDimitry Andric       OS << " omp_priv = ";
20960b57cec5SDimitry Andric       break;
20975f757f3fSDimitry Andric     case OMPDeclareReductionInitKind::Copy:
20980b57cec5SDimitry Andric       OS << " omp_priv ()";
20990b57cec5SDimitry Andric       break;
21005f757f3fSDimitry Andric     case OMPDeclareReductionInitKind::Call:
21010b57cec5SDimitry Andric       break;
21020b57cec5SDimitry Andric     }
21030b57cec5SDimitry Andric   }
21040b57cec5SDimitry Andric }
21050b57cec5SDimitry Andric 
VisitOMPRequiresDecl(const OMPRequiresDecl * D)21060b57cec5SDimitry Andric void TextNodeDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) {
21070b57cec5SDimitry Andric   for (const auto *C : D->clauselists()) {
21080b57cec5SDimitry Andric     AddChild([=] {
21090b57cec5SDimitry Andric       if (!C) {
21100b57cec5SDimitry Andric         ColorScope Color(OS, ShowColors, NullColor);
21110b57cec5SDimitry Andric         OS << "<<<NULL>>> OMPClause";
21120b57cec5SDimitry Andric         return;
21130b57cec5SDimitry Andric       }
21140b57cec5SDimitry Andric       {
21150b57cec5SDimitry Andric         ColorScope Color(OS, ShowColors, AttrColor);
21165ffd83dbSDimitry Andric         StringRef ClauseName(
21175ffd83dbSDimitry Andric             llvm::omp::getOpenMPClauseName(C->getClauseKind()));
21180b57cec5SDimitry Andric         OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
21190b57cec5SDimitry Andric            << ClauseName.drop_front() << "Clause";
21200b57cec5SDimitry Andric       }
21210b57cec5SDimitry Andric       dumpPointer(C);
21220b57cec5SDimitry Andric       dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
21230b57cec5SDimitry Andric     });
21240b57cec5SDimitry Andric   }
21250b57cec5SDimitry Andric }
21260b57cec5SDimitry Andric 
VisitOMPCapturedExprDecl(const OMPCapturedExprDecl * D)21270b57cec5SDimitry Andric void TextNodeDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
21280b57cec5SDimitry Andric   dumpName(D);
21290b57cec5SDimitry Andric   dumpType(D->getType());
21300b57cec5SDimitry Andric }
21310b57cec5SDimitry Andric 
VisitNamespaceDecl(const NamespaceDecl * D)21320b57cec5SDimitry Andric void TextNodeDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
21330b57cec5SDimitry Andric   dumpName(D);
21340b57cec5SDimitry Andric   if (D->isInline())
21350b57cec5SDimitry Andric     OS << " inline";
2136bdd1243dSDimitry Andric   if (D->isNested())
2137bdd1243dSDimitry Andric     OS << " nested";
21380b57cec5SDimitry Andric   if (!D->isOriginalNamespace())
21390b57cec5SDimitry Andric     dumpDeclRef(D->getOriginalNamespace(), "original");
21400b57cec5SDimitry Andric }
21410b57cec5SDimitry Andric 
VisitUsingDirectiveDecl(const UsingDirectiveDecl * D)21420b57cec5SDimitry Andric void TextNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
21430b57cec5SDimitry Andric   OS << ' ';
21440b57cec5SDimitry Andric   dumpBareDeclRef(D->getNominatedNamespace());
21450b57cec5SDimitry Andric }
21460b57cec5SDimitry Andric 
VisitNamespaceAliasDecl(const NamespaceAliasDecl * D)21470b57cec5SDimitry Andric void TextNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
21480b57cec5SDimitry Andric   dumpName(D);
21490b57cec5SDimitry Andric   dumpDeclRef(D->getAliasedNamespace());
21500b57cec5SDimitry Andric }
21510b57cec5SDimitry Andric 
VisitTypeAliasDecl(const TypeAliasDecl * D)21520b57cec5SDimitry Andric void TextNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
21530b57cec5SDimitry Andric   dumpName(D);
21540b57cec5SDimitry Andric   dumpType(D->getUnderlyingType());
21550b57cec5SDimitry Andric }
21560b57cec5SDimitry Andric 
VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl * D)21570b57cec5SDimitry Andric void TextNodeDumper::VisitTypeAliasTemplateDecl(
21580b57cec5SDimitry Andric     const TypeAliasTemplateDecl *D) {
21590b57cec5SDimitry Andric   dumpName(D);
21600b57cec5SDimitry Andric }
21610b57cec5SDimitry Andric 
VisitCXXRecordDecl(const CXXRecordDecl * D)21620b57cec5SDimitry Andric void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
21630b57cec5SDimitry Andric   VisitRecordDecl(D);
21645f757f3fSDimitry Andric   if (const auto *Instance = D->getInstantiatedFromMemberClass()) {
21655f757f3fSDimitry Andric     OS << " instantiated_from";
21665f757f3fSDimitry Andric     dumpPointer(Instance);
21675f757f3fSDimitry Andric   }
21685f757f3fSDimitry Andric   if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D))
21695f757f3fSDimitry Andric     dumpTemplateSpecializationKind(CTSD->getSpecializationKind());
21705f757f3fSDimitry Andric 
21715f757f3fSDimitry Andric   dumpNestedNameSpecifier(D->getQualifier());
21725f757f3fSDimitry Andric 
21730b57cec5SDimitry Andric   if (!D->isCompleteDefinition())
21740b57cec5SDimitry Andric     return;
21750b57cec5SDimitry Andric 
21760b57cec5SDimitry Andric   AddChild([=] {
21770b57cec5SDimitry Andric     {
21780b57cec5SDimitry Andric       ColorScope Color(OS, ShowColors, DeclKindNameColor);
21790b57cec5SDimitry Andric       OS << "DefinitionData";
21800b57cec5SDimitry Andric     }
21810b57cec5SDimitry Andric #define FLAG(fn, name)                                                         \
21820b57cec5SDimitry Andric   if (D->fn())                                                                 \
21830b57cec5SDimitry Andric     OS << " " #name;
21840b57cec5SDimitry Andric     FLAG(isParsingBaseSpecifiers, parsing_base_specifiers);
21850b57cec5SDimitry Andric 
21860b57cec5SDimitry Andric     FLAG(isGenericLambda, generic);
21870b57cec5SDimitry Andric     FLAG(isLambda, lambda);
21880b57cec5SDimitry Andric 
2189a7dea167SDimitry Andric     FLAG(isAnonymousStructOrUnion, is_anonymous);
21900b57cec5SDimitry Andric     FLAG(canPassInRegisters, pass_in_registers);
21910b57cec5SDimitry Andric     FLAG(isEmpty, empty);
21920b57cec5SDimitry Andric     FLAG(isAggregate, aggregate);
21930b57cec5SDimitry Andric     FLAG(isStandardLayout, standard_layout);
21940b57cec5SDimitry Andric     FLAG(isTriviallyCopyable, trivially_copyable);
21950b57cec5SDimitry Andric     FLAG(isPOD, pod);
21960b57cec5SDimitry Andric     FLAG(isTrivial, trivial);
21970b57cec5SDimitry Andric     FLAG(isPolymorphic, polymorphic);
21980b57cec5SDimitry Andric     FLAG(isAbstract, abstract);
21990b57cec5SDimitry Andric     FLAG(isLiteral, literal);
22000b57cec5SDimitry Andric 
22010b57cec5SDimitry Andric     FLAG(hasUserDeclaredConstructor, has_user_declared_ctor);
22020b57cec5SDimitry Andric     FLAG(hasConstexprNonCopyMoveConstructor, has_constexpr_non_copy_move_ctor);
22030b57cec5SDimitry Andric     FLAG(hasMutableFields, has_mutable_fields);
22040b57cec5SDimitry Andric     FLAG(hasVariantMembers, has_variant_members);
22050b57cec5SDimitry Andric     FLAG(allowConstDefaultInit, can_const_default_init);
22060b57cec5SDimitry Andric 
22070b57cec5SDimitry Andric     AddChild([=] {
22080b57cec5SDimitry Andric       {
22090b57cec5SDimitry Andric         ColorScope Color(OS, ShowColors, DeclKindNameColor);
22100b57cec5SDimitry Andric         OS << "DefaultConstructor";
22110b57cec5SDimitry Andric       }
22120b57cec5SDimitry Andric       FLAG(hasDefaultConstructor, exists);
22130b57cec5SDimitry Andric       FLAG(hasTrivialDefaultConstructor, trivial);
22140b57cec5SDimitry Andric       FLAG(hasNonTrivialDefaultConstructor, non_trivial);
22150b57cec5SDimitry Andric       FLAG(hasUserProvidedDefaultConstructor, user_provided);
22160b57cec5SDimitry Andric       FLAG(hasConstexprDefaultConstructor, constexpr);
22170b57cec5SDimitry Andric       FLAG(needsImplicitDefaultConstructor, needs_implicit);
22180b57cec5SDimitry Andric       FLAG(defaultedDefaultConstructorIsConstexpr, defaulted_is_constexpr);
22190b57cec5SDimitry Andric     });
22200b57cec5SDimitry Andric 
22210b57cec5SDimitry Andric     AddChild([=] {
22220b57cec5SDimitry Andric       {
22230b57cec5SDimitry Andric         ColorScope Color(OS, ShowColors, DeclKindNameColor);
22240b57cec5SDimitry Andric         OS << "CopyConstructor";
22250b57cec5SDimitry Andric       }
22260b57cec5SDimitry Andric       FLAG(hasSimpleCopyConstructor, simple);
22270b57cec5SDimitry Andric       FLAG(hasTrivialCopyConstructor, trivial);
22280b57cec5SDimitry Andric       FLAG(hasNonTrivialCopyConstructor, non_trivial);
22290b57cec5SDimitry Andric       FLAG(hasUserDeclaredCopyConstructor, user_declared);
22300b57cec5SDimitry Andric       FLAG(hasCopyConstructorWithConstParam, has_const_param);
22310b57cec5SDimitry Andric       FLAG(needsImplicitCopyConstructor, needs_implicit);
22320b57cec5SDimitry Andric       FLAG(needsOverloadResolutionForCopyConstructor,
22330b57cec5SDimitry Andric            needs_overload_resolution);
22340b57cec5SDimitry Andric       if (!D->needsOverloadResolutionForCopyConstructor())
22350b57cec5SDimitry Andric         FLAG(defaultedCopyConstructorIsDeleted, defaulted_is_deleted);
22360b57cec5SDimitry Andric       FLAG(implicitCopyConstructorHasConstParam, implicit_has_const_param);
22370b57cec5SDimitry Andric     });
22380b57cec5SDimitry Andric 
22390b57cec5SDimitry Andric     AddChild([=] {
22400b57cec5SDimitry Andric       {
22410b57cec5SDimitry Andric         ColorScope Color(OS, ShowColors, DeclKindNameColor);
22420b57cec5SDimitry Andric         OS << "MoveConstructor";
22430b57cec5SDimitry Andric       }
22440b57cec5SDimitry Andric       FLAG(hasMoveConstructor, exists);
22450b57cec5SDimitry Andric       FLAG(hasSimpleMoveConstructor, simple);
22460b57cec5SDimitry Andric       FLAG(hasTrivialMoveConstructor, trivial);
22470b57cec5SDimitry Andric       FLAG(hasNonTrivialMoveConstructor, non_trivial);
22480b57cec5SDimitry Andric       FLAG(hasUserDeclaredMoveConstructor, user_declared);
22490b57cec5SDimitry Andric       FLAG(needsImplicitMoveConstructor, needs_implicit);
22500b57cec5SDimitry Andric       FLAG(needsOverloadResolutionForMoveConstructor,
22510b57cec5SDimitry Andric            needs_overload_resolution);
22520b57cec5SDimitry Andric       if (!D->needsOverloadResolutionForMoveConstructor())
22530b57cec5SDimitry Andric         FLAG(defaultedMoveConstructorIsDeleted, defaulted_is_deleted);
22540b57cec5SDimitry Andric     });
22550b57cec5SDimitry Andric 
22560b57cec5SDimitry Andric     AddChild([=] {
22570b57cec5SDimitry Andric       {
22580b57cec5SDimitry Andric         ColorScope Color(OS, ShowColors, DeclKindNameColor);
22590b57cec5SDimitry Andric         OS << "CopyAssignment";
22600b57cec5SDimitry Andric       }
22615ffd83dbSDimitry Andric       FLAG(hasSimpleCopyAssignment, simple);
22620b57cec5SDimitry Andric       FLAG(hasTrivialCopyAssignment, trivial);
22630b57cec5SDimitry Andric       FLAG(hasNonTrivialCopyAssignment, non_trivial);
22640b57cec5SDimitry Andric       FLAG(hasCopyAssignmentWithConstParam, has_const_param);
22650b57cec5SDimitry Andric       FLAG(hasUserDeclaredCopyAssignment, user_declared);
22660b57cec5SDimitry Andric       FLAG(needsImplicitCopyAssignment, needs_implicit);
22670b57cec5SDimitry Andric       FLAG(needsOverloadResolutionForCopyAssignment, needs_overload_resolution);
22680b57cec5SDimitry Andric       FLAG(implicitCopyAssignmentHasConstParam, implicit_has_const_param);
22690b57cec5SDimitry Andric     });
22700b57cec5SDimitry Andric 
22710b57cec5SDimitry Andric     AddChild([=] {
22720b57cec5SDimitry Andric       {
22730b57cec5SDimitry Andric         ColorScope Color(OS, ShowColors, DeclKindNameColor);
22740b57cec5SDimitry Andric         OS << "MoveAssignment";
22750b57cec5SDimitry Andric       }
22760b57cec5SDimitry Andric       FLAG(hasMoveAssignment, exists);
22770b57cec5SDimitry Andric       FLAG(hasSimpleMoveAssignment, simple);
22780b57cec5SDimitry Andric       FLAG(hasTrivialMoveAssignment, trivial);
22790b57cec5SDimitry Andric       FLAG(hasNonTrivialMoveAssignment, non_trivial);
22800b57cec5SDimitry Andric       FLAG(hasUserDeclaredMoveAssignment, user_declared);
22810b57cec5SDimitry Andric       FLAG(needsImplicitMoveAssignment, needs_implicit);
22820b57cec5SDimitry Andric       FLAG(needsOverloadResolutionForMoveAssignment, needs_overload_resolution);
22830b57cec5SDimitry Andric     });
22840b57cec5SDimitry Andric 
22850b57cec5SDimitry Andric     AddChild([=] {
22860b57cec5SDimitry Andric       {
22870b57cec5SDimitry Andric         ColorScope Color(OS, ShowColors, DeclKindNameColor);
22880b57cec5SDimitry Andric         OS << "Destructor";
22890b57cec5SDimitry Andric       }
22900b57cec5SDimitry Andric       FLAG(hasSimpleDestructor, simple);
22910b57cec5SDimitry Andric       FLAG(hasIrrelevantDestructor, irrelevant);
22920b57cec5SDimitry Andric       FLAG(hasTrivialDestructor, trivial);
22930b57cec5SDimitry Andric       FLAG(hasNonTrivialDestructor, non_trivial);
22940b57cec5SDimitry Andric       FLAG(hasUserDeclaredDestructor, user_declared);
2295a7dea167SDimitry Andric       FLAG(hasConstexprDestructor, constexpr);
22960b57cec5SDimitry Andric       FLAG(needsImplicitDestructor, needs_implicit);
22970b57cec5SDimitry Andric       FLAG(needsOverloadResolutionForDestructor, needs_overload_resolution);
22980b57cec5SDimitry Andric       if (!D->needsOverloadResolutionForDestructor())
22990b57cec5SDimitry Andric         FLAG(defaultedDestructorIsDeleted, defaulted_is_deleted);
23000b57cec5SDimitry Andric     });
23010b57cec5SDimitry Andric   });
23020b57cec5SDimitry Andric 
23030b57cec5SDimitry Andric   for (const auto &I : D->bases()) {
23040b57cec5SDimitry Andric     AddChild([=] {
23050b57cec5SDimitry Andric       if (I.isVirtual())
23060b57cec5SDimitry Andric         OS << "virtual ";
23070b57cec5SDimitry Andric       dumpAccessSpecifier(I.getAccessSpecifier());
23080b57cec5SDimitry Andric       dumpType(I.getType());
23090b57cec5SDimitry Andric       if (I.isPackExpansion())
23100b57cec5SDimitry Andric         OS << "...";
23110b57cec5SDimitry Andric     });
23120b57cec5SDimitry Andric   }
23130b57cec5SDimitry Andric }
23140b57cec5SDimitry Andric 
VisitFunctionTemplateDecl(const FunctionTemplateDecl * D)23150b57cec5SDimitry Andric void TextNodeDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
23160b57cec5SDimitry Andric   dumpName(D);
23170b57cec5SDimitry Andric }
23180b57cec5SDimitry Andric 
VisitClassTemplateDecl(const ClassTemplateDecl * D)23190b57cec5SDimitry Andric void TextNodeDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
23200b57cec5SDimitry Andric   dumpName(D);
23210b57cec5SDimitry Andric }
23220b57cec5SDimitry Andric 
VisitVarTemplateDecl(const VarTemplateDecl * D)23230b57cec5SDimitry Andric void TextNodeDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
23240b57cec5SDimitry Andric   dumpName(D);
23250b57cec5SDimitry Andric }
23260b57cec5SDimitry Andric 
VisitBuiltinTemplateDecl(const BuiltinTemplateDecl * D)23270b57cec5SDimitry Andric void TextNodeDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
23280b57cec5SDimitry Andric   dumpName(D);
23290b57cec5SDimitry Andric }
23300b57cec5SDimitry Andric 
VisitTemplateTypeParmDecl(const TemplateTypeParmDecl * D)23310b57cec5SDimitry Andric void TextNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
2332480093f4SDimitry Andric   if (const auto *TC = D->getTypeConstraint()) {
2333480093f4SDimitry Andric     OS << " ";
2334480093f4SDimitry Andric     dumpBareDeclRef(TC->getNamedConcept());
2335480093f4SDimitry Andric     if (TC->getNamedConcept() != TC->getFoundDecl()) {
2336480093f4SDimitry Andric       OS << " (";
2337480093f4SDimitry Andric       dumpBareDeclRef(TC->getFoundDecl());
2338480093f4SDimitry Andric       OS << ")";
2339480093f4SDimitry Andric     }
2340480093f4SDimitry Andric   } else if (D->wasDeclaredWithTypename())
23410b57cec5SDimitry Andric     OS << " typename";
23420b57cec5SDimitry Andric   else
23430b57cec5SDimitry Andric     OS << " class";
23440b57cec5SDimitry Andric   OS << " depth " << D->getDepth() << " index " << D->getIndex();
23450b57cec5SDimitry Andric   if (D->isParameterPack())
23460b57cec5SDimitry Andric     OS << " ...";
23470b57cec5SDimitry Andric   dumpName(D);
23480b57cec5SDimitry Andric }
23490b57cec5SDimitry Andric 
VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl * D)23500b57cec5SDimitry Andric void TextNodeDumper::VisitNonTypeTemplateParmDecl(
23510b57cec5SDimitry Andric     const NonTypeTemplateParmDecl *D) {
23520b57cec5SDimitry Andric   dumpType(D->getType());
23530b57cec5SDimitry Andric   OS << " depth " << D->getDepth() << " index " << D->getIndex();
23540b57cec5SDimitry Andric   if (D->isParameterPack())
23550b57cec5SDimitry Andric     OS << " ...";
23560b57cec5SDimitry Andric   dumpName(D);
23570b57cec5SDimitry Andric }
23580b57cec5SDimitry Andric 
VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl * D)23590b57cec5SDimitry Andric void TextNodeDumper::VisitTemplateTemplateParmDecl(
23600b57cec5SDimitry Andric     const TemplateTemplateParmDecl *D) {
23610b57cec5SDimitry Andric   OS << " depth " << D->getDepth() << " index " << D->getIndex();
23620b57cec5SDimitry Andric   if (D->isParameterPack())
23630b57cec5SDimitry Andric     OS << " ...";
23640b57cec5SDimitry Andric   dumpName(D);
23650b57cec5SDimitry Andric }
23660b57cec5SDimitry Andric 
VisitUsingDecl(const UsingDecl * D)23670b57cec5SDimitry Andric void TextNodeDumper::VisitUsingDecl(const UsingDecl *D) {
23680b57cec5SDimitry Andric   OS << ' ';
23690b57cec5SDimitry Andric   if (D->getQualifier())
23700b57cec5SDimitry Andric     D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2371e8d8bef9SDimitry Andric   OS << D->getDeclName();
23725f757f3fSDimitry Andric   dumpNestedNameSpecifier(D->getQualifier());
23730b57cec5SDimitry Andric }
23740b57cec5SDimitry Andric 
VisitUsingEnumDecl(const UsingEnumDecl * D)2375fe6060f1SDimitry Andric void TextNodeDumper::VisitUsingEnumDecl(const UsingEnumDecl *D) {
2376fe6060f1SDimitry Andric   OS << ' ';
2377fe6060f1SDimitry Andric   dumpBareDeclRef(D->getEnumDecl());
2378fe6060f1SDimitry Andric }
2379fe6060f1SDimitry Andric 
VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl * D)23800b57cec5SDimitry Andric void TextNodeDumper::VisitUnresolvedUsingTypenameDecl(
23810b57cec5SDimitry Andric     const UnresolvedUsingTypenameDecl *D) {
23820b57cec5SDimitry Andric   OS << ' ';
23830b57cec5SDimitry Andric   if (D->getQualifier())
23840b57cec5SDimitry Andric     D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2385e8d8bef9SDimitry Andric   OS << D->getDeclName();
23860b57cec5SDimitry Andric }
23870b57cec5SDimitry Andric 
VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl * D)23880b57cec5SDimitry Andric void TextNodeDumper::VisitUnresolvedUsingValueDecl(
23890b57cec5SDimitry Andric     const UnresolvedUsingValueDecl *D) {
23900b57cec5SDimitry Andric   OS << ' ';
23910b57cec5SDimitry Andric   if (D->getQualifier())
23920b57cec5SDimitry Andric     D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2393e8d8bef9SDimitry Andric   OS << D->getDeclName();
23940b57cec5SDimitry Andric   dumpType(D->getType());
23950b57cec5SDimitry Andric }
23960b57cec5SDimitry Andric 
VisitUsingShadowDecl(const UsingShadowDecl * D)23970b57cec5SDimitry Andric void TextNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
23980b57cec5SDimitry Andric   OS << ' ';
23990b57cec5SDimitry Andric   dumpBareDeclRef(D->getTargetDecl());
24000b57cec5SDimitry Andric }
24010b57cec5SDimitry Andric 
VisitConstructorUsingShadowDecl(const ConstructorUsingShadowDecl * D)24020b57cec5SDimitry Andric void TextNodeDumper::VisitConstructorUsingShadowDecl(
24030b57cec5SDimitry Andric     const ConstructorUsingShadowDecl *D) {
24040b57cec5SDimitry Andric   if (D->constructsVirtualBase())
24050b57cec5SDimitry Andric     OS << " virtual";
24060b57cec5SDimitry Andric 
24070b57cec5SDimitry Andric   AddChild([=] {
24080b57cec5SDimitry Andric     OS << "target ";
24090b57cec5SDimitry Andric     dumpBareDeclRef(D->getTargetDecl());
24100b57cec5SDimitry Andric   });
24110b57cec5SDimitry Andric 
24120b57cec5SDimitry Andric   AddChild([=] {
24130b57cec5SDimitry Andric     OS << "nominated ";
24140b57cec5SDimitry Andric     dumpBareDeclRef(D->getNominatedBaseClass());
24150b57cec5SDimitry Andric     OS << ' ';
24160b57cec5SDimitry Andric     dumpBareDeclRef(D->getNominatedBaseClassShadowDecl());
24170b57cec5SDimitry Andric   });
24180b57cec5SDimitry Andric 
24190b57cec5SDimitry Andric   AddChild([=] {
24200b57cec5SDimitry Andric     OS << "constructed ";
24210b57cec5SDimitry Andric     dumpBareDeclRef(D->getConstructedBaseClass());
24220b57cec5SDimitry Andric     OS << ' ';
24230b57cec5SDimitry Andric     dumpBareDeclRef(D->getConstructedBaseClassShadowDecl());
24240b57cec5SDimitry Andric   });
24250b57cec5SDimitry Andric }
24260b57cec5SDimitry Andric 
VisitLinkageSpecDecl(const LinkageSpecDecl * D)24270b57cec5SDimitry Andric void TextNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
24280b57cec5SDimitry Andric   switch (D->getLanguage()) {
24295f757f3fSDimitry Andric   case LinkageSpecLanguageIDs::C:
24300b57cec5SDimitry Andric     OS << " C";
24310b57cec5SDimitry Andric     break;
24325f757f3fSDimitry Andric   case LinkageSpecLanguageIDs::CXX:
24330b57cec5SDimitry Andric     OS << " C++";
24340b57cec5SDimitry Andric     break;
24350b57cec5SDimitry Andric   }
24360b57cec5SDimitry Andric }
24370b57cec5SDimitry Andric 
VisitAccessSpecDecl(const AccessSpecDecl * D)24380b57cec5SDimitry Andric void TextNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
24390b57cec5SDimitry Andric   OS << ' ';
24400b57cec5SDimitry Andric   dumpAccessSpecifier(D->getAccess());
24410b57cec5SDimitry Andric }
24420b57cec5SDimitry Andric 
VisitFriendDecl(const FriendDecl * D)24430b57cec5SDimitry Andric void TextNodeDumper::VisitFriendDecl(const FriendDecl *D) {
24440b57cec5SDimitry Andric   if (TypeSourceInfo *T = D->getFriendType())
24450b57cec5SDimitry Andric     dumpType(T->getType());
24460b57cec5SDimitry Andric }
24470b57cec5SDimitry Andric 
VisitObjCIvarDecl(const ObjCIvarDecl * D)24480b57cec5SDimitry Andric void TextNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
24490b57cec5SDimitry Andric   dumpName(D);
24500b57cec5SDimitry Andric   dumpType(D->getType());
24510b57cec5SDimitry Andric   if (D->getSynthesize())
24520b57cec5SDimitry Andric     OS << " synthesize";
24530b57cec5SDimitry Andric 
24540b57cec5SDimitry Andric   switch (D->getAccessControl()) {
24550b57cec5SDimitry Andric   case ObjCIvarDecl::None:
24560b57cec5SDimitry Andric     OS << " none";
24570b57cec5SDimitry Andric     break;
24580b57cec5SDimitry Andric   case ObjCIvarDecl::Private:
24590b57cec5SDimitry Andric     OS << " private";
24600b57cec5SDimitry Andric     break;
24610b57cec5SDimitry Andric   case ObjCIvarDecl::Protected:
24620b57cec5SDimitry Andric     OS << " protected";
24630b57cec5SDimitry Andric     break;
24640b57cec5SDimitry Andric   case ObjCIvarDecl::Public:
24650b57cec5SDimitry Andric     OS << " public";
24660b57cec5SDimitry Andric     break;
24670b57cec5SDimitry Andric   case ObjCIvarDecl::Package:
24680b57cec5SDimitry Andric     OS << " package";
24690b57cec5SDimitry Andric     break;
24700b57cec5SDimitry Andric   }
24710b57cec5SDimitry Andric }
24720b57cec5SDimitry Andric 
VisitObjCMethodDecl(const ObjCMethodDecl * D)24730b57cec5SDimitry Andric void TextNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
24740b57cec5SDimitry Andric   if (D->isInstanceMethod())
24750b57cec5SDimitry Andric     OS << " -";
24760b57cec5SDimitry Andric   else
24770b57cec5SDimitry Andric     OS << " +";
24780b57cec5SDimitry Andric   dumpName(D);
24790b57cec5SDimitry Andric   dumpType(D->getReturnType());
24800b57cec5SDimitry Andric 
24810b57cec5SDimitry Andric   if (D->isVariadic())
24820b57cec5SDimitry Andric     OS << " variadic";
24830b57cec5SDimitry Andric }
24840b57cec5SDimitry Andric 
VisitObjCTypeParamDecl(const ObjCTypeParamDecl * D)24850b57cec5SDimitry Andric void TextNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
24860b57cec5SDimitry Andric   dumpName(D);
24870b57cec5SDimitry Andric   switch (D->getVariance()) {
24880b57cec5SDimitry Andric   case ObjCTypeParamVariance::Invariant:
24890b57cec5SDimitry Andric     break;
24900b57cec5SDimitry Andric 
24910b57cec5SDimitry Andric   case ObjCTypeParamVariance::Covariant:
24920b57cec5SDimitry Andric     OS << " covariant";
24930b57cec5SDimitry Andric     break;
24940b57cec5SDimitry Andric 
24950b57cec5SDimitry Andric   case ObjCTypeParamVariance::Contravariant:
24960b57cec5SDimitry Andric     OS << " contravariant";
24970b57cec5SDimitry Andric     break;
24980b57cec5SDimitry Andric   }
24990b57cec5SDimitry Andric 
25000b57cec5SDimitry Andric   if (D->hasExplicitBound())
25010b57cec5SDimitry Andric     OS << " bounded";
25020b57cec5SDimitry Andric   dumpType(D->getUnderlyingType());
25030b57cec5SDimitry Andric }
25040b57cec5SDimitry Andric 
VisitObjCCategoryDecl(const ObjCCategoryDecl * D)25050b57cec5SDimitry Andric void TextNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
25060b57cec5SDimitry Andric   dumpName(D);
25070b57cec5SDimitry Andric   dumpDeclRef(D->getClassInterface());
25080b57cec5SDimitry Andric   dumpDeclRef(D->getImplementation());
25090b57cec5SDimitry Andric   for (const auto *P : D->protocols())
25100b57cec5SDimitry Andric     dumpDeclRef(P);
25110b57cec5SDimitry Andric }
25120b57cec5SDimitry Andric 
VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl * D)25130b57cec5SDimitry Andric void TextNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
25140b57cec5SDimitry Andric   dumpName(D);
25150b57cec5SDimitry Andric   dumpDeclRef(D->getClassInterface());
25160b57cec5SDimitry Andric   dumpDeclRef(D->getCategoryDecl());
25170b57cec5SDimitry Andric }
25180b57cec5SDimitry Andric 
VisitObjCProtocolDecl(const ObjCProtocolDecl * D)25190b57cec5SDimitry Andric void TextNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
25200b57cec5SDimitry Andric   dumpName(D);
25210b57cec5SDimitry Andric 
25220b57cec5SDimitry Andric   for (const auto *Child : D->protocols())
25230b57cec5SDimitry Andric     dumpDeclRef(Child);
25240b57cec5SDimitry Andric }
25250b57cec5SDimitry Andric 
VisitObjCInterfaceDecl(const ObjCInterfaceDecl * D)25260b57cec5SDimitry Andric void TextNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
25270b57cec5SDimitry Andric   dumpName(D);
25280b57cec5SDimitry Andric   dumpDeclRef(D->getSuperClass(), "super");
25290b57cec5SDimitry Andric 
25300b57cec5SDimitry Andric   dumpDeclRef(D->getImplementation());
25310b57cec5SDimitry Andric   for (const auto *Child : D->protocols())
25320b57cec5SDimitry Andric     dumpDeclRef(Child);
25330b57cec5SDimitry Andric }
25340b57cec5SDimitry Andric 
VisitObjCImplementationDecl(const ObjCImplementationDecl * D)25350b57cec5SDimitry Andric void TextNodeDumper::VisitObjCImplementationDecl(
25360b57cec5SDimitry Andric     const ObjCImplementationDecl *D) {
25370b57cec5SDimitry Andric   dumpName(D);
25380b57cec5SDimitry Andric   dumpDeclRef(D->getSuperClass(), "super");
25390b57cec5SDimitry Andric   dumpDeclRef(D->getClassInterface());
25400b57cec5SDimitry Andric }
25410b57cec5SDimitry Andric 
VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl * D)25420b57cec5SDimitry Andric void TextNodeDumper::VisitObjCCompatibleAliasDecl(
25430b57cec5SDimitry Andric     const ObjCCompatibleAliasDecl *D) {
25440b57cec5SDimitry Andric   dumpName(D);
25450b57cec5SDimitry Andric   dumpDeclRef(D->getClassInterface());
25460b57cec5SDimitry Andric }
25470b57cec5SDimitry Andric 
VisitObjCPropertyDecl(const ObjCPropertyDecl * D)25480b57cec5SDimitry Andric void TextNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
25490b57cec5SDimitry Andric   dumpName(D);
25500b57cec5SDimitry Andric   dumpType(D->getType());
25510b57cec5SDimitry Andric 
25520b57cec5SDimitry Andric   if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
25530b57cec5SDimitry Andric     OS << " required";
25540b57cec5SDimitry Andric   else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
25550b57cec5SDimitry Andric     OS << " optional";
25560b57cec5SDimitry Andric 
25575ffd83dbSDimitry Andric   ObjCPropertyAttribute::Kind Attrs = D->getPropertyAttributes();
25585ffd83dbSDimitry Andric   if (Attrs != ObjCPropertyAttribute::kind_noattr) {
25595ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_readonly)
25600b57cec5SDimitry Andric       OS << " readonly";
25615ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_assign)
25620b57cec5SDimitry Andric       OS << " assign";
25635ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_readwrite)
25640b57cec5SDimitry Andric       OS << " readwrite";
25655ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_retain)
25660b57cec5SDimitry Andric       OS << " retain";
25675ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_copy)
25680b57cec5SDimitry Andric       OS << " copy";
25695ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_nonatomic)
25700b57cec5SDimitry Andric       OS << " nonatomic";
25715ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_atomic)
25720b57cec5SDimitry Andric       OS << " atomic";
25735ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_weak)
25740b57cec5SDimitry Andric       OS << " weak";
25755ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_strong)
25760b57cec5SDimitry Andric       OS << " strong";
25775ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_unsafe_unretained)
25780b57cec5SDimitry Andric       OS << " unsafe_unretained";
25795ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_class)
25800b57cec5SDimitry Andric       OS << " class";
25815ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_direct)
2582480093f4SDimitry Andric       OS << " direct";
25835ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_getter)
25840b57cec5SDimitry Andric       dumpDeclRef(D->getGetterMethodDecl(), "getter");
25855ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_setter)
25860b57cec5SDimitry Andric       dumpDeclRef(D->getSetterMethodDecl(), "setter");
25870b57cec5SDimitry Andric   }
25880b57cec5SDimitry Andric }
25890b57cec5SDimitry Andric 
VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl * D)25900b57cec5SDimitry Andric void TextNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
25910b57cec5SDimitry Andric   dumpName(D->getPropertyDecl());
25920b57cec5SDimitry Andric   if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
25930b57cec5SDimitry Andric     OS << " synthesize";
25940b57cec5SDimitry Andric   else
25950b57cec5SDimitry Andric     OS << " dynamic";
25960b57cec5SDimitry Andric   dumpDeclRef(D->getPropertyDecl());
25970b57cec5SDimitry Andric   dumpDeclRef(D->getPropertyIvarDecl());
25980b57cec5SDimitry Andric }
25990b57cec5SDimitry Andric 
VisitBlockDecl(const BlockDecl * D)26000b57cec5SDimitry Andric void TextNodeDumper::VisitBlockDecl(const BlockDecl *D) {
26010b57cec5SDimitry Andric   if (D->isVariadic())
26020b57cec5SDimitry Andric     OS << " variadic";
26030b57cec5SDimitry Andric 
26040b57cec5SDimitry Andric   if (D->capturesCXXThis())
26050b57cec5SDimitry Andric     OS << " captures_this";
26060b57cec5SDimitry Andric }
26070b57cec5SDimitry Andric 
VisitConceptDecl(const ConceptDecl * D)26080b57cec5SDimitry Andric void TextNodeDumper::VisitConceptDecl(const ConceptDecl *D) {
26090b57cec5SDimitry Andric   dumpName(D);
26100b57cec5SDimitry Andric }
261181ad6265SDimitry Andric 
VisitCompoundStmt(const CompoundStmt * S)261281ad6265SDimitry Andric void TextNodeDumper::VisitCompoundStmt(const CompoundStmt *S) {
261381ad6265SDimitry Andric   VisitStmt(S);
261481ad6265SDimitry Andric   if (S->hasStoredFPFeatures())
261581ad6265SDimitry Andric     printFPOptions(S->getStoredFPFeatures());
261681ad6265SDimitry Andric }
2617bdd1243dSDimitry Andric 
VisitHLSLBufferDecl(const HLSLBufferDecl * D)2618bdd1243dSDimitry Andric void TextNodeDumper::VisitHLSLBufferDecl(const HLSLBufferDecl *D) {
2619bdd1243dSDimitry Andric   if (D->isCBuffer())
2620bdd1243dSDimitry Andric     OS << " cbuffer";
2621bdd1243dSDimitry Andric   else
2622bdd1243dSDimitry Andric     OS << " tbuffer";
2623bdd1243dSDimitry Andric   dumpName(D);
2624bdd1243dSDimitry Andric }
2625