xref: /freebsd-src/contrib/llvm-project/clang/lib/AST/TextNodeDumper.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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"
21*0fca6ea1SDimitry Andric #include "clang/AST/TypeLocVisitor.h"
225ffd83dbSDimitry Andric #include "clang/Basic/Module.h"
235ffd83dbSDimitry Andric #include "clang/Basic/SourceManager.h"
245ffd83dbSDimitry Andric #include "clang/Basic/Specifiers.h"
255ffd83dbSDimitry Andric #include "clang/Basic/TypeTraits.h"
26fe6060f1SDimitry Andric #include "llvm/ADT/StringExtras.h"
275ffd83dbSDimitry Andric 
285ffd83dbSDimitry Andric #include <algorithm>
295ffd83dbSDimitry Andric #include <utility>
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric using namespace clang;
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {}
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric template <typename T>
360b57cec5SDimitry Andric static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) {
370b57cec5SDimitry Andric   const T *First = D->getFirstDecl();
380b57cec5SDimitry Andric   if (First != D)
390b57cec5SDimitry Andric     OS << " first " << First;
400b57cec5SDimitry Andric }
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric template <typename T>
430b57cec5SDimitry Andric static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) {
440b57cec5SDimitry Andric   const T *Prev = D->getPreviousDecl();
450b57cec5SDimitry Andric   if (Prev)
460b57cec5SDimitry Andric     OS << " prev " << Prev;
470b57cec5SDimitry Andric }
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric /// Dump the previous declaration in the redeclaration chain for a declaration,
500b57cec5SDimitry Andric /// if any.
510b57cec5SDimitry Andric static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) {
520b57cec5SDimitry Andric   switch (D->getKind()) {
530b57cec5SDimitry Andric #define DECL(DERIVED, BASE)                                                    \
540b57cec5SDimitry Andric   case Decl::DERIVED:                                                          \
550b57cec5SDimitry Andric     return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D));
560b57cec5SDimitry Andric #define ABSTRACT_DECL(DECL)
570b57cec5SDimitry Andric #include "clang/AST/DeclNodes.inc"
580b57cec5SDimitry Andric   }
590b57cec5SDimitry Andric   llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
600b57cec5SDimitry Andric }
610b57cec5SDimitry Andric 
625ffd83dbSDimitry Andric TextNodeDumper::TextNodeDumper(raw_ostream &OS, const ASTContext &Context,
635ffd83dbSDimitry Andric                                bool ShowColors)
645ffd83dbSDimitry Andric     : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors),
655ffd83dbSDimitry Andric       Context(&Context), SM(&Context.getSourceManager()),
665ffd83dbSDimitry Andric       PrintPolicy(Context.getPrintingPolicy()),
675ffd83dbSDimitry Andric       Traits(&Context.getCommentCommandTraits()) {}
685ffd83dbSDimitry Andric 
695ffd83dbSDimitry Andric TextNodeDumper::TextNodeDumper(raw_ostream &OS, bool ShowColors)
705ffd83dbSDimitry Andric     : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors) {}
710b57cec5SDimitry Andric 
720b57cec5SDimitry Andric void TextNodeDumper::Visit(const comments::Comment *C,
730b57cec5SDimitry Andric                            const comments::FullComment *FC) {
740b57cec5SDimitry Andric   if (!C) {
750b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, NullColor);
760b57cec5SDimitry Andric     OS << "<<<NULL>>>";
770b57cec5SDimitry Andric     return;
780b57cec5SDimitry Andric   }
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric   {
810b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, CommentColor);
820b57cec5SDimitry Andric     OS << C->getCommentKindName();
830b57cec5SDimitry Andric   }
840b57cec5SDimitry Andric   dumpPointer(C);
850b57cec5SDimitry Andric   dumpSourceRange(C->getSourceRange());
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric   ConstCommentVisitor<TextNodeDumper, void,
880b57cec5SDimitry Andric                       const comments::FullComment *>::visit(C, FC);
890b57cec5SDimitry Andric }
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric void TextNodeDumper::Visit(const Attr *A) {
920b57cec5SDimitry Andric   {
930b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, AttrColor);
940b57cec5SDimitry Andric 
950b57cec5SDimitry Andric     switch (A->getKind()) {
960b57cec5SDimitry Andric #define ATTR(X)                                                                \
970b57cec5SDimitry Andric   case attr::X:                                                                \
980b57cec5SDimitry Andric     OS << #X;                                                                  \
990b57cec5SDimitry Andric     break;
1000b57cec5SDimitry Andric #include "clang/Basic/AttrList.inc"
1010b57cec5SDimitry Andric     }
1020b57cec5SDimitry Andric     OS << "Attr";
1030b57cec5SDimitry Andric   }
1040b57cec5SDimitry Andric   dumpPointer(A);
1050b57cec5SDimitry Andric   dumpSourceRange(A->getRange());
1060b57cec5SDimitry Andric   if (A->isInherited())
1070b57cec5SDimitry Andric     OS << " Inherited";
1080b57cec5SDimitry Andric   if (A->isImplicit())
1090b57cec5SDimitry Andric     OS << " Implicit";
1100b57cec5SDimitry Andric 
1110b57cec5SDimitry Andric   ConstAttrVisitor<TextNodeDumper>::Visit(A);
1120b57cec5SDimitry Andric }
1130b57cec5SDimitry Andric 
1140b57cec5SDimitry Andric void TextNodeDumper::Visit(const TemplateArgument &TA, SourceRange R,
1150b57cec5SDimitry Andric                            const Decl *From, StringRef Label) {
1160b57cec5SDimitry Andric   OS << "TemplateArgument";
1170b57cec5SDimitry Andric   if (R.isValid())
1180b57cec5SDimitry Andric     dumpSourceRange(R);
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric   if (From)
1210b57cec5SDimitry Andric     dumpDeclRef(From, Label);
1220b57cec5SDimitry Andric 
1230b57cec5SDimitry Andric   ConstTemplateArgumentVisitor<TextNodeDumper>::Visit(TA);
1240b57cec5SDimitry Andric }
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric void TextNodeDumper::Visit(const Stmt *Node) {
1270b57cec5SDimitry Andric   if (!Node) {
1280b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, NullColor);
1290b57cec5SDimitry Andric     OS << "<<<NULL>>>";
1300b57cec5SDimitry Andric     return;
1310b57cec5SDimitry Andric   }
1320b57cec5SDimitry Andric   {
1330b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, StmtColor);
1340b57cec5SDimitry Andric     OS << Node->getStmtClassName();
1350b57cec5SDimitry Andric   }
1360b57cec5SDimitry Andric   dumpPointer(Node);
1370b57cec5SDimitry Andric   dumpSourceRange(Node->getSourceRange());
1380b57cec5SDimitry Andric 
1390b57cec5SDimitry Andric   if (const auto *E = dyn_cast<Expr>(Node)) {
1400b57cec5SDimitry Andric     dumpType(E->getType());
1410b57cec5SDimitry Andric 
1425ffd83dbSDimitry Andric     if (E->containsErrors()) {
1435ffd83dbSDimitry Andric       ColorScope Color(OS, ShowColors, ErrorsColor);
1445ffd83dbSDimitry Andric       OS << " contains-errors";
1455ffd83dbSDimitry Andric     }
1465ffd83dbSDimitry Andric 
1470b57cec5SDimitry Andric     {
1480b57cec5SDimitry Andric       ColorScope Color(OS, ShowColors, ValueKindColor);
1490b57cec5SDimitry Andric       switch (E->getValueKind()) {
150fe6060f1SDimitry Andric       case VK_PRValue:
1510b57cec5SDimitry Andric         break;
1520b57cec5SDimitry Andric       case VK_LValue:
1530b57cec5SDimitry Andric         OS << " lvalue";
1540b57cec5SDimitry Andric         break;
1550b57cec5SDimitry Andric       case VK_XValue:
1560b57cec5SDimitry Andric         OS << " xvalue";
1570b57cec5SDimitry Andric         break;
1580b57cec5SDimitry Andric       }
1590b57cec5SDimitry Andric     }
1600b57cec5SDimitry Andric 
1610b57cec5SDimitry Andric     {
1620b57cec5SDimitry Andric       ColorScope Color(OS, ShowColors, ObjectKindColor);
1630b57cec5SDimitry Andric       switch (E->getObjectKind()) {
1640b57cec5SDimitry Andric       case OK_Ordinary:
1650b57cec5SDimitry Andric         break;
1660b57cec5SDimitry Andric       case OK_BitField:
1670b57cec5SDimitry Andric         OS << " bitfield";
1680b57cec5SDimitry Andric         break;
1690b57cec5SDimitry Andric       case OK_ObjCProperty:
1700b57cec5SDimitry Andric         OS << " objcproperty";
1710b57cec5SDimitry Andric         break;
1720b57cec5SDimitry Andric       case OK_ObjCSubscript:
1730b57cec5SDimitry Andric         OS << " objcsubscript";
1740b57cec5SDimitry Andric         break;
1750b57cec5SDimitry Andric       case OK_VectorComponent:
1760b57cec5SDimitry Andric         OS << " vectorcomponent";
1770b57cec5SDimitry Andric         break;
1785ffd83dbSDimitry Andric       case OK_MatrixComponent:
1795ffd83dbSDimitry Andric         OS << " matrixcomponent";
1805ffd83dbSDimitry Andric         break;
1810b57cec5SDimitry Andric       }
1820b57cec5SDimitry Andric     }
1830b57cec5SDimitry Andric   }
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric   ConstStmtVisitor<TextNodeDumper>::Visit(Node);
1860b57cec5SDimitry Andric }
1870b57cec5SDimitry Andric 
1880b57cec5SDimitry Andric void TextNodeDumper::Visit(const Type *T) {
1890b57cec5SDimitry Andric   if (!T) {
1900b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, NullColor);
1910b57cec5SDimitry Andric     OS << "<<<NULL>>>";
1920b57cec5SDimitry Andric     return;
1930b57cec5SDimitry Andric   }
1940b57cec5SDimitry Andric   if (isa<LocInfoType>(T)) {
1950b57cec5SDimitry Andric     {
1960b57cec5SDimitry Andric       ColorScope Color(OS, ShowColors, TypeColor);
1970b57cec5SDimitry Andric       OS << "LocInfo Type";
1980b57cec5SDimitry Andric     }
1990b57cec5SDimitry Andric     dumpPointer(T);
2000b57cec5SDimitry Andric     return;
2010b57cec5SDimitry Andric   }
2020b57cec5SDimitry Andric 
2030b57cec5SDimitry Andric   {
2040b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, TypeColor);
2050b57cec5SDimitry Andric     OS << T->getTypeClassName() << "Type";
2060b57cec5SDimitry Andric   }
2070b57cec5SDimitry Andric   dumpPointer(T);
2080b57cec5SDimitry Andric   OS << " ";
2090b57cec5SDimitry Andric   dumpBareType(QualType(T, 0), false);
2100b57cec5SDimitry Andric 
2110b57cec5SDimitry Andric   QualType SingleStepDesugar =
2120b57cec5SDimitry Andric       T->getLocallyUnqualifiedSingleStepDesugaredType();
2130b57cec5SDimitry Andric   if (SingleStepDesugar != QualType(T, 0))
2140b57cec5SDimitry Andric     OS << " sugar";
2150b57cec5SDimitry Andric 
2165ffd83dbSDimitry Andric   if (T->containsErrors()) {
2175ffd83dbSDimitry Andric     ColorScope Color(OS, ShowColors, ErrorsColor);
2185ffd83dbSDimitry Andric     OS << " contains-errors";
2195ffd83dbSDimitry Andric   }
2205ffd83dbSDimitry Andric 
2210b57cec5SDimitry Andric   if (T->isDependentType())
2220b57cec5SDimitry Andric     OS << " dependent";
2230b57cec5SDimitry Andric   else if (T->isInstantiationDependentType())
2240b57cec5SDimitry Andric     OS << " instantiation_dependent";
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric   if (T->isVariablyModifiedType())
2270b57cec5SDimitry Andric     OS << " variably_modified";
2280b57cec5SDimitry Andric   if (T->containsUnexpandedParameterPack())
2290b57cec5SDimitry Andric     OS << " contains_unexpanded_pack";
2300b57cec5SDimitry Andric   if (T->isFromAST())
2310b57cec5SDimitry Andric     OS << " imported";
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric   TypeVisitor<TextNodeDumper>::Visit(T);
2340b57cec5SDimitry Andric }
2350b57cec5SDimitry Andric 
2360b57cec5SDimitry Andric void TextNodeDumper::Visit(QualType T) {
2370b57cec5SDimitry Andric   OS << "QualType";
2380b57cec5SDimitry Andric   dumpPointer(T.getAsOpaquePtr());
2390b57cec5SDimitry Andric   OS << " ";
2400b57cec5SDimitry Andric   dumpBareType(T, false);
2410b57cec5SDimitry Andric   OS << " " << T.split().Quals.getAsString();
2420b57cec5SDimitry Andric }
2430b57cec5SDimitry Andric 
244*0fca6ea1SDimitry Andric void TextNodeDumper::Visit(TypeLoc TL) {
245*0fca6ea1SDimitry Andric   if (!TL) {
246*0fca6ea1SDimitry Andric     ColorScope Color(OS, ShowColors, NullColor);
247*0fca6ea1SDimitry Andric     OS << "<<<NULL>>>";
248*0fca6ea1SDimitry Andric     return;
249*0fca6ea1SDimitry Andric   }
250*0fca6ea1SDimitry Andric 
251*0fca6ea1SDimitry Andric   {
252*0fca6ea1SDimitry Andric     ColorScope Color(OS, ShowColors, TypeColor);
253*0fca6ea1SDimitry Andric     OS << (TL.getTypeLocClass() == TypeLoc::Qualified
254*0fca6ea1SDimitry Andric                ? "Qualified"
255*0fca6ea1SDimitry Andric                : TL.getType()->getTypeClassName())
256*0fca6ea1SDimitry Andric        << "TypeLoc";
257*0fca6ea1SDimitry Andric   }
258*0fca6ea1SDimitry Andric   dumpSourceRange(TL.getSourceRange());
259*0fca6ea1SDimitry Andric   OS << ' ';
260*0fca6ea1SDimitry Andric   dumpBareType(TL.getType(), /*Desugar=*/false);
261*0fca6ea1SDimitry Andric 
262*0fca6ea1SDimitry Andric   TypeLocVisitor<TextNodeDumper>::Visit(TL);
263*0fca6ea1SDimitry Andric }
264*0fca6ea1SDimitry Andric 
2650b57cec5SDimitry Andric void TextNodeDumper::Visit(const Decl *D) {
2660b57cec5SDimitry Andric   if (!D) {
2670b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, NullColor);
2680b57cec5SDimitry Andric     OS << "<<<NULL>>>";
2690b57cec5SDimitry Andric     return;
2700b57cec5SDimitry Andric   }
2710b57cec5SDimitry Andric 
2720b57cec5SDimitry Andric   {
2730b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, DeclKindNameColor);
2740b57cec5SDimitry Andric     OS << D->getDeclKindName() << "Decl";
2750b57cec5SDimitry Andric   }
2760b57cec5SDimitry Andric   dumpPointer(D);
2770b57cec5SDimitry Andric   if (D->getLexicalDeclContext() != D->getDeclContext())
2780b57cec5SDimitry Andric     OS << " parent " << cast<Decl>(D->getDeclContext());
2790b57cec5SDimitry Andric   dumpPreviousDecl(OS, D);
2800b57cec5SDimitry Andric   dumpSourceRange(D->getSourceRange());
2810b57cec5SDimitry Andric   OS << ' ';
2820b57cec5SDimitry Andric   dumpLocation(D->getLocation());
2830b57cec5SDimitry Andric   if (D->isFromASTFile())
2840b57cec5SDimitry Andric     OS << " imported";
2850b57cec5SDimitry Andric   if (Module *M = D->getOwningModule())
2860b57cec5SDimitry Andric     OS << " in " << M->getFullModuleName();
2870b57cec5SDimitry Andric   if (auto *ND = dyn_cast<NamedDecl>(D))
2880b57cec5SDimitry Andric     for (Module *M : D->getASTContext().getModulesWithMergedDefinition(
2890b57cec5SDimitry Andric              const_cast<NamedDecl *>(ND)))
2900b57cec5SDimitry Andric       AddChild([=] { OS << "also in " << M->getFullModuleName(); });
2910b57cec5SDimitry Andric   if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
2925ffd83dbSDimitry Andric     if (!ND->isUnconditionallyVisible())
2930b57cec5SDimitry Andric       OS << " hidden";
2940b57cec5SDimitry Andric   if (D->isImplicit())
2950b57cec5SDimitry Andric     OS << " implicit";
2960b57cec5SDimitry Andric 
2970b57cec5SDimitry Andric   if (D->isUsed())
2980b57cec5SDimitry Andric     OS << " used";
2990b57cec5SDimitry Andric   else if (D->isThisDeclarationReferenced())
3000b57cec5SDimitry Andric     OS << " referenced";
3010b57cec5SDimitry Andric 
3020b57cec5SDimitry Andric   if (D->isInvalidDecl())
3030b57cec5SDimitry Andric     OS << " invalid";
3040b57cec5SDimitry Andric   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
3050b57cec5SDimitry Andric     if (FD->isConstexprSpecified())
3060b57cec5SDimitry Andric       OS << " constexpr";
3070b57cec5SDimitry Andric     if (FD->isConsteval())
3080b57cec5SDimitry Andric       OS << " consteval";
30906c3fb27SDimitry Andric     else if (FD->isImmediateFunction())
31006c3fb27SDimitry Andric       OS << " immediate";
31181ad6265SDimitry Andric     if (FD->isMultiVersion())
31281ad6265SDimitry Andric       OS << " multiversion";
3130b57cec5SDimitry Andric   }
3140b57cec5SDimitry Andric 
3150b57cec5SDimitry Andric   if (!isa<FunctionDecl>(*D)) {
3160b57cec5SDimitry Andric     const auto *MD = dyn_cast<ObjCMethodDecl>(D);
3170b57cec5SDimitry Andric     if (!MD || !MD->isThisDeclarationADefinition()) {
3180b57cec5SDimitry Andric       const auto *DC = dyn_cast<DeclContext>(D);
3190b57cec5SDimitry Andric       if (DC && DC->hasExternalLexicalStorage()) {
3200b57cec5SDimitry Andric         ColorScope Color(OS, ShowColors, UndeserializedColor);
3210b57cec5SDimitry Andric         OS << " <undeserialized declarations>";
3220b57cec5SDimitry Andric       }
3230b57cec5SDimitry Andric     }
3240b57cec5SDimitry Andric   }
3250b57cec5SDimitry Andric 
3265f757f3fSDimitry Andric   switch (D->getFriendObjectKind()) {
3275f757f3fSDimitry Andric   case Decl::FOK_None:
3285f757f3fSDimitry Andric     break;
3295f757f3fSDimitry Andric   case Decl::FOK_Declared:
3305f757f3fSDimitry Andric     OS << " friend";
3315f757f3fSDimitry Andric     break;
3325f757f3fSDimitry Andric   case Decl::FOK_Undeclared:
3335f757f3fSDimitry Andric     OS << " friend_undeclared";
3345f757f3fSDimitry Andric     break;
3355f757f3fSDimitry Andric   }
3365f757f3fSDimitry Andric 
3370b57cec5SDimitry Andric   ConstDeclVisitor<TextNodeDumper>::Visit(D);
3380b57cec5SDimitry Andric }
3390b57cec5SDimitry Andric 
3400b57cec5SDimitry Andric void TextNodeDumper::Visit(const CXXCtorInitializer *Init) {
3410b57cec5SDimitry Andric   OS << "CXXCtorInitializer";
3420b57cec5SDimitry Andric   if (Init->isAnyMemberInitializer()) {
3430b57cec5SDimitry Andric     OS << ' ';
3440b57cec5SDimitry Andric     dumpBareDeclRef(Init->getAnyMember());
3450b57cec5SDimitry Andric   } else if (Init->isBaseInitializer()) {
3460b57cec5SDimitry Andric     dumpType(QualType(Init->getBaseClass(), 0));
3470b57cec5SDimitry Andric   } else if (Init->isDelegatingInitializer()) {
3480b57cec5SDimitry Andric     dumpType(Init->getTypeSourceInfo()->getType());
3490b57cec5SDimitry Andric   } else {
3500b57cec5SDimitry Andric     llvm_unreachable("Unknown initializer type");
3510b57cec5SDimitry Andric   }
3520b57cec5SDimitry Andric }
3530b57cec5SDimitry Andric 
3540b57cec5SDimitry Andric void TextNodeDumper::Visit(const BlockDecl::Capture &C) {
3550b57cec5SDimitry Andric   OS << "capture";
3560b57cec5SDimitry Andric   if (C.isByRef())
3570b57cec5SDimitry Andric     OS << " byref";
3580b57cec5SDimitry Andric   if (C.isNested())
3590b57cec5SDimitry Andric     OS << " nested";
3600b57cec5SDimitry Andric   if (C.getVariable()) {
3610b57cec5SDimitry Andric     OS << ' ';
3620b57cec5SDimitry Andric     dumpBareDeclRef(C.getVariable());
3630b57cec5SDimitry Andric   }
3640b57cec5SDimitry Andric }
3650b57cec5SDimitry Andric 
3660b57cec5SDimitry Andric void TextNodeDumper::Visit(const OMPClause *C) {
3670b57cec5SDimitry Andric   if (!C) {
3680b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, NullColor);
3690b57cec5SDimitry Andric     OS << "<<<NULL>>> OMPClause";
3700b57cec5SDimitry Andric     return;
3710b57cec5SDimitry Andric   }
3720b57cec5SDimitry Andric   {
3730b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, AttrColor);
3745ffd83dbSDimitry Andric     StringRef ClauseName(llvm::omp::getOpenMPClauseName(C->getClauseKind()));
3750b57cec5SDimitry Andric     OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
3760b57cec5SDimitry Andric        << ClauseName.drop_front() << "Clause";
3770b57cec5SDimitry Andric   }
3780b57cec5SDimitry Andric   dumpPointer(C);
3790b57cec5SDimitry Andric   dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
3800b57cec5SDimitry Andric   if (C->isImplicit())
3810b57cec5SDimitry Andric     OS << " <implicit>";
3820b57cec5SDimitry Andric }
3830b57cec5SDimitry Andric 
384*0fca6ea1SDimitry Andric void TextNodeDumper::Visit(const OpenACCClause *C) {
385*0fca6ea1SDimitry Andric   if (!C) {
386*0fca6ea1SDimitry Andric     ColorScope Color(OS, ShowColors, NullColor);
387*0fca6ea1SDimitry Andric     OS << "<<<NULL>>> OpenACCClause";
388*0fca6ea1SDimitry Andric     return;
389*0fca6ea1SDimitry Andric   }
390*0fca6ea1SDimitry Andric   {
391*0fca6ea1SDimitry Andric     ColorScope Color(OS, ShowColors, AttrColor);
392*0fca6ea1SDimitry Andric     OS << C->getClauseKind();
393*0fca6ea1SDimitry Andric 
394*0fca6ea1SDimitry Andric     // Handle clauses with parens for types that have no children, likely
395*0fca6ea1SDimitry Andric     // because there is no sub expression.
396*0fca6ea1SDimitry Andric     switch (C->getClauseKind()) {
397*0fca6ea1SDimitry Andric     case OpenACCClauseKind::Default:
398*0fca6ea1SDimitry Andric       OS << '(' << cast<OpenACCDefaultClause>(C)->getDefaultClauseKind() << ')';
399*0fca6ea1SDimitry Andric       break;
400*0fca6ea1SDimitry Andric     case OpenACCClauseKind::Async:
401*0fca6ea1SDimitry Andric     case OpenACCClauseKind::Auto:
402*0fca6ea1SDimitry Andric     case OpenACCClauseKind::Attach:
403*0fca6ea1SDimitry Andric     case OpenACCClauseKind::Copy:
404*0fca6ea1SDimitry Andric     case OpenACCClauseKind::PCopy:
405*0fca6ea1SDimitry Andric     case OpenACCClauseKind::PresentOrCopy:
406*0fca6ea1SDimitry Andric     case OpenACCClauseKind::If:
407*0fca6ea1SDimitry Andric     case OpenACCClauseKind::Independent:
408*0fca6ea1SDimitry Andric     case OpenACCClauseKind::DevicePtr:
409*0fca6ea1SDimitry Andric     case OpenACCClauseKind::FirstPrivate:
410*0fca6ea1SDimitry Andric     case OpenACCClauseKind::NoCreate:
411*0fca6ea1SDimitry Andric     case OpenACCClauseKind::NumGangs:
412*0fca6ea1SDimitry Andric     case OpenACCClauseKind::NumWorkers:
413*0fca6ea1SDimitry Andric     case OpenACCClauseKind::Present:
414*0fca6ea1SDimitry Andric     case OpenACCClauseKind::Private:
415*0fca6ea1SDimitry Andric     case OpenACCClauseKind::Self:
416*0fca6ea1SDimitry Andric     case OpenACCClauseKind::Seq:
417*0fca6ea1SDimitry Andric     case OpenACCClauseKind::VectorLength:
418*0fca6ea1SDimitry Andric       // The condition expression will be printed as a part of the 'children',
419*0fca6ea1SDimitry Andric       // but print 'clause' here so it is clear what is happening from the dump.
420*0fca6ea1SDimitry Andric       OS << " clause";
421*0fca6ea1SDimitry Andric       break;
422*0fca6ea1SDimitry Andric     case OpenACCClauseKind::CopyIn:
423*0fca6ea1SDimitry Andric     case OpenACCClauseKind::PCopyIn:
424*0fca6ea1SDimitry Andric     case OpenACCClauseKind::PresentOrCopyIn:
425*0fca6ea1SDimitry Andric       OS << " clause";
426*0fca6ea1SDimitry Andric       if (cast<OpenACCCopyInClause>(C)->isReadOnly())
427*0fca6ea1SDimitry Andric         OS << " : readonly";
428*0fca6ea1SDimitry Andric       break;
429*0fca6ea1SDimitry Andric     case OpenACCClauseKind::CopyOut:
430*0fca6ea1SDimitry Andric     case OpenACCClauseKind::PCopyOut:
431*0fca6ea1SDimitry Andric     case OpenACCClauseKind::PresentOrCopyOut:
432*0fca6ea1SDimitry Andric       OS << " clause";
433*0fca6ea1SDimitry Andric       if (cast<OpenACCCopyOutClause>(C)->isZero())
434*0fca6ea1SDimitry Andric         OS << " : zero";
435*0fca6ea1SDimitry Andric       break;
436*0fca6ea1SDimitry Andric     case OpenACCClauseKind::Create:
437*0fca6ea1SDimitry Andric     case OpenACCClauseKind::PCreate:
438*0fca6ea1SDimitry Andric     case OpenACCClauseKind::PresentOrCreate:
439*0fca6ea1SDimitry Andric       OS << " clause";
440*0fca6ea1SDimitry Andric       if (cast<OpenACCCreateClause>(C)->isZero())
441*0fca6ea1SDimitry Andric         OS << " : zero";
442*0fca6ea1SDimitry Andric       break;
443*0fca6ea1SDimitry Andric     case OpenACCClauseKind::Wait:
444*0fca6ea1SDimitry Andric       OS << " clause";
445*0fca6ea1SDimitry Andric       if (cast<OpenACCWaitClause>(C)->hasDevNumExpr())
446*0fca6ea1SDimitry Andric         OS << " has devnum";
447*0fca6ea1SDimitry Andric       if (cast<OpenACCWaitClause>(C)->hasQueuesTag())
448*0fca6ea1SDimitry Andric         OS << " has queues tag";
449*0fca6ea1SDimitry Andric       break;
450*0fca6ea1SDimitry Andric     case OpenACCClauseKind::DeviceType:
451*0fca6ea1SDimitry Andric     case OpenACCClauseKind::DType:
452*0fca6ea1SDimitry Andric       OS << "(";
453*0fca6ea1SDimitry Andric       llvm::interleaveComma(
454*0fca6ea1SDimitry Andric           cast<OpenACCDeviceTypeClause>(C)->getArchitectures(), OS,
455*0fca6ea1SDimitry Andric           [&](const DeviceTypeArgument &Arch) {
456*0fca6ea1SDimitry Andric             if (Arch.first == nullptr)
457*0fca6ea1SDimitry Andric               OS << "*";
458*0fca6ea1SDimitry Andric             else
459*0fca6ea1SDimitry Andric               OS << Arch.first->getName();
460*0fca6ea1SDimitry Andric           });
461*0fca6ea1SDimitry Andric       OS << ")";
462*0fca6ea1SDimitry Andric       break;
463*0fca6ea1SDimitry Andric     case OpenACCClauseKind::Reduction:
464*0fca6ea1SDimitry Andric       OS << " clause Operator: "
465*0fca6ea1SDimitry Andric          << cast<OpenACCReductionClause>(C)->getReductionOp();
466*0fca6ea1SDimitry Andric       break;
467*0fca6ea1SDimitry Andric     default:
468*0fca6ea1SDimitry Andric       // Nothing to do here.
469*0fca6ea1SDimitry Andric       break;
470*0fca6ea1SDimitry Andric     }
471*0fca6ea1SDimitry Andric   }
472*0fca6ea1SDimitry Andric   dumpPointer(C);
473*0fca6ea1SDimitry Andric   dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
474*0fca6ea1SDimitry Andric }
475*0fca6ea1SDimitry Andric 
4760b57cec5SDimitry Andric void TextNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) {
4770b57cec5SDimitry Andric   const TypeSourceInfo *TSI = A.getTypeSourceInfo();
4780b57cec5SDimitry Andric   if (TSI) {
4790b57cec5SDimitry Andric     OS << "case ";
4800b57cec5SDimitry Andric     dumpType(TSI->getType());
4810b57cec5SDimitry Andric   } else {
4820b57cec5SDimitry Andric     OS << "default";
4830b57cec5SDimitry Andric   }
4840b57cec5SDimitry Andric 
4850b57cec5SDimitry Andric   if (A.isSelected())
4860b57cec5SDimitry Andric     OS << " selected";
4870b57cec5SDimitry Andric }
4880b57cec5SDimitry Andric 
4895f757f3fSDimitry Andric void TextNodeDumper::Visit(const ConceptReference *R) {
4905f757f3fSDimitry Andric   if (!R) {
4915f757f3fSDimitry Andric     ColorScope Color(OS, ShowColors, NullColor);
4925f757f3fSDimitry Andric     OS << "<<<NULL>>> ConceptReference";
4935f757f3fSDimitry Andric     return;
4945f757f3fSDimitry Andric   }
4955f757f3fSDimitry Andric 
4965f757f3fSDimitry Andric   OS << "ConceptReference";
4975f757f3fSDimitry Andric   dumpPointer(R);
4985f757f3fSDimitry Andric   dumpSourceRange(R->getSourceRange());
4995f757f3fSDimitry Andric   OS << ' ';
5005f757f3fSDimitry Andric   dumpBareDeclRef(R->getNamedConcept());
5015f757f3fSDimitry Andric }
5025f757f3fSDimitry Andric 
503fe6060f1SDimitry Andric void TextNodeDumper::Visit(const concepts::Requirement *R) {
504fe6060f1SDimitry Andric   if (!R) {
505fe6060f1SDimitry Andric     ColorScope Color(OS, ShowColors, NullColor);
506fe6060f1SDimitry Andric     OS << "<<<NULL>>> Requirement";
507fe6060f1SDimitry Andric     return;
508fe6060f1SDimitry Andric   }
509fe6060f1SDimitry Andric 
510fe6060f1SDimitry Andric   {
511fe6060f1SDimitry Andric     ColorScope Color(OS, ShowColors, StmtColor);
512fe6060f1SDimitry Andric     switch (R->getKind()) {
513fe6060f1SDimitry Andric     case concepts::Requirement::RK_Type:
514fe6060f1SDimitry Andric       OS << "TypeRequirement";
515fe6060f1SDimitry Andric       break;
516fe6060f1SDimitry Andric     case concepts::Requirement::RK_Simple:
517fe6060f1SDimitry Andric       OS << "SimpleRequirement";
518fe6060f1SDimitry Andric       break;
519fe6060f1SDimitry Andric     case concepts::Requirement::RK_Compound:
520fe6060f1SDimitry Andric       OS << "CompoundRequirement";
521fe6060f1SDimitry Andric       break;
522fe6060f1SDimitry Andric     case concepts::Requirement::RK_Nested:
523fe6060f1SDimitry Andric       OS << "NestedRequirement";
524fe6060f1SDimitry Andric       break;
525fe6060f1SDimitry Andric     }
526fe6060f1SDimitry Andric   }
527fe6060f1SDimitry Andric 
528fe6060f1SDimitry Andric   dumpPointer(R);
529fe6060f1SDimitry Andric 
530fe6060f1SDimitry Andric   if (auto *ER = dyn_cast<concepts::ExprRequirement>(R)) {
531fe6060f1SDimitry Andric     if (ER->hasNoexceptRequirement())
532fe6060f1SDimitry Andric       OS << " noexcept";
533fe6060f1SDimitry Andric   }
534fe6060f1SDimitry Andric 
535fe6060f1SDimitry Andric   if (R->isDependent())
536fe6060f1SDimitry Andric     OS << " dependent";
537fe6060f1SDimitry Andric   else
538fe6060f1SDimitry Andric     OS << (R->isSatisfied() ? " satisfied" : " unsatisfied");
539fe6060f1SDimitry Andric   if (R->containsUnexpandedParameterPack())
540fe6060f1SDimitry Andric     OS << " contains_unexpanded_pack";
541fe6060f1SDimitry Andric }
542fe6060f1SDimitry Andric 
5435ffd83dbSDimitry Andric static double GetApproxValue(const llvm::APFloat &F) {
5445ffd83dbSDimitry Andric   llvm::APFloat V = F;
5455ffd83dbSDimitry Andric   bool ignored;
5465ffd83dbSDimitry Andric   V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven,
5475ffd83dbSDimitry Andric             &ignored);
5485ffd83dbSDimitry Andric   return V.convertToDouble();
5495ffd83dbSDimitry Andric }
5505ffd83dbSDimitry Andric 
5515ffd83dbSDimitry Andric /// True if the \p APValue \p Value can be folded onto the current line.
5525ffd83dbSDimitry Andric static bool isSimpleAPValue(const APValue &Value) {
5535ffd83dbSDimitry Andric   switch (Value.getKind()) {
5545ffd83dbSDimitry Andric   case APValue::None:
5555ffd83dbSDimitry Andric   case APValue::Indeterminate:
5565ffd83dbSDimitry Andric   case APValue::Int:
5575ffd83dbSDimitry Andric   case APValue::Float:
5585ffd83dbSDimitry Andric   case APValue::FixedPoint:
5595ffd83dbSDimitry Andric   case APValue::ComplexInt:
5605ffd83dbSDimitry Andric   case APValue::ComplexFloat:
5615ffd83dbSDimitry Andric   case APValue::LValue:
5625ffd83dbSDimitry Andric   case APValue::MemberPointer:
5635ffd83dbSDimitry Andric   case APValue::AddrLabelDiff:
5645ffd83dbSDimitry Andric     return true;
5655ffd83dbSDimitry Andric   case APValue::Vector:
5665ffd83dbSDimitry Andric   case APValue::Array:
5675ffd83dbSDimitry Andric   case APValue::Struct:
5685ffd83dbSDimitry Andric     return false;
5695ffd83dbSDimitry Andric   case APValue::Union:
5705ffd83dbSDimitry Andric     return isSimpleAPValue(Value.getUnionValue());
5715ffd83dbSDimitry Andric   }
5725ffd83dbSDimitry Andric   llvm_unreachable("unexpected APValue kind!");
5735ffd83dbSDimitry Andric }
5745ffd83dbSDimitry Andric 
5755ffd83dbSDimitry Andric /// Dump the children of the \p APValue \p Value.
5765ffd83dbSDimitry Andric ///
5775ffd83dbSDimitry Andric /// \param[in] Value          The \p APValue to visit
5785ffd83dbSDimitry Andric /// \param[in] Ty             The \p QualType passed to \p Visit
5795ffd83dbSDimitry Andric ///
5805ffd83dbSDimitry Andric /// \param[in] IdxToChildFun  A function mapping an \p APValue and an index
5815ffd83dbSDimitry Andric ///                           to one of the child of the \p APValue
5825ffd83dbSDimitry Andric ///
5835ffd83dbSDimitry Andric /// \param[in] NumChildren    \p IdxToChildFun will be called on \p Value with
5845ffd83dbSDimitry Andric ///                           the indices in the range \p [0,NumChildren(
5855ffd83dbSDimitry Andric ///
5865ffd83dbSDimitry Andric /// \param[in] LabelSingular  The label to use on a line with a single child
5875ffd83dbSDimitry Andric /// \param[in] LabelPlurial   The label to use on a line with multiple children
5885ffd83dbSDimitry Andric void TextNodeDumper::dumpAPValueChildren(
5895ffd83dbSDimitry Andric     const APValue &Value, QualType Ty,
5905ffd83dbSDimitry Andric     const APValue &(*IdxToChildFun)(const APValue &, unsigned),
5915ffd83dbSDimitry Andric     unsigned NumChildren, StringRef LabelSingular, StringRef LabelPlurial) {
5925ffd83dbSDimitry Andric   // To save some vertical space we print up to MaxChildrenPerLine APValues
5935ffd83dbSDimitry Andric   // considered to be simple (by isSimpleAPValue) on a single line.
5945ffd83dbSDimitry Andric   constexpr unsigned MaxChildrenPerLine = 4;
5955ffd83dbSDimitry Andric   unsigned I = 0;
5965ffd83dbSDimitry Andric   while (I < NumChildren) {
5975ffd83dbSDimitry Andric     unsigned J = I;
5985ffd83dbSDimitry Andric     while (J < NumChildren) {
5995ffd83dbSDimitry Andric       if (isSimpleAPValue(IdxToChildFun(Value, J)) &&
6005ffd83dbSDimitry Andric           (J - I < MaxChildrenPerLine)) {
6015ffd83dbSDimitry Andric         ++J;
6025ffd83dbSDimitry Andric         continue;
6035ffd83dbSDimitry Andric       }
6045ffd83dbSDimitry Andric       break;
6055ffd83dbSDimitry Andric     }
6065ffd83dbSDimitry Andric 
6075ffd83dbSDimitry Andric     J = std::max(I + 1, J);
6085ffd83dbSDimitry Andric 
6095ffd83dbSDimitry Andric     // Print [I,J) on a single line.
6105ffd83dbSDimitry Andric     AddChild(J - I > 1 ? LabelPlurial : LabelSingular, [=]() {
6115ffd83dbSDimitry Andric       for (unsigned X = I; X < J; ++X) {
6125ffd83dbSDimitry Andric         Visit(IdxToChildFun(Value, X), Ty);
6135ffd83dbSDimitry Andric         if (X + 1 != J)
6145ffd83dbSDimitry Andric           OS << ", ";
6155ffd83dbSDimitry Andric       }
6165ffd83dbSDimitry Andric     });
6175ffd83dbSDimitry Andric     I = J;
6185ffd83dbSDimitry Andric   }
6195ffd83dbSDimitry Andric }
6205ffd83dbSDimitry Andric 
6215ffd83dbSDimitry Andric void TextNodeDumper::Visit(const APValue &Value, QualType Ty) {
6225ffd83dbSDimitry Andric   ColorScope Color(OS, ShowColors, ValueKindColor);
6235ffd83dbSDimitry Andric   switch (Value.getKind()) {
6245ffd83dbSDimitry Andric   case APValue::None:
6255ffd83dbSDimitry Andric     OS << "None";
6265ffd83dbSDimitry Andric     return;
6275ffd83dbSDimitry Andric   case APValue::Indeterminate:
6285ffd83dbSDimitry Andric     OS << "Indeterminate";
6295ffd83dbSDimitry Andric     return;
6305ffd83dbSDimitry Andric   case APValue::Int:
6315ffd83dbSDimitry Andric     OS << "Int ";
6325ffd83dbSDimitry Andric     {
6335ffd83dbSDimitry Andric       ColorScope Color(OS, ShowColors, ValueColor);
6345ffd83dbSDimitry Andric       OS << Value.getInt();
6355ffd83dbSDimitry Andric     }
6365ffd83dbSDimitry Andric     return;
6375ffd83dbSDimitry Andric   case APValue::Float:
6385ffd83dbSDimitry Andric     OS << "Float ";
6395ffd83dbSDimitry Andric     {
6405ffd83dbSDimitry Andric       ColorScope Color(OS, ShowColors, ValueColor);
6415ffd83dbSDimitry Andric       OS << GetApproxValue(Value.getFloat());
6425ffd83dbSDimitry Andric     }
6435ffd83dbSDimitry Andric     return;
6445ffd83dbSDimitry Andric   case APValue::FixedPoint:
6455ffd83dbSDimitry Andric     OS << "FixedPoint ";
6465ffd83dbSDimitry Andric     {
6475ffd83dbSDimitry Andric       ColorScope Color(OS, ShowColors, ValueColor);
6485ffd83dbSDimitry Andric       OS << Value.getFixedPoint();
6495ffd83dbSDimitry Andric     }
6505ffd83dbSDimitry Andric     return;
6515ffd83dbSDimitry Andric   case APValue::Vector: {
6525ffd83dbSDimitry Andric     unsigned VectorLength = Value.getVectorLength();
6535ffd83dbSDimitry Andric     OS << "Vector length=" << VectorLength;
6545ffd83dbSDimitry Andric 
6555ffd83dbSDimitry Andric     dumpAPValueChildren(
6565ffd83dbSDimitry Andric         Value, Ty,
6575ffd83dbSDimitry Andric         [](const APValue &Value, unsigned Index) -> const APValue & {
6585ffd83dbSDimitry Andric           return Value.getVectorElt(Index);
6595ffd83dbSDimitry Andric         },
6605ffd83dbSDimitry Andric         VectorLength, "element", "elements");
6615ffd83dbSDimitry Andric     return;
6625ffd83dbSDimitry Andric   }
6635ffd83dbSDimitry Andric   case APValue::ComplexInt:
6645ffd83dbSDimitry Andric     OS << "ComplexInt ";
6655ffd83dbSDimitry Andric     {
6665ffd83dbSDimitry Andric       ColorScope Color(OS, ShowColors, ValueColor);
6675ffd83dbSDimitry Andric       OS << Value.getComplexIntReal() << " + " << Value.getComplexIntImag()
6685ffd83dbSDimitry Andric          << 'i';
6695ffd83dbSDimitry Andric     }
6705ffd83dbSDimitry Andric     return;
6715ffd83dbSDimitry Andric   case APValue::ComplexFloat:
6725ffd83dbSDimitry Andric     OS << "ComplexFloat ";
6735ffd83dbSDimitry Andric     {
6745ffd83dbSDimitry Andric       ColorScope Color(OS, ShowColors, ValueColor);
6755ffd83dbSDimitry Andric       OS << GetApproxValue(Value.getComplexFloatReal()) << " + "
6765ffd83dbSDimitry Andric          << GetApproxValue(Value.getComplexFloatImag()) << 'i';
6775ffd83dbSDimitry Andric     }
6785ffd83dbSDimitry Andric     return;
6795ffd83dbSDimitry Andric   case APValue::LValue:
6805ffd83dbSDimitry Andric     (void)Context;
6815ffd83dbSDimitry Andric     OS << "LValue <todo>";
6825ffd83dbSDimitry Andric     return;
6835ffd83dbSDimitry Andric   case APValue::Array: {
6845ffd83dbSDimitry Andric     unsigned ArraySize = Value.getArraySize();
6855ffd83dbSDimitry Andric     unsigned NumInitializedElements = Value.getArrayInitializedElts();
6865ffd83dbSDimitry Andric     OS << "Array size=" << ArraySize;
6875ffd83dbSDimitry Andric 
6885ffd83dbSDimitry Andric     dumpAPValueChildren(
6895ffd83dbSDimitry Andric         Value, Ty,
6905ffd83dbSDimitry Andric         [](const APValue &Value, unsigned Index) -> const APValue & {
6915ffd83dbSDimitry Andric           return Value.getArrayInitializedElt(Index);
6925ffd83dbSDimitry Andric         },
6935ffd83dbSDimitry Andric         NumInitializedElements, "element", "elements");
6945ffd83dbSDimitry Andric 
6955ffd83dbSDimitry Andric     if (Value.hasArrayFiller()) {
6965ffd83dbSDimitry Andric       AddChild("filler", [=] {
6975ffd83dbSDimitry Andric         {
6985ffd83dbSDimitry Andric           ColorScope Color(OS, ShowColors, ValueColor);
6995ffd83dbSDimitry Andric           OS << ArraySize - NumInitializedElements << " x ";
7005ffd83dbSDimitry Andric         }
7015ffd83dbSDimitry Andric         Visit(Value.getArrayFiller(), Ty);
7025ffd83dbSDimitry Andric       });
7035ffd83dbSDimitry Andric     }
7045ffd83dbSDimitry Andric 
7055ffd83dbSDimitry Andric     return;
7065ffd83dbSDimitry Andric   }
7075ffd83dbSDimitry Andric   case APValue::Struct: {
7085ffd83dbSDimitry Andric     OS << "Struct";
7095ffd83dbSDimitry Andric 
7105ffd83dbSDimitry Andric     dumpAPValueChildren(
7115ffd83dbSDimitry Andric         Value, Ty,
7125ffd83dbSDimitry Andric         [](const APValue &Value, unsigned Index) -> const APValue & {
7135ffd83dbSDimitry Andric           return Value.getStructBase(Index);
7145ffd83dbSDimitry Andric         },
7155ffd83dbSDimitry Andric         Value.getStructNumBases(), "base", "bases");
7165ffd83dbSDimitry Andric 
7175ffd83dbSDimitry Andric     dumpAPValueChildren(
7185ffd83dbSDimitry Andric         Value, Ty,
7195ffd83dbSDimitry Andric         [](const APValue &Value, unsigned Index) -> const APValue & {
7205ffd83dbSDimitry Andric           return Value.getStructField(Index);
7215ffd83dbSDimitry Andric         },
7225ffd83dbSDimitry Andric         Value.getStructNumFields(), "field", "fields");
7235ffd83dbSDimitry Andric 
7245ffd83dbSDimitry Andric     return;
7255ffd83dbSDimitry Andric   }
7265ffd83dbSDimitry Andric   case APValue::Union: {
7275ffd83dbSDimitry Andric     OS << "Union";
7285ffd83dbSDimitry Andric     {
7295ffd83dbSDimitry Andric       ColorScope Color(OS, ShowColors, ValueColor);
7305ffd83dbSDimitry Andric       if (const FieldDecl *FD = Value.getUnionField())
7315ffd83dbSDimitry Andric         OS << " ." << *cast<NamedDecl>(FD);
7325ffd83dbSDimitry Andric     }
7335ffd83dbSDimitry Andric     // If the union value is considered to be simple, fold it into the
7345ffd83dbSDimitry Andric     // current line to save some vertical space.
7355ffd83dbSDimitry Andric     const APValue &UnionValue = Value.getUnionValue();
7365ffd83dbSDimitry Andric     if (isSimpleAPValue(UnionValue)) {
7375ffd83dbSDimitry Andric       OS << ' ';
7385ffd83dbSDimitry Andric       Visit(UnionValue, Ty);
7395ffd83dbSDimitry Andric     } else {
7405ffd83dbSDimitry Andric       AddChild([=] { Visit(UnionValue, Ty); });
7415ffd83dbSDimitry Andric     }
7425ffd83dbSDimitry Andric 
7435ffd83dbSDimitry Andric     return;
7445ffd83dbSDimitry Andric   }
7455ffd83dbSDimitry Andric   case APValue::MemberPointer:
7465ffd83dbSDimitry Andric     OS << "MemberPointer <todo>";
7475ffd83dbSDimitry Andric     return;
7485ffd83dbSDimitry Andric   case APValue::AddrLabelDiff:
7495ffd83dbSDimitry Andric     OS << "AddrLabelDiff <todo>";
7505ffd83dbSDimitry Andric     return;
7515ffd83dbSDimitry Andric   }
7525ffd83dbSDimitry Andric   llvm_unreachable("Unknown APValue kind!");
7535ffd83dbSDimitry Andric }
7545ffd83dbSDimitry Andric 
7550b57cec5SDimitry Andric void TextNodeDumper::dumpPointer(const void *Ptr) {
7560b57cec5SDimitry Andric   ColorScope Color(OS, ShowColors, AddressColor);
7570b57cec5SDimitry Andric   OS << ' ' << Ptr;
7580b57cec5SDimitry Andric }
7590b57cec5SDimitry Andric 
7600b57cec5SDimitry Andric void TextNodeDumper::dumpLocation(SourceLocation Loc) {
7610b57cec5SDimitry Andric   if (!SM)
7620b57cec5SDimitry Andric     return;
7630b57cec5SDimitry Andric 
7640b57cec5SDimitry Andric   ColorScope Color(OS, ShowColors, LocationColor);
7650b57cec5SDimitry Andric   SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
7660b57cec5SDimitry Andric 
7670b57cec5SDimitry Andric   // The general format we print out is filename:line:col, but we drop pieces
7680b57cec5SDimitry Andric   // that haven't changed since the last loc printed.
7690b57cec5SDimitry Andric   PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
7700b57cec5SDimitry Andric 
7710b57cec5SDimitry Andric   if (PLoc.isInvalid()) {
7720b57cec5SDimitry Andric     OS << "<invalid sloc>";
7730b57cec5SDimitry Andric     return;
7740b57cec5SDimitry Andric   }
7750b57cec5SDimitry Andric 
7760b57cec5SDimitry Andric   if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
7770b57cec5SDimitry Andric     OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':'
7780b57cec5SDimitry Andric        << PLoc.getColumn();
7790b57cec5SDimitry Andric     LastLocFilename = PLoc.getFilename();
7800b57cec5SDimitry Andric     LastLocLine = PLoc.getLine();
7810b57cec5SDimitry Andric   } else if (PLoc.getLine() != LastLocLine) {
7820b57cec5SDimitry Andric     OS << "line" << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
7830b57cec5SDimitry Andric     LastLocLine = PLoc.getLine();
7840b57cec5SDimitry Andric   } else {
7850b57cec5SDimitry Andric     OS << "col" << ':' << PLoc.getColumn();
7860b57cec5SDimitry Andric   }
7870b57cec5SDimitry Andric }
7880b57cec5SDimitry Andric 
7890b57cec5SDimitry Andric void TextNodeDumper::dumpSourceRange(SourceRange R) {
7900b57cec5SDimitry Andric   // Can't translate locations if a SourceManager isn't available.
7910b57cec5SDimitry Andric   if (!SM)
7920b57cec5SDimitry Andric     return;
7930b57cec5SDimitry Andric 
7940b57cec5SDimitry Andric   OS << " <";
7950b57cec5SDimitry Andric   dumpLocation(R.getBegin());
7960b57cec5SDimitry Andric   if (R.getBegin() != R.getEnd()) {
7970b57cec5SDimitry Andric     OS << ", ";
7980b57cec5SDimitry Andric     dumpLocation(R.getEnd());
7990b57cec5SDimitry Andric   }
8000b57cec5SDimitry Andric   OS << ">";
8010b57cec5SDimitry Andric 
8020b57cec5SDimitry Andric   // <t2.c:123:421[blah], t2.c:412:321>
8030b57cec5SDimitry Andric }
8040b57cec5SDimitry Andric 
8050b57cec5SDimitry Andric void TextNodeDumper::dumpBareType(QualType T, bool Desugar) {
8060b57cec5SDimitry Andric   ColorScope Color(OS, ShowColors, TypeColor);
8070b57cec5SDimitry Andric 
8080b57cec5SDimitry Andric   SplitQualType T_split = T.split();
8095f757f3fSDimitry Andric   std::string T_str = QualType::getAsString(T_split, PrintPolicy);
8105f757f3fSDimitry Andric   OS << "'" << T_str << "'";
8110b57cec5SDimitry Andric 
8120b57cec5SDimitry Andric   if (Desugar && !T.isNull()) {
8135f757f3fSDimitry Andric     // If the type is sugared, also dump a (shallow) desugared type when
8145f757f3fSDimitry Andric     // it is visibly different.
8150b57cec5SDimitry Andric     SplitQualType D_split = T.getSplitDesugaredType();
8165f757f3fSDimitry Andric     if (T_split != D_split) {
8175f757f3fSDimitry Andric       std::string D_str = QualType::getAsString(D_split, PrintPolicy);
8185f757f3fSDimitry Andric       if (T_str != D_str)
8190b57cec5SDimitry Andric         OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'";
8200b57cec5SDimitry Andric     }
8210b57cec5SDimitry Andric   }
8225f757f3fSDimitry Andric }
8230b57cec5SDimitry Andric 
8240b57cec5SDimitry Andric void TextNodeDumper::dumpType(QualType T) {
8250b57cec5SDimitry Andric   OS << ' ';
8260b57cec5SDimitry Andric   dumpBareType(T);
8270b57cec5SDimitry Andric }
8280b57cec5SDimitry Andric 
8290b57cec5SDimitry Andric void TextNodeDumper::dumpBareDeclRef(const Decl *D) {
8300b57cec5SDimitry Andric   if (!D) {
8310b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, NullColor);
8320b57cec5SDimitry Andric     OS << "<<<NULL>>>";
8330b57cec5SDimitry Andric     return;
8340b57cec5SDimitry Andric   }
8350b57cec5SDimitry Andric 
8360b57cec5SDimitry Andric   {
8370b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, DeclKindNameColor);
8380b57cec5SDimitry Andric     OS << D->getDeclKindName();
8390b57cec5SDimitry Andric   }
8400b57cec5SDimitry Andric   dumpPointer(D);
8410b57cec5SDimitry Andric 
8420b57cec5SDimitry Andric   if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
8430b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, DeclNameColor);
8440b57cec5SDimitry Andric     OS << " '" << ND->getDeclName() << '\'';
8450b57cec5SDimitry Andric   }
8460b57cec5SDimitry Andric 
8470b57cec5SDimitry Andric   if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
8480b57cec5SDimitry Andric     dumpType(VD->getType());
8490b57cec5SDimitry Andric }
8500b57cec5SDimitry Andric 
8510b57cec5SDimitry Andric void TextNodeDumper::dumpName(const NamedDecl *ND) {
8520b57cec5SDimitry Andric   if (ND->getDeclName()) {
8530b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, DeclNameColor);
854e8d8bef9SDimitry Andric     OS << ' ' << ND->getDeclName();
8550b57cec5SDimitry Andric   }
8560b57cec5SDimitry Andric }
8570b57cec5SDimitry Andric 
8580b57cec5SDimitry Andric void TextNodeDumper::dumpAccessSpecifier(AccessSpecifier AS) {
8595ffd83dbSDimitry Andric   const auto AccessSpelling = getAccessSpelling(AS);
8605ffd83dbSDimitry Andric   if (AccessSpelling.empty())
8615ffd83dbSDimitry Andric     return;
8625ffd83dbSDimitry Andric   OS << AccessSpelling;
8630b57cec5SDimitry Andric }
8645ffd83dbSDimitry Andric 
8655ffd83dbSDimitry Andric void TextNodeDumper::dumpCleanupObject(
8665ffd83dbSDimitry Andric     const ExprWithCleanups::CleanupObject &C) {
8675ffd83dbSDimitry Andric   if (auto *BD = C.dyn_cast<BlockDecl *>())
8685ffd83dbSDimitry Andric     dumpDeclRef(BD, "cleanup");
8695ffd83dbSDimitry Andric   else if (auto *CLE = C.dyn_cast<CompoundLiteralExpr *>())
8705ffd83dbSDimitry Andric     AddChild([=] {
8715ffd83dbSDimitry Andric       OS << "cleanup ";
8725ffd83dbSDimitry Andric       {
8735ffd83dbSDimitry Andric         ColorScope Color(OS, ShowColors, StmtColor);
8745ffd83dbSDimitry Andric         OS << CLE->getStmtClassName();
8755ffd83dbSDimitry Andric       }
8765ffd83dbSDimitry Andric       dumpPointer(CLE);
8775ffd83dbSDimitry Andric     });
8785ffd83dbSDimitry Andric   else
8795ffd83dbSDimitry Andric     llvm_unreachable("unexpected cleanup type");
8800b57cec5SDimitry Andric }
8810b57cec5SDimitry Andric 
8825f757f3fSDimitry Andric void clang::TextNodeDumper::dumpTemplateSpecializationKind(
8835f757f3fSDimitry Andric     TemplateSpecializationKind TSK) {
8845f757f3fSDimitry Andric   switch (TSK) {
8855f757f3fSDimitry Andric   case TSK_Undeclared:
8865f757f3fSDimitry Andric     break;
8875f757f3fSDimitry Andric   case TSK_ImplicitInstantiation:
8885f757f3fSDimitry Andric     OS << " implicit_instantiation";
8895f757f3fSDimitry Andric     break;
8905f757f3fSDimitry Andric   case TSK_ExplicitSpecialization:
8915f757f3fSDimitry Andric     OS << " explicit_specialization";
8925f757f3fSDimitry Andric     break;
8935f757f3fSDimitry Andric   case TSK_ExplicitInstantiationDeclaration:
8945f757f3fSDimitry Andric     OS << " explicit_instantiation_declaration";
8955f757f3fSDimitry Andric     break;
8965f757f3fSDimitry Andric   case TSK_ExplicitInstantiationDefinition:
8975f757f3fSDimitry Andric     OS << " explicit_instantiation_definition";
8985f757f3fSDimitry Andric     break;
8995f757f3fSDimitry Andric   }
9005f757f3fSDimitry Andric }
9015f757f3fSDimitry Andric 
9025f757f3fSDimitry Andric void clang::TextNodeDumper::dumpNestedNameSpecifier(const NestedNameSpecifier *NNS) {
9035f757f3fSDimitry Andric   if (!NNS)
9045f757f3fSDimitry Andric     return;
9055f757f3fSDimitry Andric 
9065f757f3fSDimitry Andric   AddChild([=] {
9075f757f3fSDimitry Andric     OS << "NestedNameSpecifier";
9085f757f3fSDimitry Andric 
9095f757f3fSDimitry Andric     switch (NNS->getKind()) {
9105f757f3fSDimitry Andric     case NestedNameSpecifier::Identifier:
9115f757f3fSDimitry Andric       OS << " Identifier";
9125f757f3fSDimitry Andric       OS << " '" << NNS->getAsIdentifier()->getName() << "'";
9135f757f3fSDimitry Andric       break;
9145f757f3fSDimitry Andric     case NestedNameSpecifier::Namespace:
9155f757f3fSDimitry Andric       OS << " "; // "Namespace" is printed as the decl kind.
9165f757f3fSDimitry Andric       dumpBareDeclRef(NNS->getAsNamespace());
9175f757f3fSDimitry Andric       break;
9185f757f3fSDimitry Andric     case NestedNameSpecifier::NamespaceAlias:
9195f757f3fSDimitry Andric       OS << " "; // "NamespaceAlias" is printed as the decl kind.
9205f757f3fSDimitry Andric       dumpBareDeclRef(NNS->getAsNamespaceAlias());
9215f757f3fSDimitry Andric       break;
9225f757f3fSDimitry Andric     case NestedNameSpecifier::TypeSpec:
9235f757f3fSDimitry Andric       OS << " TypeSpec";
9245f757f3fSDimitry Andric       dumpType(QualType(NNS->getAsType(), 0));
9255f757f3fSDimitry Andric       break;
9265f757f3fSDimitry Andric     case NestedNameSpecifier::TypeSpecWithTemplate:
9275f757f3fSDimitry Andric       OS << " TypeSpecWithTemplate";
9285f757f3fSDimitry Andric       dumpType(QualType(NNS->getAsType(), 0));
9295f757f3fSDimitry Andric       break;
9305f757f3fSDimitry Andric     case NestedNameSpecifier::Global:
9315f757f3fSDimitry Andric       OS << " Global";
9325f757f3fSDimitry Andric       break;
9335f757f3fSDimitry Andric     case NestedNameSpecifier::Super:
9345f757f3fSDimitry Andric       OS << " Super";
9355f757f3fSDimitry Andric       break;
9365f757f3fSDimitry Andric     }
9375f757f3fSDimitry Andric 
9385f757f3fSDimitry Andric     dumpNestedNameSpecifier(NNS->getPrefix());
9395f757f3fSDimitry Andric   });
9405f757f3fSDimitry Andric }
9415f757f3fSDimitry Andric 
9420b57cec5SDimitry Andric void TextNodeDumper::dumpDeclRef(const Decl *D, StringRef Label) {
9430b57cec5SDimitry Andric   if (!D)
9440b57cec5SDimitry Andric     return;
9450b57cec5SDimitry Andric 
9460b57cec5SDimitry Andric   AddChild([=] {
9470b57cec5SDimitry Andric     if (!Label.empty())
9480b57cec5SDimitry Andric       OS << Label << ' ';
9490b57cec5SDimitry Andric     dumpBareDeclRef(D);
9500b57cec5SDimitry Andric   });
9510b57cec5SDimitry Andric }
9520b57cec5SDimitry Andric 
953*0fca6ea1SDimitry Andric void TextNodeDumper::dumpTemplateArgument(const TemplateArgument &TA) {
954*0fca6ea1SDimitry Andric   llvm::SmallString<128> Str;
955*0fca6ea1SDimitry Andric   {
956*0fca6ea1SDimitry Andric     llvm::raw_svector_ostream SS(Str);
957*0fca6ea1SDimitry Andric     TA.print(PrintPolicy, SS, /*IncludeType=*/true);
958*0fca6ea1SDimitry Andric   }
959*0fca6ea1SDimitry Andric   OS << " '" << Str << "'";
960*0fca6ea1SDimitry Andric 
961*0fca6ea1SDimitry Andric   if (!Context)
962*0fca6ea1SDimitry Andric     return;
963*0fca6ea1SDimitry Andric 
964*0fca6ea1SDimitry Andric   if (TemplateArgument CanonTA = Context->getCanonicalTemplateArgument(TA);
965*0fca6ea1SDimitry Andric       !CanonTA.structurallyEquals(TA)) {
966*0fca6ea1SDimitry Andric     llvm::SmallString<128> CanonStr;
967*0fca6ea1SDimitry Andric     {
968*0fca6ea1SDimitry Andric       llvm::raw_svector_ostream SS(CanonStr);
969*0fca6ea1SDimitry Andric       CanonTA.print(PrintPolicy, SS, /*IncludeType=*/true);
970*0fca6ea1SDimitry Andric     }
971*0fca6ea1SDimitry Andric     if (CanonStr != Str)
972*0fca6ea1SDimitry Andric       OS << ":'" << CanonStr << "'";
973*0fca6ea1SDimitry Andric   }
974*0fca6ea1SDimitry Andric }
975*0fca6ea1SDimitry Andric 
9760b57cec5SDimitry Andric const char *TextNodeDumper::getCommandName(unsigned CommandID) {
9770b57cec5SDimitry Andric   if (Traits)
9780b57cec5SDimitry Andric     return Traits->getCommandInfo(CommandID)->Name;
9790b57cec5SDimitry Andric   const comments::CommandInfo *Info =
9800b57cec5SDimitry Andric       comments::CommandTraits::getBuiltinCommandInfo(CommandID);
9810b57cec5SDimitry Andric   if (Info)
9820b57cec5SDimitry Andric     return Info->Name;
9830b57cec5SDimitry Andric   return "<not a builtin command>";
9840b57cec5SDimitry Andric }
9850b57cec5SDimitry Andric 
986e8d8bef9SDimitry Andric void TextNodeDumper::printFPOptions(FPOptionsOverride FPO) {
987e8d8bef9SDimitry Andric #define OPTION(NAME, TYPE, WIDTH, PREVIOUS)                                    \
988e8d8bef9SDimitry Andric   if (FPO.has##NAME##Override())                                               \
989e8d8bef9SDimitry Andric     OS << " " #NAME "=" << FPO.get##NAME##Override();
990e8d8bef9SDimitry Andric #include "clang/Basic/FPOptions.def"
991e8d8bef9SDimitry Andric }
992e8d8bef9SDimitry Andric 
9930b57cec5SDimitry Andric void TextNodeDumper::visitTextComment(const comments::TextComment *C,
9940b57cec5SDimitry Andric                                       const comments::FullComment *) {
9950b57cec5SDimitry Andric   OS << " Text=\"" << C->getText() << "\"";
9960b57cec5SDimitry Andric }
9970b57cec5SDimitry Andric 
9980b57cec5SDimitry Andric void TextNodeDumper::visitInlineCommandComment(
9990b57cec5SDimitry Andric     const comments::InlineCommandComment *C, const comments::FullComment *) {
10000b57cec5SDimitry Andric   OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
10010b57cec5SDimitry Andric   switch (C->getRenderKind()) {
10025f757f3fSDimitry Andric   case comments::InlineCommandRenderKind::Normal:
10030b57cec5SDimitry Andric     OS << " RenderNormal";
10040b57cec5SDimitry Andric     break;
10055f757f3fSDimitry Andric   case comments::InlineCommandRenderKind::Bold:
10060b57cec5SDimitry Andric     OS << " RenderBold";
10070b57cec5SDimitry Andric     break;
10085f757f3fSDimitry Andric   case comments::InlineCommandRenderKind::Monospaced:
10090b57cec5SDimitry Andric     OS << " RenderMonospaced";
10100b57cec5SDimitry Andric     break;
10115f757f3fSDimitry Andric   case comments::InlineCommandRenderKind::Emphasized:
10120b57cec5SDimitry Andric     OS << " RenderEmphasized";
10130b57cec5SDimitry Andric     break;
10145f757f3fSDimitry Andric   case comments::InlineCommandRenderKind::Anchor:
1015480093f4SDimitry Andric     OS << " RenderAnchor";
1016480093f4SDimitry Andric     break;
10170b57cec5SDimitry Andric   }
10180b57cec5SDimitry Andric 
10190b57cec5SDimitry Andric   for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
10200b57cec5SDimitry Andric     OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
10210b57cec5SDimitry Andric }
10220b57cec5SDimitry Andric 
10230b57cec5SDimitry Andric void TextNodeDumper::visitHTMLStartTagComment(
10240b57cec5SDimitry Andric     const comments::HTMLStartTagComment *C, const comments::FullComment *) {
10250b57cec5SDimitry Andric   OS << " Name=\"" << C->getTagName() << "\"";
10260b57cec5SDimitry Andric   if (C->getNumAttrs() != 0) {
10270b57cec5SDimitry Andric     OS << " Attrs: ";
10280b57cec5SDimitry Andric     for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
10290b57cec5SDimitry Andric       const comments::HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
10300b57cec5SDimitry Andric       OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
10310b57cec5SDimitry Andric     }
10320b57cec5SDimitry Andric   }
10330b57cec5SDimitry Andric   if (C->isSelfClosing())
10340b57cec5SDimitry Andric     OS << " SelfClosing";
10350b57cec5SDimitry Andric }
10360b57cec5SDimitry Andric 
10370b57cec5SDimitry Andric void TextNodeDumper::visitHTMLEndTagComment(
10380b57cec5SDimitry Andric     const comments::HTMLEndTagComment *C, const comments::FullComment *) {
10390b57cec5SDimitry Andric   OS << " Name=\"" << C->getTagName() << "\"";
10400b57cec5SDimitry Andric }
10410b57cec5SDimitry Andric 
10420b57cec5SDimitry Andric void TextNodeDumper::visitBlockCommandComment(
10430b57cec5SDimitry Andric     const comments::BlockCommandComment *C, const comments::FullComment *) {
10440b57cec5SDimitry Andric   OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
10450b57cec5SDimitry Andric   for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
10460b57cec5SDimitry Andric     OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
10470b57cec5SDimitry Andric }
10480b57cec5SDimitry Andric 
10490b57cec5SDimitry Andric void TextNodeDumper::visitParamCommandComment(
10500b57cec5SDimitry Andric     const comments::ParamCommandComment *C, const comments::FullComment *FC) {
10510b57cec5SDimitry Andric   OS << " "
10520b57cec5SDimitry Andric      << comments::ParamCommandComment::getDirectionAsString(C->getDirection());
10530b57cec5SDimitry Andric 
10540b57cec5SDimitry Andric   if (C->isDirectionExplicit())
10550b57cec5SDimitry Andric     OS << " explicitly";
10560b57cec5SDimitry Andric   else
10570b57cec5SDimitry Andric     OS << " implicitly";
10580b57cec5SDimitry Andric 
10590b57cec5SDimitry Andric   if (C->hasParamName()) {
10600b57cec5SDimitry Andric     if (C->isParamIndexValid())
10610b57cec5SDimitry Andric       OS << " Param=\"" << C->getParamName(FC) << "\"";
10620b57cec5SDimitry Andric     else
10630b57cec5SDimitry Andric       OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
10640b57cec5SDimitry Andric   }
10650b57cec5SDimitry Andric 
10660b57cec5SDimitry Andric   if (C->isParamIndexValid() && !C->isVarArgParam())
10670b57cec5SDimitry Andric     OS << " ParamIndex=" << C->getParamIndex();
10680b57cec5SDimitry Andric }
10690b57cec5SDimitry Andric 
10700b57cec5SDimitry Andric void TextNodeDumper::visitTParamCommandComment(
10710b57cec5SDimitry Andric     const comments::TParamCommandComment *C, const comments::FullComment *FC) {
10720b57cec5SDimitry Andric   if (C->hasParamName()) {
10730b57cec5SDimitry Andric     if (C->isPositionValid())
10740b57cec5SDimitry Andric       OS << " Param=\"" << C->getParamName(FC) << "\"";
10750b57cec5SDimitry Andric     else
10760b57cec5SDimitry Andric       OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
10770b57cec5SDimitry Andric   }
10780b57cec5SDimitry Andric 
10790b57cec5SDimitry Andric   if (C->isPositionValid()) {
10800b57cec5SDimitry Andric     OS << " Position=<";
10810b57cec5SDimitry Andric     for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
10820b57cec5SDimitry Andric       OS << C->getIndex(i);
10830b57cec5SDimitry Andric       if (i != e - 1)
10840b57cec5SDimitry Andric         OS << ", ";
10850b57cec5SDimitry Andric     }
10860b57cec5SDimitry Andric     OS << ">";
10870b57cec5SDimitry Andric   }
10880b57cec5SDimitry Andric }
10890b57cec5SDimitry Andric 
10900b57cec5SDimitry Andric void TextNodeDumper::visitVerbatimBlockComment(
10910b57cec5SDimitry Andric     const comments::VerbatimBlockComment *C, const comments::FullComment *) {
10920b57cec5SDimitry Andric   OS << " Name=\"" << getCommandName(C->getCommandID())
10930b57cec5SDimitry Andric      << "\""
10940b57cec5SDimitry Andric         " CloseName=\""
10950b57cec5SDimitry Andric      << C->getCloseName() << "\"";
10960b57cec5SDimitry Andric }
10970b57cec5SDimitry Andric 
10980b57cec5SDimitry Andric void TextNodeDumper::visitVerbatimBlockLineComment(
10990b57cec5SDimitry Andric     const comments::VerbatimBlockLineComment *C,
11000b57cec5SDimitry Andric     const comments::FullComment *) {
11010b57cec5SDimitry Andric   OS << " Text=\"" << C->getText() << "\"";
11020b57cec5SDimitry Andric }
11030b57cec5SDimitry Andric 
11040b57cec5SDimitry Andric void TextNodeDumper::visitVerbatimLineComment(
11050b57cec5SDimitry Andric     const comments::VerbatimLineComment *C, const comments::FullComment *) {
11060b57cec5SDimitry Andric   OS << " Text=\"" << C->getText() << "\"";
11070b57cec5SDimitry Andric }
11080b57cec5SDimitry Andric 
11090b57cec5SDimitry Andric void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument &) {
11100b57cec5SDimitry Andric   OS << " null";
11110b57cec5SDimitry Andric }
11120b57cec5SDimitry Andric 
11130b57cec5SDimitry Andric void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) {
11140b57cec5SDimitry Andric   OS << " type";
1115*0fca6ea1SDimitry Andric   dumpTemplateArgument(TA);
11160b57cec5SDimitry Andric }
11170b57cec5SDimitry Andric 
11180b57cec5SDimitry Andric void TextNodeDumper::VisitDeclarationTemplateArgument(
11190b57cec5SDimitry Andric     const TemplateArgument &TA) {
11200b57cec5SDimitry Andric   OS << " decl";
1121*0fca6ea1SDimitry Andric   dumpTemplateArgument(TA);
11220b57cec5SDimitry Andric   dumpDeclRef(TA.getAsDecl());
11230b57cec5SDimitry Andric }
11240b57cec5SDimitry Andric 
1125*0fca6ea1SDimitry Andric void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &TA) {
11260b57cec5SDimitry Andric   OS << " nullptr";
1127*0fca6ea1SDimitry Andric   dumpTemplateArgument(TA);
11280b57cec5SDimitry Andric }
11290b57cec5SDimitry Andric 
11300b57cec5SDimitry Andric void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) {
1131*0fca6ea1SDimitry Andric   OS << " integral";
1132*0fca6ea1SDimitry Andric   dumpTemplateArgument(TA);
1133*0fca6ea1SDimitry Andric }
1134*0fca6ea1SDimitry Andric 
1135*0fca6ea1SDimitry Andric void TextNodeDumper::dumpTemplateName(TemplateName TN, StringRef Label) {
1136*0fca6ea1SDimitry Andric   AddChild(Label, [=] {
1137*0fca6ea1SDimitry Andric     {
1138*0fca6ea1SDimitry Andric       llvm::SmallString<128> Str;
1139*0fca6ea1SDimitry Andric       {
1140*0fca6ea1SDimitry Andric         llvm::raw_svector_ostream SS(Str);
1141*0fca6ea1SDimitry Andric         TN.print(SS, PrintPolicy);
1142*0fca6ea1SDimitry Andric       }
1143*0fca6ea1SDimitry Andric       OS << "'" << Str << "'";
1144*0fca6ea1SDimitry Andric 
1145*0fca6ea1SDimitry Andric       if (Context) {
1146*0fca6ea1SDimitry Andric         if (TemplateName CanonTN = Context->getCanonicalTemplateName(TN);
1147*0fca6ea1SDimitry Andric             CanonTN != TN) {
1148*0fca6ea1SDimitry Andric           llvm::SmallString<128> CanonStr;
1149*0fca6ea1SDimitry Andric           {
1150*0fca6ea1SDimitry Andric             llvm::raw_svector_ostream SS(CanonStr);
1151*0fca6ea1SDimitry Andric             CanonTN.print(SS, PrintPolicy);
1152*0fca6ea1SDimitry Andric           }
1153*0fca6ea1SDimitry Andric           if (CanonStr != Str)
1154*0fca6ea1SDimitry Andric             OS << ":'" << CanonStr << "'";
1155*0fca6ea1SDimitry Andric         }
1156*0fca6ea1SDimitry Andric       }
1157*0fca6ea1SDimitry Andric     }
1158*0fca6ea1SDimitry Andric     dumpBareTemplateName(TN);
1159*0fca6ea1SDimitry Andric   });
1160*0fca6ea1SDimitry Andric }
1161*0fca6ea1SDimitry Andric 
1162*0fca6ea1SDimitry Andric void TextNodeDumper::dumpBareTemplateName(TemplateName TN) {
1163*0fca6ea1SDimitry Andric   switch (TN.getKind()) {
1164*0fca6ea1SDimitry Andric   case TemplateName::Template:
1165*0fca6ea1SDimitry Andric     AddChild([=] { Visit(TN.getAsTemplateDecl()); });
1166*0fca6ea1SDimitry Andric     return;
1167*0fca6ea1SDimitry Andric   case TemplateName::UsingTemplate: {
1168*0fca6ea1SDimitry Andric     const UsingShadowDecl *USD = TN.getAsUsingShadowDecl();
1169*0fca6ea1SDimitry Andric     AddChild([=] { Visit(USD); });
1170*0fca6ea1SDimitry Andric     AddChild("target", [=] { Visit(USD->getTargetDecl()); });
1171*0fca6ea1SDimitry Andric     return;
1172*0fca6ea1SDimitry Andric   }
1173*0fca6ea1SDimitry Andric   case TemplateName::QualifiedTemplate: {
1174*0fca6ea1SDimitry Andric     OS << " qualified";
1175*0fca6ea1SDimitry Andric     const QualifiedTemplateName *QTN = TN.getAsQualifiedTemplateName();
1176*0fca6ea1SDimitry Andric     if (QTN->hasTemplateKeyword())
1177*0fca6ea1SDimitry Andric       OS << " keyword";
1178*0fca6ea1SDimitry Andric     dumpNestedNameSpecifier(QTN->getQualifier());
1179*0fca6ea1SDimitry Andric     dumpBareTemplateName(QTN->getUnderlyingTemplate());
1180*0fca6ea1SDimitry Andric     return;
1181*0fca6ea1SDimitry Andric   }
1182*0fca6ea1SDimitry Andric   case TemplateName::DependentTemplate: {
1183*0fca6ea1SDimitry Andric     OS << " dependent";
1184*0fca6ea1SDimitry Andric     const DependentTemplateName *DTN = TN.getAsDependentTemplateName();
1185*0fca6ea1SDimitry Andric     dumpNestedNameSpecifier(DTN->getQualifier());
1186*0fca6ea1SDimitry Andric     return;
1187*0fca6ea1SDimitry Andric   }
1188*0fca6ea1SDimitry Andric   case TemplateName::SubstTemplateTemplateParm: {
1189*0fca6ea1SDimitry Andric     OS << " subst";
1190*0fca6ea1SDimitry Andric     const SubstTemplateTemplateParmStorage *STS =
1191*0fca6ea1SDimitry Andric         TN.getAsSubstTemplateTemplateParm();
1192*0fca6ea1SDimitry Andric     OS << " index " << STS->getIndex();
1193*0fca6ea1SDimitry Andric     if (std::optional<unsigned int> PackIndex = STS->getPackIndex())
1194*0fca6ea1SDimitry Andric       OS << " pack_index " << *PackIndex;
1195*0fca6ea1SDimitry Andric     if (const TemplateTemplateParmDecl *P = STS->getParameter())
1196*0fca6ea1SDimitry Andric       AddChild("parameter", [=] { Visit(P); });
1197*0fca6ea1SDimitry Andric     dumpDeclRef(STS->getAssociatedDecl(), "associated");
1198*0fca6ea1SDimitry Andric     dumpTemplateName(STS->getReplacement(), "replacement");
1199*0fca6ea1SDimitry Andric     return;
1200*0fca6ea1SDimitry Andric   }
1201*0fca6ea1SDimitry Andric   // FIXME: Implement these.
1202*0fca6ea1SDimitry Andric   case TemplateName::OverloadedTemplate:
1203*0fca6ea1SDimitry Andric     OS << " overloaded";
1204*0fca6ea1SDimitry Andric     return;
1205*0fca6ea1SDimitry Andric   case TemplateName::AssumedTemplate:
1206*0fca6ea1SDimitry Andric     OS << " assumed";
1207*0fca6ea1SDimitry Andric     return;
1208*0fca6ea1SDimitry Andric   case TemplateName::SubstTemplateTemplateParmPack:
1209*0fca6ea1SDimitry Andric     OS << " subst_pack";
1210*0fca6ea1SDimitry Andric     return;
1211*0fca6ea1SDimitry Andric   }
1212*0fca6ea1SDimitry Andric   llvm_unreachable("Unexpected TemplateName Kind");
12130b57cec5SDimitry Andric }
12140b57cec5SDimitry Andric 
12150b57cec5SDimitry Andric void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) {
12160b57cec5SDimitry Andric   OS << " template";
1217*0fca6ea1SDimitry Andric   dumpTemplateArgument(TA);
1218*0fca6ea1SDimitry Andric   dumpBareTemplateName(TA.getAsTemplate());
12190b57cec5SDimitry Andric }
12200b57cec5SDimitry Andric 
12210b57cec5SDimitry Andric void TextNodeDumper::VisitTemplateExpansionTemplateArgument(
12220b57cec5SDimitry Andric     const TemplateArgument &TA) {
12230b57cec5SDimitry Andric   OS << " template expansion";
1224*0fca6ea1SDimitry Andric   dumpTemplateArgument(TA);
1225*0fca6ea1SDimitry Andric   dumpBareTemplateName(TA.getAsTemplateOrTemplatePattern());
12260b57cec5SDimitry Andric }
12270b57cec5SDimitry Andric 
1228*0fca6ea1SDimitry Andric void TextNodeDumper::VisitExpressionTemplateArgument(
1229*0fca6ea1SDimitry Andric     const TemplateArgument &TA) {
12300b57cec5SDimitry Andric   OS << " expr";
1231*0fca6ea1SDimitry Andric   dumpTemplateArgument(TA);
12320b57cec5SDimitry Andric }
12330b57cec5SDimitry Andric 
1234*0fca6ea1SDimitry Andric void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &TA) {
12350b57cec5SDimitry Andric   OS << " pack";
1236*0fca6ea1SDimitry Andric   dumpTemplateArgument(TA);
12370b57cec5SDimitry Andric }
12380b57cec5SDimitry Andric 
12390b57cec5SDimitry Andric static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
12400b57cec5SDimitry Andric   if (Node->path_empty())
12410b57cec5SDimitry Andric     return;
12420b57cec5SDimitry Andric 
12430b57cec5SDimitry Andric   OS << " (";
12440b57cec5SDimitry Andric   bool First = true;
12450b57cec5SDimitry Andric   for (CastExpr::path_const_iterator I = Node->path_begin(),
12460b57cec5SDimitry Andric                                      E = Node->path_end();
12470b57cec5SDimitry Andric        I != E; ++I) {
12480b57cec5SDimitry Andric     const CXXBaseSpecifier *Base = *I;
12490b57cec5SDimitry Andric     if (!First)
12500b57cec5SDimitry Andric       OS << " -> ";
12510b57cec5SDimitry Andric 
1252a7dea167SDimitry Andric     const auto *RD =
1253a7dea167SDimitry Andric         cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl());
12540b57cec5SDimitry Andric 
12550b57cec5SDimitry Andric     if (Base->isVirtual())
12560b57cec5SDimitry Andric       OS << "virtual ";
12570b57cec5SDimitry Andric     OS << RD->getName();
12580b57cec5SDimitry Andric     First = false;
12590b57cec5SDimitry Andric   }
12600b57cec5SDimitry Andric 
12610b57cec5SDimitry Andric   OS << ')';
12620b57cec5SDimitry Andric }
12630b57cec5SDimitry Andric 
12640b57cec5SDimitry Andric void TextNodeDumper::VisitIfStmt(const IfStmt *Node) {
12650b57cec5SDimitry Andric   if (Node->hasInitStorage())
12660b57cec5SDimitry Andric     OS << " has_init";
12670b57cec5SDimitry Andric   if (Node->hasVarStorage())
12680b57cec5SDimitry Andric     OS << " has_var";
12690b57cec5SDimitry Andric   if (Node->hasElseStorage())
12700b57cec5SDimitry Andric     OS << " has_else";
1271349cc55cSDimitry Andric   if (Node->isConstexpr())
1272349cc55cSDimitry Andric     OS << " constexpr";
1273349cc55cSDimitry Andric   if (Node->isConsteval()) {
1274349cc55cSDimitry Andric     OS << " ";
1275349cc55cSDimitry Andric     if (Node->isNegatedConsteval())
1276349cc55cSDimitry Andric       OS << "!";
1277349cc55cSDimitry Andric     OS << "consteval";
1278349cc55cSDimitry Andric   }
12790b57cec5SDimitry Andric }
12800b57cec5SDimitry Andric 
12810b57cec5SDimitry Andric void TextNodeDumper::VisitSwitchStmt(const SwitchStmt *Node) {
12820b57cec5SDimitry Andric   if (Node->hasInitStorage())
12830b57cec5SDimitry Andric     OS << " has_init";
12840b57cec5SDimitry Andric   if (Node->hasVarStorage())
12850b57cec5SDimitry Andric     OS << " has_var";
12860b57cec5SDimitry Andric }
12870b57cec5SDimitry Andric 
12880b57cec5SDimitry Andric void TextNodeDumper::VisitWhileStmt(const WhileStmt *Node) {
12890b57cec5SDimitry Andric   if (Node->hasVarStorage())
12900b57cec5SDimitry Andric     OS << " has_var";
12910b57cec5SDimitry Andric }
12920b57cec5SDimitry Andric 
12930b57cec5SDimitry Andric void TextNodeDumper::VisitLabelStmt(const LabelStmt *Node) {
12940b57cec5SDimitry Andric   OS << " '" << Node->getName() << "'";
1295fe6060f1SDimitry Andric   if (Node->isSideEntry())
1296fe6060f1SDimitry Andric     OS << " side_entry";
12970b57cec5SDimitry Andric }
12980b57cec5SDimitry Andric 
12990b57cec5SDimitry Andric void TextNodeDumper::VisitGotoStmt(const GotoStmt *Node) {
13000b57cec5SDimitry Andric   OS << " '" << Node->getLabel()->getName() << "'";
13010b57cec5SDimitry Andric   dumpPointer(Node->getLabel());
13020b57cec5SDimitry Andric }
13030b57cec5SDimitry Andric 
13040b57cec5SDimitry Andric void TextNodeDumper::VisitCaseStmt(const CaseStmt *Node) {
13050b57cec5SDimitry Andric   if (Node->caseStmtIsGNURange())
13060b57cec5SDimitry Andric     OS << " gnu_range";
13070b57cec5SDimitry Andric }
13080b57cec5SDimitry Andric 
13095f757f3fSDimitry Andric void clang::TextNodeDumper::VisitReturnStmt(const ReturnStmt *Node) {
13105f757f3fSDimitry Andric   if (const VarDecl *Cand = Node->getNRVOCandidate()) {
13115f757f3fSDimitry Andric     OS << " nrvo_candidate(";
13125f757f3fSDimitry Andric     dumpBareDeclRef(Cand);
13135f757f3fSDimitry Andric     OS << ")";
13145f757f3fSDimitry Andric   }
13155f757f3fSDimitry Andric }
13165f757f3fSDimitry Andric 
13171db9f3b2SDimitry Andric void clang::TextNodeDumper::VisitCoawaitExpr(const CoawaitExpr *Node) {
13181db9f3b2SDimitry Andric   if (Node->isImplicit())
13191db9f3b2SDimitry Andric     OS << " implicit";
13201db9f3b2SDimitry Andric }
13211db9f3b2SDimitry Andric 
13221db9f3b2SDimitry Andric void clang::TextNodeDumper::VisitCoreturnStmt(const CoreturnStmt *Node) {
13231db9f3b2SDimitry Andric   if (Node->isImplicit())
13241db9f3b2SDimitry Andric     OS << " implicit";
13251db9f3b2SDimitry Andric }
13261db9f3b2SDimitry Andric 
13270b57cec5SDimitry Andric void TextNodeDumper::VisitConstantExpr(const ConstantExpr *Node) {
13285ffd83dbSDimitry Andric   if (Node->hasAPValueResult())
13295ffd83dbSDimitry Andric     AddChild("value",
13305ffd83dbSDimitry Andric              [=] { Visit(Node->getAPValueResult(), Node->getType()); });
13310b57cec5SDimitry Andric }
13320b57cec5SDimitry Andric 
13330b57cec5SDimitry Andric void TextNodeDumper::VisitCallExpr(const CallExpr *Node) {
13340b57cec5SDimitry Andric   if (Node->usesADL())
13350b57cec5SDimitry Andric     OS << " adl";
1336e8d8bef9SDimitry Andric   if (Node->hasStoredFPFeatures())
1337e8d8bef9SDimitry Andric     printFPOptions(Node->getFPFeatures());
13380b57cec5SDimitry Andric }
13390b57cec5SDimitry Andric 
13405ffd83dbSDimitry Andric void TextNodeDumper::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *Node) {
13415ffd83dbSDimitry Andric   const char *OperatorSpelling = clang::getOperatorSpelling(Node->getOperator());
13425ffd83dbSDimitry Andric   if (OperatorSpelling)
13435ffd83dbSDimitry Andric     OS << " '" << OperatorSpelling << "'";
13445ffd83dbSDimitry Andric 
13455ffd83dbSDimitry Andric   VisitCallExpr(Node);
13465ffd83dbSDimitry Andric }
13475ffd83dbSDimitry Andric 
13480b57cec5SDimitry Andric void TextNodeDumper::VisitCastExpr(const CastExpr *Node) {
13490b57cec5SDimitry Andric   OS << " <";
13500b57cec5SDimitry Andric   {
13510b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, CastColor);
13520b57cec5SDimitry Andric     OS << Node->getCastKindName();
13530b57cec5SDimitry Andric   }
13540b57cec5SDimitry Andric   dumpBasePath(OS, Node);
13550b57cec5SDimitry Andric   OS << ">";
1356e8d8bef9SDimitry Andric   if (Node->hasStoredFPFeatures())
1357e8d8bef9SDimitry Andric     printFPOptions(Node->getFPFeatures());
13580b57cec5SDimitry Andric }
13590b57cec5SDimitry Andric 
13600b57cec5SDimitry Andric void TextNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) {
13610b57cec5SDimitry Andric   VisitCastExpr(Node);
13620b57cec5SDimitry Andric   if (Node->isPartOfExplicitCast())
13630b57cec5SDimitry Andric     OS << " part_of_explicit_cast";
13640b57cec5SDimitry Andric }
13650b57cec5SDimitry Andric 
13660b57cec5SDimitry Andric void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
13670b57cec5SDimitry Andric   OS << " ";
13680b57cec5SDimitry Andric   dumpBareDeclRef(Node->getDecl());
13695f757f3fSDimitry Andric   dumpNestedNameSpecifier(Node->getQualifier());
13700b57cec5SDimitry Andric   if (Node->getDecl() != Node->getFoundDecl()) {
13710b57cec5SDimitry Andric     OS << " (";
13720b57cec5SDimitry Andric     dumpBareDeclRef(Node->getFoundDecl());
13730b57cec5SDimitry Andric     OS << ")";
13740b57cec5SDimitry Andric   }
13750b57cec5SDimitry Andric   switch (Node->isNonOdrUse()) {
13760b57cec5SDimitry Andric   case NOUR_None: break;
13770b57cec5SDimitry Andric   case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break;
13780b57cec5SDimitry Andric   case NOUR_Constant: OS << " non_odr_use_constant"; break;
13790b57cec5SDimitry Andric   case NOUR_Discarded: OS << " non_odr_use_discarded"; break;
13800b57cec5SDimitry Andric   }
1381*0fca6ea1SDimitry Andric   if (Node->isCapturedByCopyInLambdaWithExplicitObjectParameter())
1382*0fca6ea1SDimitry Andric     OS << " dependent_capture";
1383*0fca6ea1SDimitry Andric   else if (Node->refersToEnclosingVariableOrCapture())
13845f757f3fSDimitry Andric     OS << " refers_to_enclosing_variable_or_capture";
1385*0fca6ea1SDimitry Andric 
138606c3fb27SDimitry Andric   if (Node->isImmediateEscalating())
138706c3fb27SDimitry Andric     OS << " immediate-escalating";
13880b57cec5SDimitry Andric }
13890b57cec5SDimitry Andric 
13905f757f3fSDimitry Andric void clang::TextNodeDumper::VisitDependentScopeDeclRefExpr(
13915f757f3fSDimitry Andric     const DependentScopeDeclRefExpr *Node) {
13925f757f3fSDimitry Andric 
13935f757f3fSDimitry Andric   dumpNestedNameSpecifier(Node->getQualifier());
13945f757f3fSDimitry Andric }
13955f757f3fSDimitry Andric 
13960b57cec5SDimitry Andric void TextNodeDumper::VisitUnresolvedLookupExpr(
13970b57cec5SDimitry Andric     const UnresolvedLookupExpr *Node) {
13980b57cec5SDimitry Andric   OS << " (";
13990b57cec5SDimitry Andric   if (!Node->requiresADL())
14000b57cec5SDimitry Andric     OS << "no ";
14010b57cec5SDimitry Andric   OS << "ADL) = '" << Node->getName() << '\'';
14020b57cec5SDimitry Andric 
14030b57cec5SDimitry Andric   UnresolvedLookupExpr::decls_iterator I = Node->decls_begin(),
14040b57cec5SDimitry Andric                                        E = Node->decls_end();
14050b57cec5SDimitry Andric   if (I == E)
14060b57cec5SDimitry Andric     OS << " empty";
14070b57cec5SDimitry Andric   for (; I != E; ++I)
14080b57cec5SDimitry Andric     dumpPointer(*I);
14090b57cec5SDimitry Andric }
14100b57cec5SDimitry Andric 
14110b57cec5SDimitry Andric void TextNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) {
14120b57cec5SDimitry Andric   {
14130b57cec5SDimitry Andric     ColorScope Color(OS, ShowColors, DeclKindNameColor);
14140b57cec5SDimitry Andric     OS << " " << Node->getDecl()->getDeclKindName() << "Decl";
14150b57cec5SDimitry Andric   }
14160b57cec5SDimitry Andric   OS << "='" << *Node->getDecl() << "'";
14170b57cec5SDimitry Andric   dumpPointer(Node->getDecl());
14180b57cec5SDimitry Andric   if (Node->isFreeIvar())
14190b57cec5SDimitry Andric     OS << " isFreeIvar";
14200b57cec5SDimitry Andric }
14210b57cec5SDimitry Andric 
1422fe6060f1SDimitry Andric void TextNodeDumper::VisitSYCLUniqueStableNameExpr(
1423fe6060f1SDimitry Andric     const SYCLUniqueStableNameExpr *Node) {
1424fe6060f1SDimitry Andric   dumpType(Node->getTypeSourceInfo()->getType());
1425fe6060f1SDimitry Andric }
1426fe6060f1SDimitry Andric 
14270b57cec5SDimitry Andric void TextNodeDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
14280b57cec5SDimitry Andric   OS << " " << PredefinedExpr::getIdentKindName(Node->getIdentKind());
14290b57cec5SDimitry Andric }
14300b57cec5SDimitry Andric 
14310b57cec5SDimitry Andric void TextNodeDumper::VisitCharacterLiteral(const CharacterLiteral *Node) {
14320b57cec5SDimitry Andric   ColorScope Color(OS, ShowColors, ValueColor);
14330b57cec5SDimitry Andric   OS << " " << Node->getValue();
14340b57cec5SDimitry Andric }
14350b57cec5SDimitry Andric 
14360b57cec5SDimitry Andric void TextNodeDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
14370b57cec5SDimitry Andric   bool isSigned = Node->getType()->isSignedIntegerType();
14380b57cec5SDimitry Andric   ColorScope Color(OS, ShowColors, ValueColor);
1439fe6060f1SDimitry Andric   OS << " " << toString(Node->getValue(), 10, isSigned);
14400b57cec5SDimitry Andric }
14410b57cec5SDimitry Andric 
14420b57cec5SDimitry Andric void TextNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *Node) {
14430b57cec5SDimitry Andric   ColorScope Color(OS, ShowColors, ValueColor);
14440b57cec5SDimitry Andric   OS << " " << Node->getValueAsString(/*Radix=*/10);
14450b57cec5SDimitry Andric }
14460b57cec5SDimitry Andric 
14470b57cec5SDimitry Andric void TextNodeDumper::VisitFloatingLiteral(const FloatingLiteral *Node) {
14480b57cec5SDimitry Andric   ColorScope Color(OS, ShowColors, ValueColor);
14490b57cec5SDimitry Andric   OS << " " << Node->getValueAsApproximateDouble();
14500b57cec5SDimitry Andric }
14510b57cec5SDimitry Andric 
14520b57cec5SDimitry Andric void TextNodeDumper::VisitStringLiteral(const StringLiteral *Str) {
14530b57cec5SDimitry Andric   ColorScope Color(OS, ShowColors, ValueColor);
14540b57cec5SDimitry Andric   OS << " ";
14550b57cec5SDimitry Andric   Str->outputString(OS);
14560b57cec5SDimitry Andric }
14570b57cec5SDimitry Andric 
14580b57cec5SDimitry Andric void TextNodeDumper::VisitInitListExpr(const InitListExpr *ILE) {
14590b57cec5SDimitry Andric   if (auto *Field = ILE->getInitializedFieldInUnion()) {
14600b57cec5SDimitry Andric     OS << " field ";
14610b57cec5SDimitry Andric     dumpBareDeclRef(Field);
14620b57cec5SDimitry Andric   }
14630b57cec5SDimitry Andric }
14640b57cec5SDimitry Andric 
14650b57cec5SDimitry Andric void TextNodeDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
14660b57cec5SDimitry Andric   if (E->isResultDependent())
14670b57cec5SDimitry Andric     OS << " result_dependent";
14680b57cec5SDimitry Andric }
14690b57cec5SDimitry Andric 
14700b57cec5SDimitry Andric void TextNodeDumper::VisitUnaryOperator(const UnaryOperator *Node) {
14710b57cec5SDimitry Andric   OS << " " << (Node->isPostfix() ? "postfix" : "prefix") << " '"
14720b57cec5SDimitry Andric      << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
14730b57cec5SDimitry Andric   if (!Node->canOverflow())
14740b57cec5SDimitry Andric     OS << " cannot overflow";
1475e8d8bef9SDimitry Andric   if (Node->hasStoredFPFeatures())
1476e8d8bef9SDimitry Andric     printFPOptions(Node->getStoredFPFeatures());
14770b57cec5SDimitry Andric }
14780b57cec5SDimitry Andric 
14790b57cec5SDimitry Andric void TextNodeDumper::VisitUnaryExprOrTypeTraitExpr(
14800b57cec5SDimitry Andric     const UnaryExprOrTypeTraitExpr *Node) {
14815ffd83dbSDimitry Andric   OS << " " << getTraitSpelling(Node->getKind());
14825ffd83dbSDimitry Andric 
14830b57cec5SDimitry Andric   if (Node->isArgumentType())
14840b57cec5SDimitry Andric     dumpType(Node->getArgumentType());
14850b57cec5SDimitry Andric }
14860b57cec5SDimitry Andric 
14870b57cec5SDimitry Andric void TextNodeDumper::VisitMemberExpr(const MemberExpr *Node) {
14880b57cec5SDimitry Andric   OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl();
14890b57cec5SDimitry Andric   dumpPointer(Node->getMemberDecl());
14905f757f3fSDimitry Andric   dumpNestedNameSpecifier(Node->getQualifier());
14910b57cec5SDimitry Andric   switch (Node->isNonOdrUse()) {
14920b57cec5SDimitry Andric   case NOUR_None: break;
14930b57cec5SDimitry Andric   case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break;
14940b57cec5SDimitry Andric   case NOUR_Constant: OS << " non_odr_use_constant"; break;
14950b57cec5SDimitry Andric   case NOUR_Discarded: OS << " non_odr_use_discarded"; break;
14960b57cec5SDimitry Andric   }
14970b57cec5SDimitry Andric }
14980b57cec5SDimitry Andric 
14990b57cec5SDimitry Andric void TextNodeDumper::VisitExtVectorElementExpr(
15000b57cec5SDimitry Andric     const ExtVectorElementExpr *Node) {
15010b57cec5SDimitry Andric   OS << " " << Node->getAccessor().getNameStart();
15020b57cec5SDimitry Andric }
15030b57cec5SDimitry Andric 
15040b57cec5SDimitry Andric void TextNodeDumper::VisitBinaryOperator(const BinaryOperator *Node) {
15050b57cec5SDimitry Andric   OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1506e8d8bef9SDimitry Andric   if (Node->hasStoredFPFeatures())
1507e8d8bef9SDimitry Andric     printFPOptions(Node->getStoredFPFeatures());
15080b57cec5SDimitry Andric }
15090b57cec5SDimitry Andric 
15100b57cec5SDimitry Andric void TextNodeDumper::VisitCompoundAssignOperator(
15110b57cec5SDimitry Andric     const CompoundAssignOperator *Node) {
15120b57cec5SDimitry Andric   OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
15130b57cec5SDimitry Andric      << "' ComputeLHSTy=";
15140b57cec5SDimitry Andric   dumpBareType(Node->getComputationLHSType());
15150b57cec5SDimitry Andric   OS << " ComputeResultTy=";
15160b57cec5SDimitry Andric   dumpBareType(Node->getComputationResultType());
1517e8d8bef9SDimitry Andric   if (Node->hasStoredFPFeatures())
1518e8d8bef9SDimitry Andric     printFPOptions(Node->getStoredFPFeatures());
15190b57cec5SDimitry Andric }
15200b57cec5SDimitry Andric 
15210b57cec5SDimitry Andric void TextNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) {
15220b57cec5SDimitry Andric   OS << " " << Node->getLabel()->getName();
15230b57cec5SDimitry Andric   dumpPointer(Node->getLabel());
15240b57cec5SDimitry Andric }
15250b57cec5SDimitry Andric 
15260b57cec5SDimitry Andric void TextNodeDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) {
15270b57cec5SDimitry Andric   OS << " " << Node->getCastName() << "<"
15280b57cec5SDimitry Andric      << Node->getTypeAsWritten().getAsString() << ">"
15290b57cec5SDimitry Andric      << " <" << Node->getCastKindName();
15300b57cec5SDimitry Andric   dumpBasePath(OS, Node);
15310b57cec5SDimitry Andric   OS << ">";
15320b57cec5SDimitry Andric }
15330b57cec5SDimitry Andric 
15340b57cec5SDimitry Andric void TextNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
15350b57cec5SDimitry Andric   OS << " " << (Node->getValue() ? "true" : "false");
15360b57cec5SDimitry Andric }
15370b57cec5SDimitry Andric 
15380b57cec5SDimitry Andric void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
15390b57cec5SDimitry Andric   if (Node->isImplicit())
15400b57cec5SDimitry Andric     OS << " implicit";
1541*0fca6ea1SDimitry Andric   if (Node->isCapturedByCopyInLambdaWithExplicitObjectParameter())
1542*0fca6ea1SDimitry Andric     OS << " dependent_capture";
15430b57cec5SDimitry Andric   OS << " this";
15440b57cec5SDimitry Andric }
15450b57cec5SDimitry Andric 
15460b57cec5SDimitry Andric void TextNodeDumper::VisitCXXFunctionalCastExpr(
15470b57cec5SDimitry Andric     const CXXFunctionalCastExpr *Node) {
15480b57cec5SDimitry Andric   OS << " functional cast to " << Node->getTypeAsWritten().getAsString() << " <"
15490b57cec5SDimitry Andric      << Node->getCastKindName() << ">";
1550e8d8bef9SDimitry Andric   if (Node->hasStoredFPFeatures())
1551e8d8bef9SDimitry Andric     printFPOptions(Node->getFPFeatures());
1552e8d8bef9SDimitry Andric }
1553e8d8bef9SDimitry Andric 
1554e8d8bef9SDimitry Andric void TextNodeDumper::VisitCXXStaticCastExpr(const CXXStaticCastExpr *Node) {
1555e8d8bef9SDimitry Andric   VisitCXXNamedCastExpr(Node);
1556e8d8bef9SDimitry Andric   if (Node->hasStoredFPFeatures())
1557e8d8bef9SDimitry Andric     printFPOptions(Node->getFPFeatures());
15580b57cec5SDimitry Andric }
15590b57cec5SDimitry Andric 
15600b57cec5SDimitry Andric void TextNodeDumper::VisitCXXUnresolvedConstructExpr(
15610b57cec5SDimitry Andric     const CXXUnresolvedConstructExpr *Node) {
15620b57cec5SDimitry Andric   dumpType(Node->getTypeAsWritten());
15630b57cec5SDimitry Andric   if (Node->isListInitialization())
15640b57cec5SDimitry Andric     OS << " list";
15650b57cec5SDimitry Andric }
15660b57cec5SDimitry Andric 
15670b57cec5SDimitry Andric void TextNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
15680b57cec5SDimitry Andric   CXXConstructorDecl *Ctor = Node->getConstructor();
15690b57cec5SDimitry Andric   dumpType(Ctor->getType());
15700b57cec5SDimitry Andric   if (Node->isElidable())
15710b57cec5SDimitry Andric     OS << " elidable";
15720b57cec5SDimitry Andric   if (Node->isListInitialization())
15730b57cec5SDimitry Andric     OS << " list";
15740b57cec5SDimitry Andric   if (Node->isStdInitListInitialization())
15750b57cec5SDimitry Andric     OS << " std::initializer_list";
15760b57cec5SDimitry Andric   if (Node->requiresZeroInitialization())
15770b57cec5SDimitry Andric     OS << " zeroing";
157806c3fb27SDimitry Andric   if (Node->isImmediateEscalating())
157906c3fb27SDimitry Andric     OS << " immediate-escalating";
15800b57cec5SDimitry Andric }
15810b57cec5SDimitry Andric 
15820b57cec5SDimitry Andric void TextNodeDumper::VisitCXXBindTemporaryExpr(
15830b57cec5SDimitry Andric     const CXXBindTemporaryExpr *Node) {
15840b57cec5SDimitry Andric   OS << " (CXXTemporary";
15850b57cec5SDimitry Andric   dumpPointer(Node);
15860b57cec5SDimitry Andric   OS << ")";
15870b57cec5SDimitry Andric }
15880b57cec5SDimitry Andric 
15890b57cec5SDimitry Andric void TextNodeDumper::VisitCXXNewExpr(const CXXNewExpr *Node) {
15900b57cec5SDimitry Andric   if (Node->isGlobalNew())
15910b57cec5SDimitry Andric     OS << " global";
15920b57cec5SDimitry Andric   if (Node->isArray())
15930b57cec5SDimitry Andric     OS << " array";
15940b57cec5SDimitry Andric   if (Node->getOperatorNew()) {
15950b57cec5SDimitry Andric     OS << ' ';
15960b57cec5SDimitry Andric     dumpBareDeclRef(Node->getOperatorNew());
15970b57cec5SDimitry Andric   }
15980b57cec5SDimitry Andric   // We could dump the deallocation function used in case of error, but it's
15990b57cec5SDimitry Andric   // usually not that interesting.
16000b57cec5SDimitry Andric }
16010b57cec5SDimitry Andric 
16020b57cec5SDimitry Andric void TextNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *Node) {
16030b57cec5SDimitry Andric   if (Node->isGlobalDelete())
16040b57cec5SDimitry Andric     OS << " global";
16050b57cec5SDimitry Andric   if (Node->isArrayForm())
16060b57cec5SDimitry Andric     OS << " array";
16070b57cec5SDimitry Andric   if (Node->getOperatorDelete()) {
16080b57cec5SDimitry Andric     OS << ' ';
16090b57cec5SDimitry Andric     dumpBareDeclRef(Node->getOperatorDelete());
16100b57cec5SDimitry Andric   }
16110b57cec5SDimitry Andric }
16120b57cec5SDimitry Andric 
16135ffd83dbSDimitry Andric void TextNodeDumper::VisitTypeTraitExpr(const TypeTraitExpr *Node) {
16145ffd83dbSDimitry Andric   OS << " " << getTraitSpelling(Node->getTrait());
16155ffd83dbSDimitry Andric }
16165ffd83dbSDimitry Andric 
16175ffd83dbSDimitry Andric void TextNodeDumper::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *Node) {
16185ffd83dbSDimitry Andric   OS << " " << getTraitSpelling(Node->getTrait());
16195ffd83dbSDimitry Andric }
16205ffd83dbSDimitry Andric 
16215ffd83dbSDimitry Andric void TextNodeDumper::VisitExpressionTraitExpr(const ExpressionTraitExpr *Node) {
16225ffd83dbSDimitry Andric   OS << " " << getTraitSpelling(Node->getTrait());
16235ffd83dbSDimitry Andric }
16245ffd83dbSDimitry Andric 
1625*0fca6ea1SDimitry Andric void TextNodeDumper::VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *Node) {
1626*0fca6ea1SDimitry Andric   if (Node->hasRewrittenInit())
1627*0fca6ea1SDimitry Andric     OS << " has rewritten init";
1628*0fca6ea1SDimitry Andric }
1629*0fca6ea1SDimitry Andric 
1630*0fca6ea1SDimitry Andric void TextNodeDumper::VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *Node) {
1631*0fca6ea1SDimitry Andric   if (Node->hasRewrittenInit())
1632*0fca6ea1SDimitry Andric     OS << " has rewritten init";
1633*0fca6ea1SDimitry Andric }
1634*0fca6ea1SDimitry Andric 
16350b57cec5SDimitry Andric void TextNodeDumper::VisitMaterializeTemporaryExpr(
16360b57cec5SDimitry Andric     const MaterializeTemporaryExpr *Node) {
16370b57cec5SDimitry Andric   if (const ValueDecl *VD = Node->getExtendingDecl()) {
16380b57cec5SDimitry Andric     OS << " extended by ";
16390b57cec5SDimitry Andric     dumpBareDeclRef(VD);
16400b57cec5SDimitry Andric   }
16410b57cec5SDimitry Andric }
16420b57cec5SDimitry Andric 
16430b57cec5SDimitry Andric void TextNodeDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) {
16440b57cec5SDimitry Andric   for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
16455ffd83dbSDimitry Andric     dumpCleanupObject(Node->getObject(i));
16460b57cec5SDimitry Andric }
16470b57cec5SDimitry Andric 
16480b57cec5SDimitry Andric void TextNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
16490b57cec5SDimitry Andric   dumpPointer(Node->getPack());
16500b57cec5SDimitry Andric   dumpName(Node->getPack());
16510b57cec5SDimitry Andric }
16520b57cec5SDimitry Andric 
16530b57cec5SDimitry Andric void TextNodeDumper::VisitCXXDependentScopeMemberExpr(
16540b57cec5SDimitry Andric     const CXXDependentScopeMemberExpr *Node) {
16550b57cec5SDimitry Andric   OS << " " << (Node->isArrow() ? "->" : ".") << Node->getMember();
16560b57cec5SDimitry Andric }
16570b57cec5SDimitry Andric 
16580b57cec5SDimitry Andric void TextNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
16590b57cec5SDimitry Andric   OS << " selector=";
16600b57cec5SDimitry Andric   Node->getSelector().print(OS);
16610b57cec5SDimitry Andric   switch (Node->getReceiverKind()) {
16620b57cec5SDimitry Andric   case ObjCMessageExpr::Instance:
16630b57cec5SDimitry Andric     break;
16640b57cec5SDimitry Andric 
16650b57cec5SDimitry Andric   case ObjCMessageExpr::Class:
16660b57cec5SDimitry Andric     OS << " class=";
16670b57cec5SDimitry Andric     dumpBareType(Node->getClassReceiver());
16680b57cec5SDimitry Andric     break;
16690b57cec5SDimitry Andric 
16700b57cec5SDimitry Andric   case ObjCMessageExpr::SuperInstance:
16710b57cec5SDimitry Andric     OS << " super (instance)";
16720b57cec5SDimitry Andric     break;
16730b57cec5SDimitry Andric 
16740b57cec5SDimitry Andric   case ObjCMessageExpr::SuperClass:
16750b57cec5SDimitry Andric     OS << " super (class)";
16760b57cec5SDimitry Andric     break;
16770b57cec5SDimitry Andric   }
16780b57cec5SDimitry Andric }
16790b57cec5SDimitry Andric 
16800b57cec5SDimitry Andric void TextNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
16810b57cec5SDimitry Andric   if (auto *BoxingMethod = Node->getBoxingMethod()) {
16820b57cec5SDimitry Andric     OS << " selector=";
16830b57cec5SDimitry Andric     BoxingMethod->getSelector().print(OS);
16840b57cec5SDimitry Andric   }
16850b57cec5SDimitry Andric }
16860b57cec5SDimitry Andric 
16870b57cec5SDimitry Andric void TextNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
16880b57cec5SDimitry Andric   if (!Node->getCatchParamDecl())
16890b57cec5SDimitry Andric     OS << " catch all";
16900b57cec5SDimitry Andric }
16910b57cec5SDimitry Andric 
16920b57cec5SDimitry Andric void TextNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
16930b57cec5SDimitry Andric   dumpType(Node->getEncodedType());
16940b57cec5SDimitry Andric }
16950b57cec5SDimitry Andric 
16960b57cec5SDimitry Andric void TextNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
16970b57cec5SDimitry Andric   OS << " ";
16980b57cec5SDimitry Andric   Node->getSelector().print(OS);
16990b57cec5SDimitry Andric }
17000b57cec5SDimitry Andric 
17010b57cec5SDimitry Andric void TextNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
17020b57cec5SDimitry Andric   OS << ' ' << *Node->getProtocol();
17030b57cec5SDimitry Andric }
17040b57cec5SDimitry Andric 
17050b57cec5SDimitry Andric void TextNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) {
17060b57cec5SDimitry Andric   if (Node->isImplicitProperty()) {
17070b57cec5SDimitry Andric     OS << " Kind=MethodRef Getter=\"";
17080b57cec5SDimitry Andric     if (Node->getImplicitPropertyGetter())
17090b57cec5SDimitry Andric       Node->getImplicitPropertyGetter()->getSelector().print(OS);
17100b57cec5SDimitry Andric     else
17110b57cec5SDimitry Andric       OS << "(null)";
17120b57cec5SDimitry Andric 
17130b57cec5SDimitry Andric     OS << "\" Setter=\"";
17140b57cec5SDimitry Andric     if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
17150b57cec5SDimitry Andric       Setter->getSelector().print(OS);
17160b57cec5SDimitry Andric     else
17170b57cec5SDimitry Andric       OS << "(null)";
17180b57cec5SDimitry Andric     OS << "\"";
17190b57cec5SDimitry Andric   } else {
17200b57cec5SDimitry Andric     OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty()
17210b57cec5SDimitry Andric        << '"';
17220b57cec5SDimitry Andric   }
17230b57cec5SDimitry Andric 
17240b57cec5SDimitry Andric   if (Node->isSuperReceiver())
17250b57cec5SDimitry Andric     OS << " super";
17260b57cec5SDimitry Andric 
17270b57cec5SDimitry Andric   OS << " Messaging=";
17280b57cec5SDimitry Andric   if (Node->isMessagingGetter() && Node->isMessagingSetter())
17290b57cec5SDimitry Andric     OS << "Getter&Setter";
17300b57cec5SDimitry Andric   else if (Node->isMessagingGetter())
17310b57cec5SDimitry Andric     OS << "Getter";
17320b57cec5SDimitry Andric   else if (Node->isMessagingSetter())
17330b57cec5SDimitry Andric     OS << "Setter";
17340b57cec5SDimitry Andric }
17350b57cec5SDimitry Andric 
17360b57cec5SDimitry Andric void TextNodeDumper::VisitObjCSubscriptRefExpr(
17370b57cec5SDimitry Andric     const ObjCSubscriptRefExpr *Node) {
17380b57cec5SDimitry Andric   if (Node->isArraySubscriptRefExpr())
17390b57cec5SDimitry Andric     OS << " Kind=ArraySubscript GetterForArray=\"";
17400b57cec5SDimitry Andric   else
17410b57cec5SDimitry Andric     OS << " Kind=DictionarySubscript GetterForDictionary=\"";
17420b57cec5SDimitry Andric   if (Node->getAtIndexMethodDecl())
17430b57cec5SDimitry Andric     Node->getAtIndexMethodDecl()->getSelector().print(OS);
17440b57cec5SDimitry Andric   else
17450b57cec5SDimitry Andric     OS << "(null)";
17460b57cec5SDimitry Andric 
17470b57cec5SDimitry Andric   if (Node->isArraySubscriptRefExpr())
17480b57cec5SDimitry Andric     OS << "\" SetterForArray=\"";
17490b57cec5SDimitry Andric   else
17500b57cec5SDimitry Andric     OS << "\" SetterForDictionary=\"";
17510b57cec5SDimitry Andric   if (Node->setAtIndexMethodDecl())
17520b57cec5SDimitry Andric     Node->setAtIndexMethodDecl()->getSelector().print(OS);
17530b57cec5SDimitry Andric   else
17540b57cec5SDimitry Andric     OS << "(null)";
17550b57cec5SDimitry Andric }
17560b57cec5SDimitry Andric 
17570b57cec5SDimitry Andric void TextNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) {
17580b57cec5SDimitry Andric   OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
17590b57cec5SDimitry Andric }
17600b57cec5SDimitry Andric 
17615ffd83dbSDimitry Andric void TextNodeDumper::VisitOMPIteratorExpr(const OMPIteratorExpr *Node) {
17625ffd83dbSDimitry Andric   OS << " ";
17635ffd83dbSDimitry Andric   for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) {
17645ffd83dbSDimitry Andric     Visit(Node->getIteratorDecl(I));
17655ffd83dbSDimitry Andric     OS << " = ";
17665ffd83dbSDimitry Andric     const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I);
17675ffd83dbSDimitry Andric     OS << " begin ";
17685ffd83dbSDimitry Andric     Visit(Range.Begin);
17695ffd83dbSDimitry Andric     OS << " end ";
17705ffd83dbSDimitry Andric     Visit(Range.End);
17715ffd83dbSDimitry Andric     if (Range.Step) {
17725ffd83dbSDimitry Andric       OS << " step ";
17735ffd83dbSDimitry Andric       Visit(Range.Step);
17745ffd83dbSDimitry Andric     }
17755ffd83dbSDimitry Andric   }
17765ffd83dbSDimitry Andric }
17775ffd83dbSDimitry Andric 
1778e8d8bef9SDimitry Andric void TextNodeDumper::VisitConceptSpecializationExpr(
1779e8d8bef9SDimitry Andric     const ConceptSpecializationExpr *Node) {
1780e8d8bef9SDimitry Andric   OS << " ";
1781e8d8bef9SDimitry Andric   dumpBareDeclRef(Node->getFoundDecl());
1782e8d8bef9SDimitry Andric }
1783e8d8bef9SDimitry Andric 
1784fe6060f1SDimitry Andric void TextNodeDumper::VisitRequiresExpr(
1785fe6060f1SDimitry Andric     const RequiresExpr *Node) {
1786fe6060f1SDimitry Andric   if (!Node->isValueDependent())
1787fe6060f1SDimitry Andric     OS << (Node->isSatisfied() ? " satisfied" : " unsatisfied");
1788fe6060f1SDimitry Andric }
1789fe6060f1SDimitry Andric 
17900b57cec5SDimitry Andric void TextNodeDumper::VisitRValueReferenceType(const ReferenceType *T) {
17910b57cec5SDimitry Andric   if (T->isSpelledAsLValue())
17920b57cec5SDimitry Andric     OS << " written as lvalue reference";
17930b57cec5SDimitry Andric }
17940b57cec5SDimitry Andric 
17950b57cec5SDimitry Andric void TextNodeDumper::VisitArrayType(const ArrayType *T) {
17960b57cec5SDimitry Andric   switch (T->getSizeModifier()) {
17975f757f3fSDimitry Andric   case ArraySizeModifier::Normal:
17980b57cec5SDimitry Andric     break;
17995f757f3fSDimitry Andric   case ArraySizeModifier::Static:
18000b57cec5SDimitry Andric     OS << " static";
18010b57cec5SDimitry Andric     break;
18025f757f3fSDimitry Andric   case ArraySizeModifier::Star:
18030b57cec5SDimitry Andric     OS << " *";
18040b57cec5SDimitry Andric     break;
18050b57cec5SDimitry Andric   }
18060b57cec5SDimitry Andric   OS << " " << T->getIndexTypeQualifiers().getAsString();
18070b57cec5SDimitry Andric }
18080b57cec5SDimitry Andric 
18090b57cec5SDimitry Andric void TextNodeDumper::VisitConstantArrayType(const ConstantArrayType *T) {
18100b57cec5SDimitry Andric   OS << " " << T->getSize();
18110b57cec5SDimitry Andric   VisitArrayType(T);
18120b57cec5SDimitry Andric }
18130b57cec5SDimitry Andric 
18140b57cec5SDimitry Andric void TextNodeDumper::VisitVariableArrayType(const VariableArrayType *T) {
18150b57cec5SDimitry Andric   OS << " ";
18160b57cec5SDimitry Andric   dumpSourceRange(T->getBracketsRange());
18170b57cec5SDimitry Andric   VisitArrayType(T);
18180b57cec5SDimitry Andric }
18190b57cec5SDimitry Andric 
18200b57cec5SDimitry Andric void TextNodeDumper::VisitDependentSizedArrayType(
18210b57cec5SDimitry Andric     const DependentSizedArrayType *T) {
18220b57cec5SDimitry Andric   VisitArrayType(T);
18230b57cec5SDimitry Andric   OS << " ";
18240b57cec5SDimitry Andric   dumpSourceRange(T->getBracketsRange());
18250b57cec5SDimitry Andric }
18260b57cec5SDimitry Andric 
18270b57cec5SDimitry Andric void TextNodeDumper::VisitDependentSizedExtVectorType(
18280b57cec5SDimitry Andric     const DependentSizedExtVectorType *T) {
18290b57cec5SDimitry Andric   OS << " ";
18300b57cec5SDimitry Andric   dumpLocation(T->getAttributeLoc());
18310b57cec5SDimitry Andric }
18320b57cec5SDimitry Andric 
18330b57cec5SDimitry Andric void TextNodeDumper::VisitVectorType(const VectorType *T) {
18340b57cec5SDimitry Andric   switch (T->getVectorKind()) {
18355f757f3fSDimitry Andric   case VectorKind::Generic:
18360b57cec5SDimitry Andric     break;
18375f757f3fSDimitry Andric   case VectorKind::AltiVecVector:
18380b57cec5SDimitry Andric     OS << " altivec";
18390b57cec5SDimitry Andric     break;
18405f757f3fSDimitry Andric   case VectorKind::AltiVecPixel:
18410b57cec5SDimitry Andric     OS << " altivec pixel";
18420b57cec5SDimitry Andric     break;
18435f757f3fSDimitry Andric   case VectorKind::AltiVecBool:
18440b57cec5SDimitry Andric     OS << " altivec bool";
18450b57cec5SDimitry Andric     break;
18465f757f3fSDimitry Andric   case VectorKind::Neon:
18470b57cec5SDimitry Andric     OS << " neon";
18480b57cec5SDimitry Andric     break;
18495f757f3fSDimitry Andric   case VectorKind::NeonPoly:
18500b57cec5SDimitry Andric     OS << " neon poly";
18510b57cec5SDimitry Andric     break;
18525f757f3fSDimitry Andric   case VectorKind::SveFixedLengthData:
1853e8d8bef9SDimitry Andric     OS << " fixed-length sve data vector";
1854e8d8bef9SDimitry Andric     break;
18555f757f3fSDimitry Andric   case VectorKind::SveFixedLengthPredicate:
1856e8d8bef9SDimitry Andric     OS << " fixed-length sve predicate vector";
1857e8d8bef9SDimitry Andric     break;
18585f757f3fSDimitry Andric   case VectorKind::RVVFixedLengthData:
185906c3fb27SDimitry Andric     OS << " fixed-length rvv data vector";
186006c3fb27SDimitry Andric     break;
1861b3edf446SDimitry Andric   case VectorKind::RVVFixedLengthMask:
1862b3edf446SDimitry Andric     OS << " fixed-length rvv mask vector";
1863b3edf446SDimitry Andric     break;
18640b57cec5SDimitry Andric   }
18650b57cec5SDimitry Andric   OS << " " << T->getNumElements();
18660b57cec5SDimitry Andric }
18670b57cec5SDimitry Andric 
18680b57cec5SDimitry Andric void TextNodeDumper::VisitFunctionType(const FunctionType *T) {
18690b57cec5SDimitry Andric   auto EI = T->getExtInfo();
18700b57cec5SDimitry Andric   if (EI.getNoReturn())
18710b57cec5SDimitry Andric     OS << " noreturn";
18720b57cec5SDimitry Andric   if (EI.getProducesResult())
18730b57cec5SDimitry Andric     OS << " produces_result";
18740b57cec5SDimitry Andric   if (EI.getHasRegParm())
18750b57cec5SDimitry Andric     OS << " regparm " << EI.getRegParm();
18760b57cec5SDimitry Andric   OS << " " << FunctionType::getNameForCallConv(EI.getCC());
18770b57cec5SDimitry Andric }
18780b57cec5SDimitry Andric 
18790b57cec5SDimitry Andric void TextNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) {
18800b57cec5SDimitry Andric   auto EPI = T->getExtProtoInfo();
18810b57cec5SDimitry Andric   if (EPI.HasTrailingReturn)
18820b57cec5SDimitry Andric     OS << " trailing_return";
18830b57cec5SDimitry Andric   if (T->isConst())
18840b57cec5SDimitry Andric     OS << " const";
18850b57cec5SDimitry Andric   if (T->isVolatile())
18860b57cec5SDimitry Andric     OS << " volatile";
18870b57cec5SDimitry Andric   if (T->isRestrict())
18880b57cec5SDimitry Andric     OS << " restrict";
18890b57cec5SDimitry Andric   if (T->getExtProtoInfo().Variadic)
18900b57cec5SDimitry Andric     OS << " variadic";
18910b57cec5SDimitry Andric   switch (EPI.RefQualifier) {
18920b57cec5SDimitry Andric   case RQ_None:
18930b57cec5SDimitry Andric     break;
18940b57cec5SDimitry Andric   case RQ_LValue:
18950b57cec5SDimitry Andric     OS << " &";
18960b57cec5SDimitry Andric     break;
18970b57cec5SDimitry Andric   case RQ_RValue:
18980b57cec5SDimitry Andric     OS << " &&";
18990b57cec5SDimitry Andric     break;
19000b57cec5SDimitry Andric   }
19015f757f3fSDimitry Andric 
19025f757f3fSDimitry Andric   switch (EPI.ExceptionSpec.Type) {
19035f757f3fSDimitry Andric   case EST_None:
19045f757f3fSDimitry Andric     break;
19055f757f3fSDimitry Andric   case EST_DynamicNone:
19065f757f3fSDimitry Andric     OS << " exceptionspec_dynamic_none";
19075f757f3fSDimitry Andric     break;
19085f757f3fSDimitry Andric   case EST_Dynamic:
19095f757f3fSDimitry Andric     OS << " exceptionspec_dynamic";
19105f757f3fSDimitry Andric     break;
19115f757f3fSDimitry Andric   case EST_MSAny:
19125f757f3fSDimitry Andric     OS << " exceptionspec_ms_any";
19135f757f3fSDimitry Andric     break;
19145f757f3fSDimitry Andric   case EST_NoThrow:
19155f757f3fSDimitry Andric     OS << " exceptionspec_nothrow";
19165f757f3fSDimitry Andric     break;
19175f757f3fSDimitry Andric   case EST_BasicNoexcept:
19185f757f3fSDimitry Andric     OS << " exceptionspec_basic_noexcept";
19195f757f3fSDimitry Andric     break;
19205f757f3fSDimitry Andric   case EST_DependentNoexcept:
19215f757f3fSDimitry Andric     OS << " exceptionspec_dependent_noexcept";
19225f757f3fSDimitry Andric     break;
19235f757f3fSDimitry Andric   case EST_NoexceptFalse:
19245f757f3fSDimitry Andric     OS << " exceptionspec_noexcept_false";
19255f757f3fSDimitry Andric     break;
19265f757f3fSDimitry Andric   case EST_NoexceptTrue:
19275f757f3fSDimitry Andric     OS << " exceptionspec_noexcept_true";
19285f757f3fSDimitry Andric     break;
19295f757f3fSDimitry Andric   case EST_Unevaluated:
19305f757f3fSDimitry Andric     OS << " exceptionspec_unevaluated";
19315f757f3fSDimitry Andric     break;
19325f757f3fSDimitry Andric   case EST_Uninstantiated:
19335f757f3fSDimitry Andric     OS << " exceptionspec_uninstantiated";
19345f757f3fSDimitry Andric     break;
19355f757f3fSDimitry Andric   case EST_Unparsed:
19365f757f3fSDimitry Andric     OS << " exceptionspec_unparsed";
19375f757f3fSDimitry Andric     break;
19385f757f3fSDimitry Andric   }
19395f757f3fSDimitry Andric   if (!EPI.ExceptionSpec.Exceptions.empty()) {
19405f757f3fSDimitry Andric     AddChild([=] {
19415f757f3fSDimitry Andric       OS << "Exceptions:";
19425f757f3fSDimitry Andric       for (unsigned I = 0, N = EPI.ExceptionSpec.Exceptions.size(); I != N;
19435f757f3fSDimitry Andric            ++I) {
19445f757f3fSDimitry Andric         if (I)
19455f757f3fSDimitry Andric           OS << ",";
19465f757f3fSDimitry Andric         dumpType(EPI.ExceptionSpec.Exceptions[I]);
19475f757f3fSDimitry Andric       }
19485f757f3fSDimitry Andric     });
19495f757f3fSDimitry Andric   }
19505f757f3fSDimitry Andric   if (EPI.ExceptionSpec.NoexceptExpr) {
19515f757f3fSDimitry Andric     AddChild([=] {
19525f757f3fSDimitry Andric       OS << "NoexceptExpr: ";
19535f757f3fSDimitry Andric       Visit(EPI.ExceptionSpec.NoexceptExpr);
19545f757f3fSDimitry Andric     });
19555f757f3fSDimitry Andric   }
19565f757f3fSDimitry Andric   dumpDeclRef(EPI.ExceptionSpec.SourceDecl, "ExceptionSourceDecl");
19575f757f3fSDimitry Andric   dumpDeclRef(EPI.ExceptionSpec.SourceTemplate, "ExceptionSourceTemplate");
19585f757f3fSDimitry Andric 
19590b57cec5SDimitry Andric   // FIXME: Consumed parameters.
19600b57cec5SDimitry Andric   VisitFunctionType(T);
19610b57cec5SDimitry Andric }
19620b57cec5SDimitry Andric 
19630b57cec5SDimitry Andric void TextNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
19640b57cec5SDimitry Andric   dumpDeclRef(T->getDecl());
19650b57cec5SDimitry Andric }
19660b57cec5SDimitry Andric 
19670eae32dcSDimitry Andric void TextNodeDumper::VisitUsingType(const UsingType *T) {
19680eae32dcSDimitry Andric   dumpDeclRef(T->getFoundDecl());
1969bdd1243dSDimitry Andric   if (!T->typeMatchesDecl())
1970bdd1243dSDimitry Andric     OS << " divergent";
19710eae32dcSDimitry Andric }
19720eae32dcSDimitry Andric 
19730b57cec5SDimitry Andric void TextNodeDumper::VisitTypedefType(const TypedefType *T) {
19740b57cec5SDimitry Andric   dumpDeclRef(T->getDecl());
1975bdd1243dSDimitry Andric   if (!T->typeMatchesDecl())
1976bdd1243dSDimitry Andric     OS << " divergent";
19770b57cec5SDimitry Andric }
19780b57cec5SDimitry Andric 
19790b57cec5SDimitry Andric void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType *T) {
19800b57cec5SDimitry Andric   switch (T->getUTTKind()) {
1981bdd1243dSDimitry Andric #define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait)                                  \
1982bdd1243dSDimitry Andric   case UnaryTransformType::Enum:                                               \
1983bdd1243dSDimitry Andric     OS << " " #Trait;                                                          \
19840b57cec5SDimitry Andric     break;
1985bdd1243dSDimitry Andric #include "clang/Basic/TransformTypeTraits.def"
19860b57cec5SDimitry Andric   }
19870b57cec5SDimitry Andric }
19880b57cec5SDimitry Andric 
19890b57cec5SDimitry Andric void TextNodeDumper::VisitTagType(const TagType *T) {
19900b57cec5SDimitry Andric   dumpDeclRef(T->getDecl());
19910b57cec5SDimitry Andric }
19920b57cec5SDimitry Andric 
19930b57cec5SDimitry Andric void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
19940b57cec5SDimitry Andric   OS << " depth " << T->getDepth() << " index " << T->getIndex();
19950b57cec5SDimitry Andric   if (T->isParameterPack())
19960b57cec5SDimitry Andric     OS << " pack";
19970b57cec5SDimitry Andric   dumpDeclRef(T->getDecl());
19980b57cec5SDimitry Andric }
19990b57cec5SDimitry Andric 
2000bdd1243dSDimitry Andric void TextNodeDumper::VisitSubstTemplateTypeParmType(
2001bdd1243dSDimitry Andric     const SubstTemplateTypeParmType *T) {
2002bdd1243dSDimitry Andric   dumpDeclRef(T->getAssociatedDecl());
2003bdd1243dSDimitry Andric   VisitTemplateTypeParmDecl(T->getReplacedParameter());
2004bdd1243dSDimitry Andric   if (auto PackIndex = T->getPackIndex())
2005bdd1243dSDimitry Andric     OS << " pack_index " << *PackIndex;
2006bdd1243dSDimitry Andric }
2007bdd1243dSDimitry Andric 
2008bdd1243dSDimitry Andric void TextNodeDumper::VisitSubstTemplateTypeParmPackType(
2009bdd1243dSDimitry Andric     const SubstTemplateTypeParmPackType *T) {
2010bdd1243dSDimitry Andric   dumpDeclRef(T->getAssociatedDecl());
2011bdd1243dSDimitry Andric   VisitTemplateTypeParmDecl(T->getReplacedParameter());
2012bdd1243dSDimitry Andric }
2013bdd1243dSDimitry Andric 
20140b57cec5SDimitry Andric void TextNodeDumper::VisitAutoType(const AutoType *T) {
20150b57cec5SDimitry Andric   if (T->isDecltypeAuto())
20160b57cec5SDimitry Andric     OS << " decltype(auto)";
20170b57cec5SDimitry Andric   if (!T->isDeduced())
20180b57cec5SDimitry Andric     OS << " undeduced";
2019*0fca6ea1SDimitry Andric   if (T->isConstrained())
202055e4f9d5SDimitry Andric     dumpDeclRef(T->getTypeConstraintConcept());
20210b57cec5SDimitry Andric }
20220b57cec5SDimitry Andric 
202381ad6265SDimitry Andric void TextNodeDumper::VisitDeducedTemplateSpecializationType(
202481ad6265SDimitry Andric     const DeducedTemplateSpecializationType *T) {
2025*0fca6ea1SDimitry Andric   dumpTemplateName(T->getTemplateName(), "name");
202681ad6265SDimitry Andric }
202781ad6265SDimitry Andric 
20280b57cec5SDimitry Andric void TextNodeDumper::VisitTemplateSpecializationType(
20290b57cec5SDimitry Andric     const TemplateSpecializationType *T) {
20300b57cec5SDimitry Andric   if (T->isTypeAlias())
20310b57cec5SDimitry Andric     OS << " alias";
2032*0fca6ea1SDimitry Andric   dumpTemplateName(T->getTemplateName(), "name");
20330b57cec5SDimitry Andric }
20340b57cec5SDimitry Andric 
20350b57cec5SDimitry Andric void TextNodeDumper::VisitInjectedClassNameType(
20360b57cec5SDimitry Andric     const InjectedClassNameType *T) {
20370b57cec5SDimitry Andric   dumpDeclRef(T->getDecl());
20380b57cec5SDimitry Andric }
20390b57cec5SDimitry Andric 
20400b57cec5SDimitry Andric void TextNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
20410b57cec5SDimitry Andric   dumpDeclRef(T->getDecl());
20420b57cec5SDimitry Andric }
20430b57cec5SDimitry Andric 
20440b57cec5SDimitry Andric void TextNodeDumper::VisitPackExpansionType(const PackExpansionType *T) {
20450b57cec5SDimitry Andric   if (auto N = T->getNumExpansions())
20460b57cec5SDimitry Andric     OS << " expansions " << *N;
20470b57cec5SDimitry Andric }
20480b57cec5SDimitry Andric 
2049*0fca6ea1SDimitry Andric void TextNodeDumper::VisitTypeLoc(TypeLoc TL) {
2050*0fca6ea1SDimitry Andric   // By default, add extra Type details with no extra loc info.
2051*0fca6ea1SDimitry Andric   TypeVisitor<TextNodeDumper>::Visit(TL.getTypePtr());
2052*0fca6ea1SDimitry Andric }
2053*0fca6ea1SDimitry Andric // FIXME: override behavior for TypeLocs that have interesting location
2054*0fca6ea1SDimitry Andric // information, such as the qualifier in ElaboratedTypeLoc.
2055*0fca6ea1SDimitry Andric 
20560b57cec5SDimitry Andric void TextNodeDumper::VisitLabelDecl(const LabelDecl *D) { dumpName(D); }
20570b57cec5SDimitry Andric 
20580b57cec5SDimitry Andric void TextNodeDumper::VisitTypedefDecl(const TypedefDecl *D) {
20590b57cec5SDimitry Andric   dumpName(D);
20600b57cec5SDimitry Andric   dumpType(D->getUnderlyingType());
20610b57cec5SDimitry Andric   if (D->isModulePrivate())
20620b57cec5SDimitry Andric     OS << " __module_private__";
20630b57cec5SDimitry Andric }
20640b57cec5SDimitry Andric 
20650b57cec5SDimitry Andric void TextNodeDumper::VisitEnumDecl(const EnumDecl *D) {
20660b57cec5SDimitry Andric   if (D->isScoped()) {
20670b57cec5SDimitry Andric     if (D->isScopedUsingClassTag())
20680b57cec5SDimitry Andric       OS << " class";
20690b57cec5SDimitry Andric     else
20700b57cec5SDimitry Andric       OS << " struct";
20710b57cec5SDimitry Andric   }
20720b57cec5SDimitry Andric   dumpName(D);
20730b57cec5SDimitry Andric   if (D->isModulePrivate())
20740b57cec5SDimitry Andric     OS << " __module_private__";
20750b57cec5SDimitry Andric   if (D->isFixed())
20760b57cec5SDimitry Andric     dumpType(D->getIntegerType());
20770b57cec5SDimitry Andric }
20780b57cec5SDimitry Andric 
20790b57cec5SDimitry Andric void TextNodeDumper::VisitRecordDecl(const RecordDecl *D) {
20800b57cec5SDimitry Andric   OS << ' ' << D->getKindName();
20810b57cec5SDimitry Andric   dumpName(D);
20820b57cec5SDimitry Andric   if (D->isModulePrivate())
20830b57cec5SDimitry Andric     OS << " __module_private__";
20840b57cec5SDimitry Andric   if (D->isCompleteDefinition())
20850b57cec5SDimitry Andric     OS << " definition";
20860b57cec5SDimitry Andric }
20870b57cec5SDimitry Andric 
20880b57cec5SDimitry Andric void TextNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
20890b57cec5SDimitry Andric   dumpName(D);
20900b57cec5SDimitry Andric   dumpType(D->getType());
20910b57cec5SDimitry Andric }
20920b57cec5SDimitry Andric 
20930b57cec5SDimitry Andric void TextNodeDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
20940b57cec5SDimitry Andric   dumpName(D);
20950b57cec5SDimitry Andric   dumpType(D->getType());
20960b57cec5SDimitry Andric 
20970b57cec5SDimitry Andric   for (const auto *Child : D->chain())
20980b57cec5SDimitry Andric     dumpDeclRef(Child);
20990b57cec5SDimitry Andric }
21000b57cec5SDimitry Andric 
21010b57cec5SDimitry Andric void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) {
21020b57cec5SDimitry Andric   dumpName(D);
21030b57cec5SDimitry Andric   dumpType(D->getType());
21045f757f3fSDimitry Andric   dumpTemplateSpecializationKind(D->getTemplateSpecializationKind());
21050b57cec5SDimitry Andric 
21060b57cec5SDimitry Andric   StorageClass SC = D->getStorageClass();
21070b57cec5SDimitry Andric   if (SC != SC_None)
21080b57cec5SDimitry Andric     OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
21090b57cec5SDimitry Andric   if (D->isInlineSpecified())
21100b57cec5SDimitry Andric     OS << " inline";
21110b57cec5SDimitry Andric   if (D->isVirtualAsWritten())
21120b57cec5SDimitry Andric     OS << " virtual";
21130b57cec5SDimitry Andric   if (D->isModulePrivate())
21140b57cec5SDimitry Andric     OS << " __module_private__";
21150b57cec5SDimitry Andric 
21167a6dacacSDimitry Andric   if (D->isPureVirtual())
21170b57cec5SDimitry Andric     OS << " pure";
21180b57cec5SDimitry Andric   if (D->isDefaulted()) {
21190b57cec5SDimitry Andric     OS << " default";
21200b57cec5SDimitry Andric     if (D->isDeleted())
21210b57cec5SDimitry Andric       OS << "_delete";
21220b57cec5SDimitry Andric   }
21230b57cec5SDimitry Andric   if (D->isDeletedAsWritten())
21240b57cec5SDimitry Andric     OS << " delete";
21250b57cec5SDimitry Andric   if (D->isTrivial())
21260b57cec5SDimitry Andric     OS << " trivial";
21270b57cec5SDimitry Andric 
2128*0fca6ea1SDimitry Andric   if (const StringLiteral *M = D->getDeletedMessage())
2129*0fca6ea1SDimitry Andric     AddChild("delete message", [=] { Visit(M); });
2130*0fca6ea1SDimitry Andric 
213181ad6265SDimitry Andric   if (D->isIneligibleOrNotSelected())
213281ad6265SDimitry Andric     OS << (isa<CXXDestructorDecl>(D) ? " not_selected" : " ineligible");
213381ad6265SDimitry Andric 
21340b57cec5SDimitry Andric   if (const auto *FPT = D->getType()->getAs<FunctionProtoType>()) {
21350b57cec5SDimitry Andric     FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
21360b57cec5SDimitry Andric     switch (EPI.ExceptionSpec.Type) {
21370b57cec5SDimitry Andric     default:
21380b57cec5SDimitry Andric       break;
21390b57cec5SDimitry Andric     case EST_Unevaluated:
21400b57cec5SDimitry Andric       OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl;
21410b57cec5SDimitry Andric       break;
21420b57cec5SDimitry Andric     case EST_Uninstantiated:
21430b57cec5SDimitry Andric       OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate;
21440b57cec5SDimitry Andric       break;
21450b57cec5SDimitry Andric     }
21460b57cec5SDimitry Andric   }
21470b57cec5SDimitry Andric 
21480b57cec5SDimitry Andric   if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
21490b57cec5SDimitry Andric     if (MD->size_overridden_methods() != 0) {
21500b57cec5SDimitry Andric       auto dumpOverride = [=](const CXXMethodDecl *D) {
21510b57cec5SDimitry Andric         SplitQualType T_split = D->getType().split();
2152e8d8bef9SDimitry Andric         OS << D << " " << D->getParent()->getName() << "::" << D->getDeclName()
2153e8d8bef9SDimitry Andric            << " '" << QualType::getAsString(T_split, PrintPolicy) << "'";
21540b57cec5SDimitry Andric       };
21550b57cec5SDimitry Andric 
21560b57cec5SDimitry Andric       AddChild([=] {
21570b57cec5SDimitry Andric         auto Overrides = MD->overridden_methods();
21580b57cec5SDimitry Andric         OS << "Overrides: [ ";
21590b57cec5SDimitry Andric         dumpOverride(*Overrides.begin());
21605f757f3fSDimitry Andric         for (const auto *Override : llvm::drop_begin(Overrides)) {
21610b57cec5SDimitry Andric           OS << ", ";
21620b57cec5SDimitry Andric           dumpOverride(Override);
21630b57cec5SDimitry Andric         }
21640b57cec5SDimitry Andric         OS << " ]";
21650b57cec5SDimitry Andric       });
21660b57cec5SDimitry Andric     }
21670b57cec5SDimitry Andric   }
21680b57cec5SDimitry Andric 
2169fcaf7f86SDimitry Andric   if (!D->isInlineSpecified() && D->isInlined()) {
2170fcaf7f86SDimitry Andric     OS << " implicit-inline";
2171fcaf7f86SDimitry Andric   }
21720b57cec5SDimitry Andric   // Since NumParams comes from the FunctionProtoType of the FunctionDecl and
21730b57cec5SDimitry Andric   // the Params are set later, it is possible for a dump during debugging to
21740b57cec5SDimitry Andric   // encounter a FunctionDecl that has been created but hasn't been assigned
21750b57cec5SDimitry Andric   // ParmVarDecls yet.
21760b57cec5SDimitry Andric   if (!D->param_empty() && !D->param_begin())
21770b57cec5SDimitry Andric     OS << " <<<NULL params x " << D->getNumParams() << ">>>";
21785f757f3fSDimitry Andric 
21795f757f3fSDimitry Andric   if (const auto *Instance = D->getInstantiatedFromMemberFunction()) {
21805f757f3fSDimitry Andric     OS << " instantiated_from";
21815f757f3fSDimitry Andric     dumpPointer(Instance);
21825f757f3fSDimitry Andric   }
21830b57cec5SDimitry Andric }
21840b57cec5SDimitry Andric 
2185*0fca6ea1SDimitry Andric void TextNodeDumper::VisitCXXDeductionGuideDecl(
2186*0fca6ea1SDimitry Andric     const CXXDeductionGuideDecl *D) {
2187*0fca6ea1SDimitry Andric   VisitFunctionDecl(D);
2188*0fca6ea1SDimitry Andric   switch (D->getDeductionCandidateKind()) {
2189*0fca6ea1SDimitry Andric   case DeductionCandidate::Normal:
2190*0fca6ea1SDimitry Andric   case DeductionCandidate::Copy:
2191*0fca6ea1SDimitry Andric     return;
2192*0fca6ea1SDimitry Andric   case DeductionCandidate::Aggregate:
2193*0fca6ea1SDimitry Andric     OS << " aggregate ";
2194*0fca6ea1SDimitry Andric     break;
2195*0fca6ea1SDimitry Andric   }
2196*0fca6ea1SDimitry Andric }
2197*0fca6ea1SDimitry Andric 
2198480093f4SDimitry Andric void TextNodeDumper::VisitLifetimeExtendedTemporaryDecl(
2199480093f4SDimitry Andric     const LifetimeExtendedTemporaryDecl *D) {
2200480093f4SDimitry Andric   OS << " extended by ";
2201480093f4SDimitry Andric   dumpBareDeclRef(D->getExtendingDecl());
2202480093f4SDimitry Andric   OS << " mangling ";
2203480093f4SDimitry Andric   {
2204480093f4SDimitry Andric     ColorScope Color(OS, ShowColors, ValueColor);
2205480093f4SDimitry Andric     OS << D->getManglingNumber();
2206480093f4SDimitry Andric   }
2207480093f4SDimitry Andric }
2208480093f4SDimitry Andric 
22090b57cec5SDimitry Andric void TextNodeDumper::VisitFieldDecl(const FieldDecl *D) {
22100b57cec5SDimitry Andric   dumpName(D);
22110b57cec5SDimitry Andric   dumpType(D->getType());
22120b57cec5SDimitry Andric   if (D->isMutable())
22130b57cec5SDimitry Andric     OS << " mutable";
22140b57cec5SDimitry Andric   if (D->isModulePrivate())
22150b57cec5SDimitry Andric     OS << " __module_private__";
22160b57cec5SDimitry Andric }
22170b57cec5SDimitry Andric 
22180b57cec5SDimitry Andric void TextNodeDumper::VisitVarDecl(const VarDecl *D) {
22195f757f3fSDimitry Andric   dumpNestedNameSpecifier(D->getQualifier());
22200b57cec5SDimitry Andric   dumpName(D);
22215f757f3fSDimitry Andric   if (const auto *P = dyn_cast<ParmVarDecl>(D);
22225f757f3fSDimitry Andric       P && P->isExplicitObjectParameter())
22235f757f3fSDimitry Andric     OS << " this";
22245f757f3fSDimitry Andric 
22250b57cec5SDimitry Andric   dumpType(D->getType());
22265f757f3fSDimitry Andric   dumpTemplateSpecializationKind(D->getTemplateSpecializationKind());
22270b57cec5SDimitry Andric   StorageClass SC = D->getStorageClass();
22280b57cec5SDimitry Andric   if (SC != SC_None)
22290b57cec5SDimitry Andric     OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
22300b57cec5SDimitry Andric   switch (D->getTLSKind()) {
22310b57cec5SDimitry Andric   case VarDecl::TLS_None:
22320b57cec5SDimitry Andric     break;
22330b57cec5SDimitry Andric   case VarDecl::TLS_Static:
22340b57cec5SDimitry Andric     OS << " tls";
22350b57cec5SDimitry Andric     break;
22360b57cec5SDimitry Andric   case VarDecl::TLS_Dynamic:
22370b57cec5SDimitry Andric     OS << " tls_dynamic";
22380b57cec5SDimitry Andric     break;
22390b57cec5SDimitry Andric   }
22400b57cec5SDimitry Andric   if (D->isModulePrivate())
22410b57cec5SDimitry Andric     OS << " __module_private__";
22420b57cec5SDimitry Andric   if (D->isNRVOVariable())
22430b57cec5SDimitry Andric     OS << " nrvo";
22440b57cec5SDimitry Andric   if (D->isInline())
22450b57cec5SDimitry Andric     OS << " inline";
22460b57cec5SDimitry Andric   if (D->isConstexpr())
22470b57cec5SDimitry Andric     OS << " constexpr";
22480b57cec5SDimitry Andric   if (D->hasInit()) {
22490b57cec5SDimitry Andric     switch (D->getInitStyle()) {
22500b57cec5SDimitry Andric     case VarDecl::CInit:
22510b57cec5SDimitry Andric       OS << " cinit";
22520b57cec5SDimitry Andric       break;
22530b57cec5SDimitry Andric     case VarDecl::CallInit:
22540b57cec5SDimitry Andric       OS << " callinit";
22550b57cec5SDimitry Andric       break;
22560b57cec5SDimitry Andric     case VarDecl::ListInit:
22570b57cec5SDimitry Andric       OS << " listinit";
22580b57cec5SDimitry Andric       break;
2259bdd1243dSDimitry Andric     case VarDecl::ParenListInit:
2260bdd1243dSDimitry Andric       OS << " parenlistinit";
22610b57cec5SDimitry Andric     }
22620b57cec5SDimitry Andric   }
2263a7dea167SDimitry Andric   if (D->needsDestruction(D->getASTContext()))
2264a7dea167SDimitry Andric     OS << " destroyed";
22650b57cec5SDimitry Andric   if (D->isParameterPack())
22660b57cec5SDimitry Andric     OS << " pack";
22675ffd83dbSDimitry Andric 
22685ffd83dbSDimitry Andric   if (D->hasInit()) {
22695ffd83dbSDimitry Andric     const Expr *E = D->getInit();
22705ffd83dbSDimitry Andric     // Only dump the value of constexpr VarDecls for now.
227106c3fb27SDimitry Andric     if (E && !E->isValueDependent() && D->isConstexpr() &&
227206c3fb27SDimitry Andric         !D->getType()->isDependentType()) {
22735ffd83dbSDimitry Andric       const APValue *Value = D->evaluateValue();
22745ffd83dbSDimitry Andric       if (Value)
22755ffd83dbSDimitry Andric         AddChild("value", [=] { Visit(*Value, E->getType()); });
22765ffd83dbSDimitry Andric     }
22775ffd83dbSDimitry Andric   }
22780b57cec5SDimitry Andric }
22790b57cec5SDimitry Andric 
22800b57cec5SDimitry Andric void TextNodeDumper::VisitBindingDecl(const BindingDecl *D) {
22810b57cec5SDimitry Andric   dumpName(D);
22820b57cec5SDimitry Andric   dumpType(D->getType());
22830b57cec5SDimitry Andric }
22840b57cec5SDimitry Andric 
22850b57cec5SDimitry Andric void TextNodeDumper::VisitCapturedDecl(const CapturedDecl *D) {
22860b57cec5SDimitry Andric   if (D->isNothrow())
22870b57cec5SDimitry Andric     OS << " nothrow";
22880b57cec5SDimitry Andric }
22890b57cec5SDimitry Andric 
22900b57cec5SDimitry Andric void TextNodeDumper::VisitImportDecl(const ImportDecl *D) {
22910b57cec5SDimitry Andric   OS << ' ' << D->getImportedModule()->getFullModuleName();
22920b57cec5SDimitry Andric 
22930b57cec5SDimitry Andric   for (Decl *InitD :
22940b57cec5SDimitry Andric        D->getASTContext().getModuleInitializers(D->getImportedModule()))
22950b57cec5SDimitry Andric     dumpDeclRef(InitD, "initializer");
22960b57cec5SDimitry Andric }
22970b57cec5SDimitry Andric 
22980b57cec5SDimitry Andric void TextNodeDumper::VisitPragmaCommentDecl(const PragmaCommentDecl *D) {
22990b57cec5SDimitry Andric   OS << ' ';
23000b57cec5SDimitry Andric   switch (D->getCommentKind()) {
23010b57cec5SDimitry Andric   case PCK_Unknown:
23020b57cec5SDimitry Andric     llvm_unreachable("unexpected pragma comment kind");
23030b57cec5SDimitry Andric   case PCK_Compiler:
23040b57cec5SDimitry Andric     OS << "compiler";
23050b57cec5SDimitry Andric     break;
23060b57cec5SDimitry Andric   case PCK_ExeStr:
23070b57cec5SDimitry Andric     OS << "exestr";
23080b57cec5SDimitry Andric     break;
23090b57cec5SDimitry Andric   case PCK_Lib:
23100b57cec5SDimitry Andric     OS << "lib";
23110b57cec5SDimitry Andric     break;
23120b57cec5SDimitry Andric   case PCK_Linker:
23130b57cec5SDimitry Andric     OS << "linker";
23140b57cec5SDimitry Andric     break;
23150b57cec5SDimitry Andric   case PCK_User:
23160b57cec5SDimitry Andric     OS << "user";
23170b57cec5SDimitry Andric     break;
23180b57cec5SDimitry Andric   }
23190b57cec5SDimitry Andric   StringRef Arg = D->getArg();
23200b57cec5SDimitry Andric   if (!Arg.empty())
23210b57cec5SDimitry Andric     OS << " \"" << Arg << "\"";
23220b57cec5SDimitry Andric }
23230b57cec5SDimitry Andric 
23240b57cec5SDimitry Andric void TextNodeDumper::VisitPragmaDetectMismatchDecl(
23250b57cec5SDimitry Andric     const PragmaDetectMismatchDecl *D) {
23260b57cec5SDimitry Andric   OS << " \"" << D->getName() << "\" \"" << D->getValue() << "\"";
23270b57cec5SDimitry Andric }
23280b57cec5SDimitry Andric 
23290b57cec5SDimitry Andric void TextNodeDumper::VisitOMPExecutableDirective(
23300b57cec5SDimitry Andric     const OMPExecutableDirective *D) {
23310b57cec5SDimitry Andric   if (D->isStandaloneDirective())
23320b57cec5SDimitry Andric     OS << " openmp_standalone_directive";
23330b57cec5SDimitry Andric }
23340b57cec5SDimitry Andric 
23350b57cec5SDimitry Andric void TextNodeDumper::VisitOMPDeclareReductionDecl(
23360b57cec5SDimitry Andric     const OMPDeclareReductionDecl *D) {
23370b57cec5SDimitry Andric   dumpName(D);
23380b57cec5SDimitry Andric   dumpType(D->getType());
23390b57cec5SDimitry Andric   OS << " combiner";
23400b57cec5SDimitry Andric   dumpPointer(D->getCombiner());
23410b57cec5SDimitry Andric   if (const auto *Initializer = D->getInitializer()) {
23420b57cec5SDimitry Andric     OS << " initializer";
23430b57cec5SDimitry Andric     dumpPointer(Initializer);
23440b57cec5SDimitry Andric     switch (D->getInitializerKind()) {
23455f757f3fSDimitry Andric     case OMPDeclareReductionInitKind::Direct:
23460b57cec5SDimitry Andric       OS << " omp_priv = ";
23470b57cec5SDimitry Andric       break;
23485f757f3fSDimitry Andric     case OMPDeclareReductionInitKind::Copy:
23490b57cec5SDimitry Andric       OS << " omp_priv ()";
23500b57cec5SDimitry Andric       break;
23515f757f3fSDimitry Andric     case OMPDeclareReductionInitKind::Call:
23520b57cec5SDimitry Andric       break;
23530b57cec5SDimitry Andric     }
23540b57cec5SDimitry Andric   }
23550b57cec5SDimitry Andric }
23560b57cec5SDimitry Andric 
23570b57cec5SDimitry Andric void TextNodeDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) {
23580b57cec5SDimitry Andric   for (const auto *C : D->clauselists()) {
23590b57cec5SDimitry Andric     AddChild([=] {
23600b57cec5SDimitry Andric       if (!C) {
23610b57cec5SDimitry Andric         ColorScope Color(OS, ShowColors, NullColor);
23620b57cec5SDimitry Andric         OS << "<<<NULL>>> OMPClause";
23630b57cec5SDimitry Andric         return;
23640b57cec5SDimitry Andric       }
23650b57cec5SDimitry Andric       {
23660b57cec5SDimitry Andric         ColorScope Color(OS, ShowColors, AttrColor);
23675ffd83dbSDimitry Andric         StringRef ClauseName(
23685ffd83dbSDimitry Andric             llvm::omp::getOpenMPClauseName(C->getClauseKind()));
23690b57cec5SDimitry Andric         OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
23700b57cec5SDimitry Andric            << ClauseName.drop_front() << "Clause";
23710b57cec5SDimitry Andric       }
23720b57cec5SDimitry Andric       dumpPointer(C);
23730b57cec5SDimitry Andric       dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
23740b57cec5SDimitry Andric     });
23750b57cec5SDimitry Andric   }
23760b57cec5SDimitry Andric }
23770b57cec5SDimitry Andric 
23780b57cec5SDimitry Andric void TextNodeDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
23790b57cec5SDimitry Andric   dumpName(D);
23800b57cec5SDimitry Andric   dumpType(D->getType());
23810b57cec5SDimitry Andric }
23820b57cec5SDimitry Andric 
23830b57cec5SDimitry Andric void TextNodeDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
23840b57cec5SDimitry Andric   dumpName(D);
23850b57cec5SDimitry Andric   if (D->isInline())
23860b57cec5SDimitry Andric     OS << " inline";
2387bdd1243dSDimitry Andric   if (D->isNested())
2388bdd1243dSDimitry Andric     OS << " nested";
2389*0fca6ea1SDimitry Andric   if (!D->isFirstDecl())
2390*0fca6ea1SDimitry Andric     dumpDeclRef(D->getFirstDecl(), "original");
23910b57cec5SDimitry Andric }
23920b57cec5SDimitry Andric 
23930b57cec5SDimitry Andric void TextNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
23940b57cec5SDimitry Andric   OS << ' ';
23950b57cec5SDimitry Andric   dumpBareDeclRef(D->getNominatedNamespace());
23960b57cec5SDimitry Andric }
23970b57cec5SDimitry Andric 
23980b57cec5SDimitry Andric void TextNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
23990b57cec5SDimitry Andric   dumpName(D);
24000b57cec5SDimitry Andric   dumpDeclRef(D->getAliasedNamespace());
24010b57cec5SDimitry Andric }
24020b57cec5SDimitry Andric 
24030b57cec5SDimitry Andric void TextNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
24040b57cec5SDimitry Andric   dumpName(D);
24050b57cec5SDimitry Andric   dumpType(D->getUnderlyingType());
24060b57cec5SDimitry Andric }
24070b57cec5SDimitry Andric 
24080b57cec5SDimitry Andric void TextNodeDumper::VisitTypeAliasTemplateDecl(
24090b57cec5SDimitry Andric     const TypeAliasTemplateDecl *D) {
24100b57cec5SDimitry Andric   dumpName(D);
24110b57cec5SDimitry Andric }
24120b57cec5SDimitry Andric 
24130b57cec5SDimitry Andric void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
24140b57cec5SDimitry Andric   VisitRecordDecl(D);
24155f757f3fSDimitry Andric   if (const auto *Instance = D->getInstantiatedFromMemberClass()) {
24165f757f3fSDimitry Andric     OS << " instantiated_from";
24175f757f3fSDimitry Andric     dumpPointer(Instance);
24185f757f3fSDimitry Andric   }
24195f757f3fSDimitry Andric   if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D))
24205f757f3fSDimitry Andric     dumpTemplateSpecializationKind(CTSD->getSpecializationKind());
24215f757f3fSDimitry Andric 
24225f757f3fSDimitry Andric   dumpNestedNameSpecifier(D->getQualifier());
24235f757f3fSDimitry Andric 
24240b57cec5SDimitry Andric   if (!D->isCompleteDefinition())
24250b57cec5SDimitry Andric     return;
24260b57cec5SDimitry Andric 
24270b57cec5SDimitry Andric   AddChild([=] {
24280b57cec5SDimitry Andric     {
24290b57cec5SDimitry Andric       ColorScope Color(OS, ShowColors, DeclKindNameColor);
24300b57cec5SDimitry Andric       OS << "DefinitionData";
24310b57cec5SDimitry Andric     }
24320b57cec5SDimitry Andric #define FLAG(fn, name)                                                         \
24330b57cec5SDimitry Andric   if (D->fn())                                                                 \
24340b57cec5SDimitry Andric     OS << " " #name;
24350b57cec5SDimitry Andric     FLAG(isParsingBaseSpecifiers, parsing_base_specifiers);
24360b57cec5SDimitry Andric 
24370b57cec5SDimitry Andric     FLAG(isGenericLambda, generic);
24380b57cec5SDimitry Andric     FLAG(isLambda, lambda);
24390b57cec5SDimitry Andric 
2440a7dea167SDimitry Andric     FLAG(isAnonymousStructOrUnion, is_anonymous);
24410b57cec5SDimitry Andric     FLAG(canPassInRegisters, pass_in_registers);
24420b57cec5SDimitry Andric     FLAG(isEmpty, empty);
24430b57cec5SDimitry Andric     FLAG(isAggregate, aggregate);
24440b57cec5SDimitry Andric     FLAG(isStandardLayout, standard_layout);
24450b57cec5SDimitry Andric     FLAG(isTriviallyCopyable, trivially_copyable);
24460b57cec5SDimitry Andric     FLAG(isPOD, pod);
24470b57cec5SDimitry Andric     FLAG(isTrivial, trivial);
24480b57cec5SDimitry Andric     FLAG(isPolymorphic, polymorphic);
24490b57cec5SDimitry Andric     FLAG(isAbstract, abstract);
24500b57cec5SDimitry Andric     FLAG(isLiteral, literal);
24510b57cec5SDimitry Andric 
24520b57cec5SDimitry Andric     FLAG(hasUserDeclaredConstructor, has_user_declared_ctor);
24530b57cec5SDimitry Andric     FLAG(hasConstexprNonCopyMoveConstructor, has_constexpr_non_copy_move_ctor);
24540b57cec5SDimitry Andric     FLAG(hasMutableFields, has_mutable_fields);
24550b57cec5SDimitry Andric     FLAG(hasVariantMembers, has_variant_members);
24560b57cec5SDimitry Andric     FLAG(allowConstDefaultInit, can_const_default_init);
24570b57cec5SDimitry Andric 
24580b57cec5SDimitry Andric     AddChild([=] {
24590b57cec5SDimitry Andric       {
24600b57cec5SDimitry Andric         ColorScope Color(OS, ShowColors, DeclKindNameColor);
24610b57cec5SDimitry Andric         OS << "DefaultConstructor";
24620b57cec5SDimitry Andric       }
24630b57cec5SDimitry Andric       FLAG(hasDefaultConstructor, exists);
24640b57cec5SDimitry Andric       FLAG(hasTrivialDefaultConstructor, trivial);
24650b57cec5SDimitry Andric       FLAG(hasNonTrivialDefaultConstructor, non_trivial);
24660b57cec5SDimitry Andric       FLAG(hasUserProvidedDefaultConstructor, user_provided);
24670b57cec5SDimitry Andric       FLAG(hasConstexprDefaultConstructor, constexpr);
24680b57cec5SDimitry Andric       FLAG(needsImplicitDefaultConstructor, needs_implicit);
24690b57cec5SDimitry Andric       FLAG(defaultedDefaultConstructorIsConstexpr, defaulted_is_constexpr);
24700b57cec5SDimitry Andric     });
24710b57cec5SDimitry Andric 
24720b57cec5SDimitry Andric     AddChild([=] {
24730b57cec5SDimitry Andric       {
24740b57cec5SDimitry Andric         ColorScope Color(OS, ShowColors, DeclKindNameColor);
24750b57cec5SDimitry Andric         OS << "CopyConstructor";
24760b57cec5SDimitry Andric       }
24770b57cec5SDimitry Andric       FLAG(hasSimpleCopyConstructor, simple);
24780b57cec5SDimitry Andric       FLAG(hasTrivialCopyConstructor, trivial);
24790b57cec5SDimitry Andric       FLAG(hasNonTrivialCopyConstructor, non_trivial);
24800b57cec5SDimitry Andric       FLAG(hasUserDeclaredCopyConstructor, user_declared);
24810b57cec5SDimitry Andric       FLAG(hasCopyConstructorWithConstParam, has_const_param);
24820b57cec5SDimitry Andric       FLAG(needsImplicitCopyConstructor, needs_implicit);
24830b57cec5SDimitry Andric       FLAG(needsOverloadResolutionForCopyConstructor,
24840b57cec5SDimitry Andric            needs_overload_resolution);
24850b57cec5SDimitry Andric       if (!D->needsOverloadResolutionForCopyConstructor())
24860b57cec5SDimitry Andric         FLAG(defaultedCopyConstructorIsDeleted, defaulted_is_deleted);
24870b57cec5SDimitry Andric       FLAG(implicitCopyConstructorHasConstParam, implicit_has_const_param);
24880b57cec5SDimitry Andric     });
24890b57cec5SDimitry Andric 
24900b57cec5SDimitry Andric     AddChild([=] {
24910b57cec5SDimitry Andric       {
24920b57cec5SDimitry Andric         ColorScope Color(OS, ShowColors, DeclKindNameColor);
24930b57cec5SDimitry Andric         OS << "MoveConstructor";
24940b57cec5SDimitry Andric       }
24950b57cec5SDimitry Andric       FLAG(hasMoveConstructor, exists);
24960b57cec5SDimitry Andric       FLAG(hasSimpleMoveConstructor, simple);
24970b57cec5SDimitry Andric       FLAG(hasTrivialMoveConstructor, trivial);
24980b57cec5SDimitry Andric       FLAG(hasNonTrivialMoveConstructor, non_trivial);
24990b57cec5SDimitry Andric       FLAG(hasUserDeclaredMoveConstructor, user_declared);
25000b57cec5SDimitry Andric       FLAG(needsImplicitMoveConstructor, needs_implicit);
25010b57cec5SDimitry Andric       FLAG(needsOverloadResolutionForMoveConstructor,
25020b57cec5SDimitry Andric            needs_overload_resolution);
25030b57cec5SDimitry Andric       if (!D->needsOverloadResolutionForMoveConstructor())
25040b57cec5SDimitry Andric         FLAG(defaultedMoveConstructorIsDeleted, defaulted_is_deleted);
25050b57cec5SDimitry Andric     });
25060b57cec5SDimitry Andric 
25070b57cec5SDimitry Andric     AddChild([=] {
25080b57cec5SDimitry Andric       {
25090b57cec5SDimitry Andric         ColorScope Color(OS, ShowColors, DeclKindNameColor);
25100b57cec5SDimitry Andric         OS << "CopyAssignment";
25110b57cec5SDimitry Andric       }
25125ffd83dbSDimitry Andric       FLAG(hasSimpleCopyAssignment, simple);
25130b57cec5SDimitry Andric       FLAG(hasTrivialCopyAssignment, trivial);
25140b57cec5SDimitry Andric       FLAG(hasNonTrivialCopyAssignment, non_trivial);
25150b57cec5SDimitry Andric       FLAG(hasCopyAssignmentWithConstParam, has_const_param);
25160b57cec5SDimitry Andric       FLAG(hasUserDeclaredCopyAssignment, user_declared);
25170b57cec5SDimitry Andric       FLAG(needsImplicitCopyAssignment, needs_implicit);
25180b57cec5SDimitry Andric       FLAG(needsOverloadResolutionForCopyAssignment, needs_overload_resolution);
25190b57cec5SDimitry Andric       FLAG(implicitCopyAssignmentHasConstParam, implicit_has_const_param);
25200b57cec5SDimitry Andric     });
25210b57cec5SDimitry Andric 
25220b57cec5SDimitry Andric     AddChild([=] {
25230b57cec5SDimitry Andric       {
25240b57cec5SDimitry Andric         ColorScope Color(OS, ShowColors, DeclKindNameColor);
25250b57cec5SDimitry Andric         OS << "MoveAssignment";
25260b57cec5SDimitry Andric       }
25270b57cec5SDimitry Andric       FLAG(hasMoveAssignment, exists);
25280b57cec5SDimitry Andric       FLAG(hasSimpleMoveAssignment, simple);
25290b57cec5SDimitry Andric       FLAG(hasTrivialMoveAssignment, trivial);
25300b57cec5SDimitry Andric       FLAG(hasNonTrivialMoveAssignment, non_trivial);
25310b57cec5SDimitry Andric       FLAG(hasUserDeclaredMoveAssignment, user_declared);
25320b57cec5SDimitry Andric       FLAG(needsImplicitMoveAssignment, needs_implicit);
25330b57cec5SDimitry Andric       FLAG(needsOverloadResolutionForMoveAssignment, needs_overload_resolution);
25340b57cec5SDimitry Andric     });
25350b57cec5SDimitry Andric 
25360b57cec5SDimitry Andric     AddChild([=] {
25370b57cec5SDimitry Andric       {
25380b57cec5SDimitry Andric         ColorScope Color(OS, ShowColors, DeclKindNameColor);
25390b57cec5SDimitry Andric         OS << "Destructor";
25400b57cec5SDimitry Andric       }
25410b57cec5SDimitry Andric       FLAG(hasSimpleDestructor, simple);
25420b57cec5SDimitry Andric       FLAG(hasIrrelevantDestructor, irrelevant);
25430b57cec5SDimitry Andric       FLAG(hasTrivialDestructor, trivial);
25440b57cec5SDimitry Andric       FLAG(hasNonTrivialDestructor, non_trivial);
25450b57cec5SDimitry Andric       FLAG(hasUserDeclaredDestructor, user_declared);
2546a7dea167SDimitry Andric       FLAG(hasConstexprDestructor, constexpr);
25470b57cec5SDimitry Andric       FLAG(needsImplicitDestructor, needs_implicit);
25480b57cec5SDimitry Andric       FLAG(needsOverloadResolutionForDestructor, needs_overload_resolution);
25490b57cec5SDimitry Andric       if (!D->needsOverloadResolutionForDestructor())
25500b57cec5SDimitry Andric         FLAG(defaultedDestructorIsDeleted, defaulted_is_deleted);
25510b57cec5SDimitry Andric     });
25520b57cec5SDimitry Andric   });
25530b57cec5SDimitry Andric 
25540b57cec5SDimitry Andric   for (const auto &I : D->bases()) {
25550b57cec5SDimitry Andric     AddChild([=] {
25560b57cec5SDimitry Andric       if (I.isVirtual())
25570b57cec5SDimitry Andric         OS << "virtual ";
25580b57cec5SDimitry Andric       dumpAccessSpecifier(I.getAccessSpecifier());
25590b57cec5SDimitry Andric       dumpType(I.getType());
25600b57cec5SDimitry Andric       if (I.isPackExpansion())
25610b57cec5SDimitry Andric         OS << "...";
25620b57cec5SDimitry Andric     });
25630b57cec5SDimitry Andric   }
25640b57cec5SDimitry Andric }
25650b57cec5SDimitry Andric 
25660b57cec5SDimitry Andric void TextNodeDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
25670b57cec5SDimitry Andric   dumpName(D);
25680b57cec5SDimitry Andric }
25690b57cec5SDimitry Andric 
25700b57cec5SDimitry Andric void TextNodeDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
25710b57cec5SDimitry Andric   dumpName(D);
25720b57cec5SDimitry Andric }
25730b57cec5SDimitry Andric 
25740b57cec5SDimitry Andric void TextNodeDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
25750b57cec5SDimitry Andric   dumpName(D);
25760b57cec5SDimitry Andric }
25770b57cec5SDimitry Andric 
25780b57cec5SDimitry Andric void TextNodeDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
25790b57cec5SDimitry Andric   dumpName(D);
25800b57cec5SDimitry Andric }
25810b57cec5SDimitry Andric 
25820b57cec5SDimitry Andric void TextNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
2583480093f4SDimitry Andric   if (const auto *TC = D->getTypeConstraint()) {
2584480093f4SDimitry Andric     OS << " ";
2585480093f4SDimitry Andric     dumpBareDeclRef(TC->getNamedConcept());
2586480093f4SDimitry Andric     if (TC->getNamedConcept() != TC->getFoundDecl()) {
2587480093f4SDimitry Andric       OS << " (";
2588480093f4SDimitry Andric       dumpBareDeclRef(TC->getFoundDecl());
2589480093f4SDimitry Andric       OS << ")";
2590480093f4SDimitry Andric     }
2591480093f4SDimitry Andric   } else if (D->wasDeclaredWithTypename())
25920b57cec5SDimitry Andric     OS << " typename";
25930b57cec5SDimitry Andric   else
25940b57cec5SDimitry Andric     OS << " class";
25950b57cec5SDimitry Andric   OS << " depth " << D->getDepth() << " index " << D->getIndex();
25960b57cec5SDimitry Andric   if (D->isParameterPack())
25970b57cec5SDimitry Andric     OS << " ...";
25980b57cec5SDimitry Andric   dumpName(D);
25990b57cec5SDimitry Andric }
26000b57cec5SDimitry Andric 
26010b57cec5SDimitry Andric void TextNodeDumper::VisitNonTypeTemplateParmDecl(
26020b57cec5SDimitry Andric     const NonTypeTemplateParmDecl *D) {
26030b57cec5SDimitry Andric   dumpType(D->getType());
26040b57cec5SDimitry Andric   OS << " depth " << D->getDepth() << " index " << D->getIndex();
26050b57cec5SDimitry Andric   if (D->isParameterPack())
26060b57cec5SDimitry Andric     OS << " ...";
26070b57cec5SDimitry Andric   dumpName(D);
26080b57cec5SDimitry Andric }
26090b57cec5SDimitry Andric 
26100b57cec5SDimitry Andric void TextNodeDumper::VisitTemplateTemplateParmDecl(
26110b57cec5SDimitry Andric     const TemplateTemplateParmDecl *D) {
26120b57cec5SDimitry Andric   OS << " depth " << D->getDepth() << " index " << D->getIndex();
26130b57cec5SDimitry Andric   if (D->isParameterPack())
26140b57cec5SDimitry Andric     OS << " ...";
26150b57cec5SDimitry Andric   dumpName(D);
26160b57cec5SDimitry Andric }
26170b57cec5SDimitry Andric 
26180b57cec5SDimitry Andric void TextNodeDumper::VisitUsingDecl(const UsingDecl *D) {
26190b57cec5SDimitry Andric   OS << ' ';
26200b57cec5SDimitry Andric   if (D->getQualifier())
26210b57cec5SDimitry Andric     D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2622e8d8bef9SDimitry Andric   OS << D->getDeclName();
26235f757f3fSDimitry Andric   dumpNestedNameSpecifier(D->getQualifier());
26240b57cec5SDimitry Andric }
26250b57cec5SDimitry Andric 
2626fe6060f1SDimitry Andric void TextNodeDumper::VisitUsingEnumDecl(const UsingEnumDecl *D) {
2627fe6060f1SDimitry Andric   OS << ' ';
2628fe6060f1SDimitry Andric   dumpBareDeclRef(D->getEnumDecl());
2629fe6060f1SDimitry Andric }
2630fe6060f1SDimitry Andric 
26310b57cec5SDimitry Andric void TextNodeDumper::VisitUnresolvedUsingTypenameDecl(
26320b57cec5SDimitry Andric     const UnresolvedUsingTypenameDecl *D) {
26330b57cec5SDimitry Andric   OS << ' ';
26340b57cec5SDimitry Andric   if (D->getQualifier())
26350b57cec5SDimitry Andric     D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2636e8d8bef9SDimitry Andric   OS << D->getDeclName();
26370b57cec5SDimitry Andric }
26380b57cec5SDimitry Andric 
26390b57cec5SDimitry Andric void TextNodeDumper::VisitUnresolvedUsingValueDecl(
26400b57cec5SDimitry Andric     const UnresolvedUsingValueDecl *D) {
26410b57cec5SDimitry Andric   OS << ' ';
26420b57cec5SDimitry Andric   if (D->getQualifier())
26430b57cec5SDimitry Andric     D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2644e8d8bef9SDimitry Andric   OS << D->getDeclName();
26450b57cec5SDimitry Andric   dumpType(D->getType());
26460b57cec5SDimitry Andric }
26470b57cec5SDimitry Andric 
26480b57cec5SDimitry Andric void TextNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
26490b57cec5SDimitry Andric   OS << ' ';
26500b57cec5SDimitry Andric   dumpBareDeclRef(D->getTargetDecl());
26510b57cec5SDimitry Andric }
26520b57cec5SDimitry Andric 
26530b57cec5SDimitry Andric void TextNodeDumper::VisitConstructorUsingShadowDecl(
26540b57cec5SDimitry Andric     const ConstructorUsingShadowDecl *D) {
26550b57cec5SDimitry Andric   if (D->constructsVirtualBase())
26560b57cec5SDimitry Andric     OS << " virtual";
26570b57cec5SDimitry Andric 
26580b57cec5SDimitry Andric   AddChild([=] {
26590b57cec5SDimitry Andric     OS << "target ";
26600b57cec5SDimitry Andric     dumpBareDeclRef(D->getTargetDecl());
26610b57cec5SDimitry Andric   });
26620b57cec5SDimitry Andric 
26630b57cec5SDimitry Andric   AddChild([=] {
26640b57cec5SDimitry Andric     OS << "nominated ";
26650b57cec5SDimitry Andric     dumpBareDeclRef(D->getNominatedBaseClass());
26660b57cec5SDimitry Andric     OS << ' ';
26670b57cec5SDimitry Andric     dumpBareDeclRef(D->getNominatedBaseClassShadowDecl());
26680b57cec5SDimitry Andric   });
26690b57cec5SDimitry Andric 
26700b57cec5SDimitry Andric   AddChild([=] {
26710b57cec5SDimitry Andric     OS << "constructed ";
26720b57cec5SDimitry Andric     dumpBareDeclRef(D->getConstructedBaseClass());
26730b57cec5SDimitry Andric     OS << ' ';
26740b57cec5SDimitry Andric     dumpBareDeclRef(D->getConstructedBaseClassShadowDecl());
26750b57cec5SDimitry Andric   });
26760b57cec5SDimitry Andric }
26770b57cec5SDimitry Andric 
26780b57cec5SDimitry Andric void TextNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
26790b57cec5SDimitry Andric   switch (D->getLanguage()) {
26805f757f3fSDimitry Andric   case LinkageSpecLanguageIDs::C:
26810b57cec5SDimitry Andric     OS << " C";
26820b57cec5SDimitry Andric     break;
26835f757f3fSDimitry Andric   case LinkageSpecLanguageIDs::CXX:
26840b57cec5SDimitry Andric     OS << " C++";
26850b57cec5SDimitry Andric     break;
26860b57cec5SDimitry Andric   }
26870b57cec5SDimitry Andric }
26880b57cec5SDimitry Andric 
26890b57cec5SDimitry Andric void TextNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
26900b57cec5SDimitry Andric   OS << ' ';
26910b57cec5SDimitry Andric   dumpAccessSpecifier(D->getAccess());
26920b57cec5SDimitry Andric }
26930b57cec5SDimitry Andric 
26940b57cec5SDimitry Andric void TextNodeDumper::VisitFriendDecl(const FriendDecl *D) {
26950b57cec5SDimitry Andric   if (TypeSourceInfo *T = D->getFriendType())
26960b57cec5SDimitry Andric     dumpType(T->getType());
26970b57cec5SDimitry Andric }
26980b57cec5SDimitry Andric 
26990b57cec5SDimitry Andric void TextNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
27000b57cec5SDimitry Andric   dumpName(D);
27010b57cec5SDimitry Andric   dumpType(D->getType());
27020b57cec5SDimitry Andric   if (D->getSynthesize())
27030b57cec5SDimitry Andric     OS << " synthesize";
27040b57cec5SDimitry Andric 
27050b57cec5SDimitry Andric   switch (D->getAccessControl()) {
27060b57cec5SDimitry Andric   case ObjCIvarDecl::None:
27070b57cec5SDimitry Andric     OS << " none";
27080b57cec5SDimitry Andric     break;
27090b57cec5SDimitry Andric   case ObjCIvarDecl::Private:
27100b57cec5SDimitry Andric     OS << " private";
27110b57cec5SDimitry Andric     break;
27120b57cec5SDimitry Andric   case ObjCIvarDecl::Protected:
27130b57cec5SDimitry Andric     OS << " protected";
27140b57cec5SDimitry Andric     break;
27150b57cec5SDimitry Andric   case ObjCIvarDecl::Public:
27160b57cec5SDimitry Andric     OS << " public";
27170b57cec5SDimitry Andric     break;
27180b57cec5SDimitry Andric   case ObjCIvarDecl::Package:
27190b57cec5SDimitry Andric     OS << " package";
27200b57cec5SDimitry Andric     break;
27210b57cec5SDimitry Andric   }
27220b57cec5SDimitry Andric }
27230b57cec5SDimitry Andric 
27240b57cec5SDimitry Andric void TextNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
27250b57cec5SDimitry Andric   if (D->isInstanceMethod())
27260b57cec5SDimitry Andric     OS << " -";
27270b57cec5SDimitry Andric   else
27280b57cec5SDimitry Andric     OS << " +";
27290b57cec5SDimitry Andric   dumpName(D);
27300b57cec5SDimitry Andric   dumpType(D->getReturnType());
27310b57cec5SDimitry Andric 
27320b57cec5SDimitry Andric   if (D->isVariadic())
27330b57cec5SDimitry Andric     OS << " variadic";
27340b57cec5SDimitry Andric }
27350b57cec5SDimitry Andric 
27360b57cec5SDimitry Andric void TextNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
27370b57cec5SDimitry Andric   dumpName(D);
27380b57cec5SDimitry Andric   switch (D->getVariance()) {
27390b57cec5SDimitry Andric   case ObjCTypeParamVariance::Invariant:
27400b57cec5SDimitry Andric     break;
27410b57cec5SDimitry Andric 
27420b57cec5SDimitry Andric   case ObjCTypeParamVariance::Covariant:
27430b57cec5SDimitry Andric     OS << " covariant";
27440b57cec5SDimitry Andric     break;
27450b57cec5SDimitry Andric 
27460b57cec5SDimitry Andric   case ObjCTypeParamVariance::Contravariant:
27470b57cec5SDimitry Andric     OS << " contravariant";
27480b57cec5SDimitry Andric     break;
27490b57cec5SDimitry Andric   }
27500b57cec5SDimitry Andric 
27510b57cec5SDimitry Andric   if (D->hasExplicitBound())
27520b57cec5SDimitry Andric     OS << " bounded";
27530b57cec5SDimitry Andric   dumpType(D->getUnderlyingType());
27540b57cec5SDimitry Andric }
27550b57cec5SDimitry Andric 
27560b57cec5SDimitry Andric void TextNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
27570b57cec5SDimitry Andric   dumpName(D);
27580b57cec5SDimitry Andric   dumpDeclRef(D->getClassInterface());
27590b57cec5SDimitry Andric   dumpDeclRef(D->getImplementation());
27600b57cec5SDimitry Andric   for (const auto *P : D->protocols())
27610b57cec5SDimitry Andric     dumpDeclRef(P);
27620b57cec5SDimitry Andric }
27630b57cec5SDimitry Andric 
27640b57cec5SDimitry Andric void TextNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
27650b57cec5SDimitry Andric   dumpName(D);
27660b57cec5SDimitry Andric   dumpDeclRef(D->getClassInterface());
27670b57cec5SDimitry Andric   dumpDeclRef(D->getCategoryDecl());
27680b57cec5SDimitry Andric }
27690b57cec5SDimitry Andric 
27700b57cec5SDimitry Andric void TextNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
27710b57cec5SDimitry Andric   dumpName(D);
27720b57cec5SDimitry Andric 
27730b57cec5SDimitry Andric   for (const auto *Child : D->protocols())
27740b57cec5SDimitry Andric     dumpDeclRef(Child);
27750b57cec5SDimitry Andric }
27760b57cec5SDimitry Andric 
27770b57cec5SDimitry Andric void TextNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
27780b57cec5SDimitry Andric   dumpName(D);
27790b57cec5SDimitry Andric   dumpDeclRef(D->getSuperClass(), "super");
27800b57cec5SDimitry Andric 
27810b57cec5SDimitry Andric   dumpDeclRef(D->getImplementation());
27820b57cec5SDimitry Andric   for (const auto *Child : D->protocols())
27830b57cec5SDimitry Andric     dumpDeclRef(Child);
27840b57cec5SDimitry Andric }
27850b57cec5SDimitry Andric 
27860b57cec5SDimitry Andric void TextNodeDumper::VisitObjCImplementationDecl(
27870b57cec5SDimitry Andric     const ObjCImplementationDecl *D) {
27880b57cec5SDimitry Andric   dumpName(D);
27890b57cec5SDimitry Andric   dumpDeclRef(D->getSuperClass(), "super");
27900b57cec5SDimitry Andric   dumpDeclRef(D->getClassInterface());
27910b57cec5SDimitry Andric }
27920b57cec5SDimitry Andric 
27930b57cec5SDimitry Andric void TextNodeDumper::VisitObjCCompatibleAliasDecl(
27940b57cec5SDimitry Andric     const ObjCCompatibleAliasDecl *D) {
27950b57cec5SDimitry Andric   dumpName(D);
27960b57cec5SDimitry Andric   dumpDeclRef(D->getClassInterface());
27970b57cec5SDimitry Andric }
27980b57cec5SDimitry Andric 
27990b57cec5SDimitry Andric void TextNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
28000b57cec5SDimitry Andric   dumpName(D);
28010b57cec5SDimitry Andric   dumpType(D->getType());
28020b57cec5SDimitry Andric 
28030b57cec5SDimitry Andric   if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
28040b57cec5SDimitry Andric     OS << " required";
28050b57cec5SDimitry Andric   else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
28060b57cec5SDimitry Andric     OS << " optional";
28070b57cec5SDimitry Andric 
28085ffd83dbSDimitry Andric   ObjCPropertyAttribute::Kind Attrs = D->getPropertyAttributes();
28095ffd83dbSDimitry Andric   if (Attrs != ObjCPropertyAttribute::kind_noattr) {
28105ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_readonly)
28110b57cec5SDimitry Andric       OS << " readonly";
28125ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_assign)
28130b57cec5SDimitry Andric       OS << " assign";
28145ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_readwrite)
28150b57cec5SDimitry Andric       OS << " readwrite";
28165ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_retain)
28170b57cec5SDimitry Andric       OS << " retain";
28185ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_copy)
28190b57cec5SDimitry Andric       OS << " copy";
28205ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_nonatomic)
28210b57cec5SDimitry Andric       OS << " nonatomic";
28225ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_atomic)
28230b57cec5SDimitry Andric       OS << " atomic";
28245ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_weak)
28250b57cec5SDimitry Andric       OS << " weak";
28265ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_strong)
28270b57cec5SDimitry Andric       OS << " strong";
28285ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_unsafe_unretained)
28290b57cec5SDimitry Andric       OS << " unsafe_unretained";
28305ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_class)
28310b57cec5SDimitry Andric       OS << " class";
28325ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_direct)
2833480093f4SDimitry Andric       OS << " direct";
28345ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_getter)
28350b57cec5SDimitry Andric       dumpDeclRef(D->getGetterMethodDecl(), "getter");
28365ffd83dbSDimitry Andric     if (Attrs & ObjCPropertyAttribute::kind_setter)
28370b57cec5SDimitry Andric       dumpDeclRef(D->getSetterMethodDecl(), "setter");
28380b57cec5SDimitry Andric   }
28390b57cec5SDimitry Andric }
28400b57cec5SDimitry Andric 
28410b57cec5SDimitry Andric void TextNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
28420b57cec5SDimitry Andric   dumpName(D->getPropertyDecl());
28430b57cec5SDimitry Andric   if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
28440b57cec5SDimitry Andric     OS << " synthesize";
28450b57cec5SDimitry Andric   else
28460b57cec5SDimitry Andric     OS << " dynamic";
28470b57cec5SDimitry Andric   dumpDeclRef(D->getPropertyDecl());
28480b57cec5SDimitry Andric   dumpDeclRef(D->getPropertyIvarDecl());
28490b57cec5SDimitry Andric }
28500b57cec5SDimitry Andric 
28510b57cec5SDimitry Andric void TextNodeDumper::VisitBlockDecl(const BlockDecl *D) {
28520b57cec5SDimitry Andric   if (D->isVariadic())
28530b57cec5SDimitry Andric     OS << " variadic";
28540b57cec5SDimitry Andric 
28550b57cec5SDimitry Andric   if (D->capturesCXXThis())
28560b57cec5SDimitry Andric     OS << " captures_this";
28570b57cec5SDimitry Andric }
28580b57cec5SDimitry Andric 
28590b57cec5SDimitry Andric void TextNodeDumper::VisitConceptDecl(const ConceptDecl *D) {
28600b57cec5SDimitry Andric   dumpName(D);
28610b57cec5SDimitry Andric }
286281ad6265SDimitry Andric 
286381ad6265SDimitry Andric void TextNodeDumper::VisitCompoundStmt(const CompoundStmt *S) {
286481ad6265SDimitry Andric   VisitStmt(S);
286581ad6265SDimitry Andric   if (S->hasStoredFPFeatures())
286681ad6265SDimitry Andric     printFPOptions(S->getStoredFPFeatures());
286781ad6265SDimitry Andric }
2868bdd1243dSDimitry Andric 
2869bdd1243dSDimitry Andric void TextNodeDumper::VisitHLSLBufferDecl(const HLSLBufferDecl *D) {
2870bdd1243dSDimitry Andric   if (D->isCBuffer())
2871bdd1243dSDimitry Andric     OS << " cbuffer";
2872bdd1243dSDimitry Andric   else
2873bdd1243dSDimitry Andric     OS << " tbuffer";
2874bdd1243dSDimitry Andric   dumpName(D);
2875bdd1243dSDimitry Andric }
2876*0fca6ea1SDimitry Andric 
2877*0fca6ea1SDimitry Andric void TextNodeDumper::VisitOpenACCConstructStmt(const OpenACCConstructStmt *S) {
2878*0fca6ea1SDimitry Andric   OS << " " << S->getDirectiveKind();
2879*0fca6ea1SDimitry Andric }
2880*0fca6ea1SDimitry Andric void TextNodeDumper::VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *S) {
2881*0fca6ea1SDimitry Andric 
2882*0fca6ea1SDimitry Andric   if (S->isOrphanedLoopConstruct())
2883*0fca6ea1SDimitry Andric     OS << " <orphan>";
2884*0fca6ea1SDimitry Andric   else
2885*0fca6ea1SDimitry Andric     OS << " parent: " << S->getParentComputeConstruct();
2886*0fca6ea1SDimitry Andric }
2887*0fca6ea1SDimitry Andric 
2888*0fca6ea1SDimitry Andric void TextNodeDumper::VisitEmbedExpr(const EmbedExpr *S) {
2889*0fca6ea1SDimitry Andric   AddChild("begin", [=] { OS << S->getStartingElementPos(); });
2890*0fca6ea1SDimitry Andric   AddChild("number of elements", [=] { OS << S->getDataElementCount(); });
2891*0fca6ea1SDimitry Andric }
2892