xref: /netbsd-src/external/apache2/llvm/dist/clang/lib/AST/TextNodeDumper.cpp (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
17330f729Sjoerg //===--- TextNodeDumper.cpp - Printing of AST nodes -----------------------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This file implements AST dumping of components of individual AST nodes.
107330f729Sjoerg //
117330f729Sjoerg //===----------------------------------------------------------------------===//
127330f729Sjoerg 
137330f729Sjoerg #include "clang/AST/TextNodeDumper.h"
14*e038c9c4Sjoerg #include "clang/AST/APValue.h"
157330f729Sjoerg #include "clang/AST/DeclFriend.h"
167330f729Sjoerg #include "clang/AST/DeclOpenMP.h"
177330f729Sjoerg #include "clang/AST/DeclTemplate.h"
187330f729Sjoerg #include "clang/AST/LocInfoType.h"
19*e038c9c4Sjoerg #include "clang/AST/Type.h"
20*e038c9c4Sjoerg #include "clang/Basic/Module.h"
21*e038c9c4Sjoerg #include "clang/Basic/SourceManager.h"
22*e038c9c4Sjoerg #include "clang/Basic/Specifiers.h"
23*e038c9c4Sjoerg #include "clang/Basic/TypeTraits.h"
24*e038c9c4Sjoerg 
25*e038c9c4Sjoerg #include <algorithm>
26*e038c9c4Sjoerg #include <utility>
277330f729Sjoerg 
287330f729Sjoerg using namespace clang;
297330f729Sjoerg 
dumpPreviousDeclImpl(raw_ostream & OS,...)307330f729Sjoerg static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {}
317330f729Sjoerg 
327330f729Sjoerg template <typename T>
dumpPreviousDeclImpl(raw_ostream & OS,const Mergeable<T> * D)337330f729Sjoerg static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) {
347330f729Sjoerg   const T *First = D->getFirstDecl();
357330f729Sjoerg   if (First != D)
367330f729Sjoerg     OS << " first " << First;
377330f729Sjoerg }
387330f729Sjoerg 
397330f729Sjoerg template <typename T>
dumpPreviousDeclImpl(raw_ostream & OS,const Redeclarable<T> * D)407330f729Sjoerg static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) {
417330f729Sjoerg   const T *Prev = D->getPreviousDecl();
427330f729Sjoerg   if (Prev)
437330f729Sjoerg     OS << " prev " << Prev;
447330f729Sjoerg }
457330f729Sjoerg 
467330f729Sjoerg /// Dump the previous declaration in the redeclaration chain for a declaration,
477330f729Sjoerg /// if any.
dumpPreviousDecl(raw_ostream & OS,const Decl * D)487330f729Sjoerg static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) {
497330f729Sjoerg   switch (D->getKind()) {
507330f729Sjoerg #define DECL(DERIVED, BASE)                                                    \
517330f729Sjoerg   case Decl::DERIVED:                                                          \
527330f729Sjoerg     return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D));
537330f729Sjoerg #define ABSTRACT_DECL(DECL)
547330f729Sjoerg #include "clang/AST/DeclNodes.inc"
557330f729Sjoerg   }
567330f729Sjoerg   llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
577330f729Sjoerg }
587330f729Sjoerg 
TextNodeDumper(raw_ostream & OS,const ASTContext & Context,bool ShowColors)59*e038c9c4Sjoerg TextNodeDumper::TextNodeDumper(raw_ostream &OS, const ASTContext &Context,
60*e038c9c4Sjoerg                                bool ShowColors)
61*e038c9c4Sjoerg     : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors),
62*e038c9c4Sjoerg       Context(&Context), SM(&Context.getSourceManager()),
63*e038c9c4Sjoerg       PrintPolicy(Context.getPrintingPolicy()),
64*e038c9c4Sjoerg       Traits(&Context.getCommentCommandTraits()) {}
65*e038c9c4Sjoerg 
TextNodeDumper(raw_ostream & OS,bool ShowColors)66*e038c9c4Sjoerg TextNodeDumper::TextNodeDumper(raw_ostream &OS, bool ShowColors)
67*e038c9c4Sjoerg     : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors) {}
687330f729Sjoerg 
Visit(const comments::Comment * C,const comments::FullComment * FC)697330f729Sjoerg void TextNodeDumper::Visit(const comments::Comment *C,
707330f729Sjoerg                            const comments::FullComment *FC) {
717330f729Sjoerg   if (!C) {
727330f729Sjoerg     ColorScope Color(OS, ShowColors, NullColor);
737330f729Sjoerg     OS << "<<<NULL>>>";
747330f729Sjoerg     return;
757330f729Sjoerg   }
767330f729Sjoerg 
777330f729Sjoerg   {
787330f729Sjoerg     ColorScope Color(OS, ShowColors, CommentColor);
797330f729Sjoerg     OS << C->getCommentKindName();
807330f729Sjoerg   }
817330f729Sjoerg   dumpPointer(C);
827330f729Sjoerg   dumpSourceRange(C->getSourceRange());
837330f729Sjoerg 
847330f729Sjoerg   ConstCommentVisitor<TextNodeDumper, void,
857330f729Sjoerg                       const comments::FullComment *>::visit(C, FC);
867330f729Sjoerg }
877330f729Sjoerg 
Visit(const Attr * A)887330f729Sjoerg void TextNodeDumper::Visit(const Attr *A) {
897330f729Sjoerg   {
907330f729Sjoerg     ColorScope Color(OS, ShowColors, AttrColor);
917330f729Sjoerg 
927330f729Sjoerg     switch (A->getKind()) {
937330f729Sjoerg #define ATTR(X)                                                                \
947330f729Sjoerg   case attr::X:                                                                \
957330f729Sjoerg     OS << #X;                                                                  \
967330f729Sjoerg     break;
977330f729Sjoerg #include "clang/Basic/AttrList.inc"
987330f729Sjoerg     }
997330f729Sjoerg     OS << "Attr";
1007330f729Sjoerg   }
1017330f729Sjoerg   dumpPointer(A);
1027330f729Sjoerg   dumpSourceRange(A->getRange());
1037330f729Sjoerg   if (A->isInherited())
1047330f729Sjoerg     OS << " Inherited";
1057330f729Sjoerg   if (A->isImplicit())
1067330f729Sjoerg     OS << " Implicit";
1077330f729Sjoerg 
1087330f729Sjoerg   ConstAttrVisitor<TextNodeDumper>::Visit(A);
1097330f729Sjoerg }
1107330f729Sjoerg 
Visit(const TemplateArgument & TA,SourceRange R,const Decl * From,StringRef Label)1117330f729Sjoerg void TextNodeDumper::Visit(const TemplateArgument &TA, SourceRange R,
1127330f729Sjoerg                            const Decl *From, StringRef Label) {
1137330f729Sjoerg   OS << "TemplateArgument";
1147330f729Sjoerg   if (R.isValid())
1157330f729Sjoerg     dumpSourceRange(R);
1167330f729Sjoerg 
1177330f729Sjoerg   if (From)
1187330f729Sjoerg     dumpDeclRef(From, Label);
1197330f729Sjoerg 
1207330f729Sjoerg   ConstTemplateArgumentVisitor<TextNodeDumper>::Visit(TA);
1217330f729Sjoerg }
1227330f729Sjoerg 
Visit(const Stmt * Node)1237330f729Sjoerg void TextNodeDumper::Visit(const Stmt *Node) {
1247330f729Sjoerg   if (!Node) {
1257330f729Sjoerg     ColorScope Color(OS, ShowColors, NullColor);
1267330f729Sjoerg     OS << "<<<NULL>>>";
1277330f729Sjoerg     return;
1287330f729Sjoerg   }
1297330f729Sjoerg   {
1307330f729Sjoerg     ColorScope Color(OS, ShowColors, StmtColor);
1317330f729Sjoerg     OS << Node->getStmtClassName();
1327330f729Sjoerg   }
1337330f729Sjoerg   dumpPointer(Node);
1347330f729Sjoerg   dumpSourceRange(Node->getSourceRange());
1357330f729Sjoerg 
1367330f729Sjoerg   if (const auto *E = dyn_cast<Expr>(Node)) {
1377330f729Sjoerg     dumpType(E->getType());
1387330f729Sjoerg 
139*e038c9c4Sjoerg     if (E->containsErrors()) {
140*e038c9c4Sjoerg       ColorScope Color(OS, ShowColors, ErrorsColor);
141*e038c9c4Sjoerg       OS << " contains-errors";
142*e038c9c4Sjoerg     }
143*e038c9c4Sjoerg 
1447330f729Sjoerg     {
1457330f729Sjoerg       ColorScope Color(OS, ShowColors, ValueKindColor);
1467330f729Sjoerg       switch (E->getValueKind()) {
1477330f729Sjoerg       case VK_RValue:
1487330f729Sjoerg         break;
1497330f729Sjoerg       case VK_LValue:
1507330f729Sjoerg         OS << " lvalue";
1517330f729Sjoerg         break;
1527330f729Sjoerg       case VK_XValue:
1537330f729Sjoerg         OS << " xvalue";
1547330f729Sjoerg         break;
1557330f729Sjoerg       }
1567330f729Sjoerg     }
1577330f729Sjoerg 
1587330f729Sjoerg     {
1597330f729Sjoerg       ColorScope Color(OS, ShowColors, ObjectKindColor);
1607330f729Sjoerg       switch (E->getObjectKind()) {
1617330f729Sjoerg       case OK_Ordinary:
1627330f729Sjoerg         break;
1637330f729Sjoerg       case OK_BitField:
1647330f729Sjoerg         OS << " bitfield";
1657330f729Sjoerg         break;
1667330f729Sjoerg       case OK_ObjCProperty:
1677330f729Sjoerg         OS << " objcproperty";
1687330f729Sjoerg         break;
1697330f729Sjoerg       case OK_ObjCSubscript:
1707330f729Sjoerg         OS << " objcsubscript";
1717330f729Sjoerg         break;
1727330f729Sjoerg       case OK_VectorComponent:
1737330f729Sjoerg         OS << " vectorcomponent";
1747330f729Sjoerg         break;
175*e038c9c4Sjoerg       case OK_MatrixComponent:
176*e038c9c4Sjoerg         OS << " matrixcomponent";
177*e038c9c4Sjoerg         break;
1787330f729Sjoerg       }
1797330f729Sjoerg     }
1807330f729Sjoerg   }
1817330f729Sjoerg 
1827330f729Sjoerg   ConstStmtVisitor<TextNodeDumper>::Visit(Node);
1837330f729Sjoerg }
1847330f729Sjoerg 
Visit(const Type * T)1857330f729Sjoerg void TextNodeDumper::Visit(const Type *T) {
1867330f729Sjoerg   if (!T) {
1877330f729Sjoerg     ColorScope Color(OS, ShowColors, NullColor);
1887330f729Sjoerg     OS << "<<<NULL>>>";
1897330f729Sjoerg     return;
1907330f729Sjoerg   }
1917330f729Sjoerg   if (isa<LocInfoType>(T)) {
1927330f729Sjoerg     {
1937330f729Sjoerg       ColorScope Color(OS, ShowColors, TypeColor);
1947330f729Sjoerg       OS << "LocInfo Type";
1957330f729Sjoerg     }
1967330f729Sjoerg     dumpPointer(T);
1977330f729Sjoerg     return;
1987330f729Sjoerg   }
1997330f729Sjoerg 
2007330f729Sjoerg   {
2017330f729Sjoerg     ColorScope Color(OS, ShowColors, TypeColor);
2027330f729Sjoerg     OS << T->getTypeClassName() << "Type";
2037330f729Sjoerg   }
2047330f729Sjoerg   dumpPointer(T);
2057330f729Sjoerg   OS << " ";
2067330f729Sjoerg   dumpBareType(QualType(T, 0), false);
2077330f729Sjoerg 
2087330f729Sjoerg   QualType SingleStepDesugar =
2097330f729Sjoerg       T->getLocallyUnqualifiedSingleStepDesugaredType();
2107330f729Sjoerg   if (SingleStepDesugar != QualType(T, 0))
2117330f729Sjoerg     OS << " sugar";
2127330f729Sjoerg 
213*e038c9c4Sjoerg   if (T->containsErrors()) {
214*e038c9c4Sjoerg     ColorScope Color(OS, ShowColors, ErrorsColor);
215*e038c9c4Sjoerg     OS << " contains-errors";
216*e038c9c4Sjoerg   }
217*e038c9c4Sjoerg 
2187330f729Sjoerg   if (T->isDependentType())
2197330f729Sjoerg     OS << " dependent";
2207330f729Sjoerg   else if (T->isInstantiationDependentType())
2217330f729Sjoerg     OS << " instantiation_dependent";
2227330f729Sjoerg 
2237330f729Sjoerg   if (T->isVariablyModifiedType())
2247330f729Sjoerg     OS << " variably_modified";
2257330f729Sjoerg   if (T->containsUnexpandedParameterPack())
2267330f729Sjoerg     OS << " contains_unexpanded_pack";
2277330f729Sjoerg   if (T->isFromAST())
2287330f729Sjoerg     OS << " imported";
2297330f729Sjoerg 
2307330f729Sjoerg   TypeVisitor<TextNodeDumper>::Visit(T);
2317330f729Sjoerg }
2327330f729Sjoerg 
Visit(QualType T)2337330f729Sjoerg void TextNodeDumper::Visit(QualType T) {
2347330f729Sjoerg   OS << "QualType";
2357330f729Sjoerg   dumpPointer(T.getAsOpaquePtr());
2367330f729Sjoerg   OS << " ";
2377330f729Sjoerg   dumpBareType(T, false);
2387330f729Sjoerg   OS << " " << T.split().Quals.getAsString();
2397330f729Sjoerg }
2407330f729Sjoerg 
Visit(const Decl * D)2417330f729Sjoerg void TextNodeDumper::Visit(const Decl *D) {
2427330f729Sjoerg   if (!D) {
2437330f729Sjoerg     ColorScope Color(OS, ShowColors, NullColor);
2447330f729Sjoerg     OS << "<<<NULL>>>";
2457330f729Sjoerg     return;
2467330f729Sjoerg   }
2477330f729Sjoerg 
2487330f729Sjoerg   {
2497330f729Sjoerg     ColorScope Color(OS, ShowColors, DeclKindNameColor);
2507330f729Sjoerg     OS << D->getDeclKindName() << "Decl";
2517330f729Sjoerg   }
2527330f729Sjoerg   dumpPointer(D);
2537330f729Sjoerg   if (D->getLexicalDeclContext() != D->getDeclContext())
2547330f729Sjoerg     OS << " parent " << cast<Decl>(D->getDeclContext());
2557330f729Sjoerg   dumpPreviousDecl(OS, D);
2567330f729Sjoerg   dumpSourceRange(D->getSourceRange());
2577330f729Sjoerg   OS << ' ';
2587330f729Sjoerg   dumpLocation(D->getLocation());
2597330f729Sjoerg   if (D->isFromASTFile())
2607330f729Sjoerg     OS << " imported";
2617330f729Sjoerg   if (Module *M = D->getOwningModule())
2627330f729Sjoerg     OS << " in " << M->getFullModuleName();
2637330f729Sjoerg   if (auto *ND = dyn_cast<NamedDecl>(D))
2647330f729Sjoerg     for (Module *M : D->getASTContext().getModulesWithMergedDefinition(
2657330f729Sjoerg              const_cast<NamedDecl *>(ND)))
2667330f729Sjoerg       AddChild([=] { OS << "also in " << M->getFullModuleName(); });
2677330f729Sjoerg   if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
268*e038c9c4Sjoerg     if (!ND->isUnconditionallyVisible())
2697330f729Sjoerg       OS << " hidden";
2707330f729Sjoerg   if (D->isImplicit())
2717330f729Sjoerg     OS << " implicit";
2727330f729Sjoerg 
2737330f729Sjoerg   if (D->isUsed())
2747330f729Sjoerg     OS << " used";
2757330f729Sjoerg   else if (D->isThisDeclarationReferenced())
2767330f729Sjoerg     OS << " referenced";
2777330f729Sjoerg 
2787330f729Sjoerg   if (D->isInvalidDecl())
2797330f729Sjoerg     OS << " invalid";
2807330f729Sjoerg   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
2817330f729Sjoerg     if (FD->isConstexprSpecified())
2827330f729Sjoerg       OS << " constexpr";
2837330f729Sjoerg     if (FD->isConsteval())
2847330f729Sjoerg       OS << " consteval";
2857330f729Sjoerg   }
2867330f729Sjoerg 
2877330f729Sjoerg   if (!isa<FunctionDecl>(*D)) {
2887330f729Sjoerg     const auto *MD = dyn_cast<ObjCMethodDecl>(D);
2897330f729Sjoerg     if (!MD || !MD->isThisDeclarationADefinition()) {
2907330f729Sjoerg       const auto *DC = dyn_cast<DeclContext>(D);
2917330f729Sjoerg       if (DC && DC->hasExternalLexicalStorage()) {
2927330f729Sjoerg         ColorScope Color(OS, ShowColors, UndeserializedColor);
2937330f729Sjoerg         OS << " <undeserialized declarations>";
2947330f729Sjoerg       }
2957330f729Sjoerg     }
2967330f729Sjoerg   }
2977330f729Sjoerg 
2987330f729Sjoerg   ConstDeclVisitor<TextNodeDumper>::Visit(D);
2997330f729Sjoerg }
3007330f729Sjoerg 
Visit(const CXXCtorInitializer * Init)3017330f729Sjoerg void TextNodeDumper::Visit(const CXXCtorInitializer *Init) {
3027330f729Sjoerg   OS << "CXXCtorInitializer";
3037330f729Sjoerg   if (Init->isAnyMemberInitializer()) {
3047330f729Sjoerg     OS << ' ';
3057330f729Sjoerg     dumpBareDeclRef(Init->getAnyMember());
3067330f729Sjoerg   } else if (Init->isBaseInitializer()) {
3077330f729Sjoerg     dumpType(QualType(Init->getBaseClass(), 0));
3087330f729Sjoerg   } else if (Init->isDelegatingInitializer()) {
3097330f729Sjoerg     dumpType(Init->getTypeSourceInfo()->getType());
3107330f729Sjoerg   } else {
3117330f729Sjoerg     llvm_unreachable("Unknown initializer type");
3127330f729Sjoerg   }
3137330f729Sjoerg }
3147330f729Sjoerg 
Visit(const BlockDecl::Capture & C)3157330f729Sjoerg void TextNodeDumper::Visit(const BlockDecl::Capture &C) {
3167330f729Sjoerg   OS << "capture";
3177330f729Sjoerg   if (C.isByRef())
3187330f729Sjoerg     OS << " byref";
3197330f729Sjoerg   if (C.isNested())
3207330f729Sjoerg     OS << " nested";
3217330f729Sjoerg   if (C.getVariable()) {
3227330f729Sjoerg     OS << ' ';
3237330f729Sjoerg     dumpBareDeclRef(C.getVariable());
3247330f729Sjoerg   }
3257330f729Sjoerg }
3267330f729Sjoerg 
Visit(const OMPClause * C)3277330f729Sjoerg void TextNodeDumper::Visit(const OMPClause *C) {
3287330f729Sjoerg   if (!C) {
3297330f729Sjoerg     ColorScope Color(OS, ShowColors, NullColor);
3307330f729Sjoerg     OS << "<<<NULL>>> OMPClause";
3317330f729Sjoerg     return;
3327330f729Sjoerg   }
3337330f729Sjoerg   {
3347330f729Sjoerg     ColorScope Color(OS, ShowColors, AttrColor);
335*e038c9c4Sjoerg     StringRef ClauseName(llvm::omp::getOpenMPClauseName(C->getClauseKind()));
3367330f729Sjoerg     OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
3377330f729Sjoerg        << ClauseName.drop_front() << "Clause";
3387330f729Sjoerg   }
3397330f729Sjoerg   dumpPointer(C);
3407330f729Sjoerg   dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
3417330f729Sjoerg   if (C->isImplicit())
3427330f729Sjoerg     OS << " <implicit>";
3437330f729Sjoerg }
3447330f729Sjoerg 
Visit(const GenericSelectionExpr::ConstAssociation & A)3457330f729Sjoerg void TextNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) {
3467330f729Sjoerg   const TypeSourceInfo *TSI = A.getTypeSourceInfo();
3477330f729Sjoerg   if (TSI) {
3487330f729Sjoerg     OS << "case ";
3497330f729Sjoerg     dumpType(TSI->getType());
3507330f729Sjoerg   } else {
3517330f729Sjoerg     OS << "default";
3527330f729Sjoerg   }
3537330f729Sjoerg 
3547330f729Sjoerg   if (A.isSelected())
3557330f729Sjoerg     OS << " selected";
3567330f729Sjoerg }
3577330f729Sjoerg 
GetApproxValue(const llvm::APFloat & F)358*e038c9c4Sjoerg static double GetApproxValue(const llvm::APFloat &F) {
359*e038c9c4Sjoerg   llvm::APFloat V = F;
360*e038c9c4Sjoerg   bool ignored;
361*e038c9c4Sjoerg   V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven,
362*e038c9c4Sjoerg             &ignored);
363*e038c9c4Sjoerg   return V.convertToDouble();
364*e038c9c4Sjoerg }
365*e038c9c4Sjoerg 
366*e038c9c4Sjoerg /// True if the \p APValue \p Value can be folded onto the current line.
isSimpleAPValue(const APValue & Value)367*e038c9c4Sjoerg static bool isSimpleAPValue(const APValue &Value) {
368*e038c9c4Sjoerg   switch (Value.getKind()) {
369*e038c9c4Sjoerg   case APValue::None:
370*e038c9c4Sjoerg   case APValue::Indeterminate:
371*e038c9c4Sjoerg   case APValue::Int:
372*e038c9c4Sjoerg   case APValue::Float:
373*e038c9c4Sjoerg   case APValue::FixedPoint:
374*e038c9c4Sjoerg   case APValue::ComplexInt:
375*e038c9c4Sjoerg   case APValue::ComplexFloat:
376*e038c9c4Sjoerg   case APValue::LValue:
377*e038c9c4Sjoerg   case APValue::MemberPointer:
378*e038c9c4Sjoerg   case APValue::AddrLabelDiff:
379*e038c9c4Sjoerg     return true;
380*e038c9c4Sjoerg   case APValue::Vector:
381*e038c9c4Sjoerg   case APValue::Array:
382*e038c9c4Sjoerg   case APValue::Struct:
383*e038c9c4Sjoerg     return false;
384*e038c9c4Sjoerg   case APValue::Union:
385*e038c9c4Sjoerg     return isSimpleAPValue(Value.getUnionValue());
386*e038c9c4Sjoerg   }
387*e038c9c4Sjoerg   llvm_unreachable("unexpected APValue kind!");
388*e038c9c4Sjoerg }
389*e038c9c4Sjoerg 
390*e038c9c4Sjoerg /// Dump the children of the \p APValue \p Value.
391*e038c9c4Sjoerg ///
392*e038c9c4Sjoerg /// \param[in] Value          The \p APValue to visit
393*e038c9c4Sjoerg /// \param[in] Ty             The \p QualType passed to \p Visit
394*e038c9c4Sjoerg ///
395*e038c9c4Sjoerg /// \param[in] IdxToChildFun  A function mapping an \p APValue and an index
396*e038c9c4Sjoerg ///                           to one of the child of the \p APValue
397*e038c9c4Sjoerg ///
398*e038c9c4Sjoerg /// \param[in] NumChildren    \p IdxToChildFun will be called on \p Value with
399*e038c9c4Sjoerg ///                           the indices in the range \p [0,NumChildren(
400*e038c9c4Sjoerg ///
401*e038c9c4Sjoerg /// \param[in] LabelSingular  The label to use on a line with a single child
402*e038c9c4Sjoerg /// \param[in] LabelPlurial   The label to use on a line with multiple children
dumpAPValueChildren(const APValue & Value,QualType Ty,const APValue & (* IdxToChildFun)(const APValue &,unsigned),unsigned NumChildren,StringRef LabelSingular,StringRef LabelPlurial)403*e038c9c4Sjoerg void TextNodeDumper::dumpAPValueChildren(
404*e038c9c4Sjoerg     const APValue &Value, QualType Ty,
405*e038c9c4Sjoerg     const APValue &(*IdxToChildFun)(const APValue &, unsigned),
406*e038c9c4Sjoerg     unsigned NumChildren, StringRef LabelSingular, StringRef LabelPlurial) {
407*e038c9c4Sjoerg   // To save some vertical space we print up to MaxChildrenPerLine APValues
408*e038c9c4Sjoerg   // considered to be simple (by isSimpleAPValue) on a single line.
409*e038c9c4Sjoerg   constexpr unsigned MaxChildrenPerLine = 4;
410*e038c9c4Sjoerg   unsigned I = 0;
411*e038c9c4Sjoerg   while (I < NumChildren) {
412*e038c9c4Sjoerg     unsigned J = I;
413*e038c9c4Sjoerg     while (J < NumChildren) {
414*e038c9c4Sjoerg       if (isSimpleAPValue(IdxToChildFun(Value, J)) &&
415*e038c9c4Sjoerg           (J - I < MaxChildrenPerLine)) {
416*e038c9c4Sjoerg         ++J;
417*e038c9c4Sjoerg         continue;
418*e038c9c4Sjoerg       }
419*e038c9c4Sjoerg       break;
420*e038c9c4Sjoerg     }
421*e038c9c4Sjoerg 
422*e038c9c4Sjoerg     J = std::max(I + 1, J);
423*e038c9c4Sjoerg 
424*e038c9c4Sjoerg     // Print [I,J) on a single line.
425*e038c9c4Sjoerg     AddChild(J - I > 1 ? LabelPlurial : LabelSingular, [=]() {
426*e038c9c4Sjoerg       for (unsigned X = I; X < J; ++X) {
427*e038c9c4Sjoerg         Visit(IdxToChildFun(Value, X), Ty);
428*e038c9c4Sjoerg         if (X + 1 != J)
429*e038c9c4Sjoerg           OS << ", ";
430*e038c9c4Sjoerg       }
431*e038c9c4Sjoerg     });
432*e038c9c4Sjoerg     I = J;
433*e038c9c4Sjoerg   }
434*e038c9c4Sjoerg }
435*e038c9c4Sjoerg 
Visit(const APValue & Value,QualType Ty)436*e038c9c4Sjoerg void TextNodeDumper::Visit(const APValue &Value, QualType Ty) {
437*e038c9c4Sjoerg   ColorScope Color(OS, ShowColors, ValueKindColor);
438*e038c9c4Sjoerg   switch (Value.getKind()) {
439*e038c9c4Sjoerg   case APValue::None:
440*e038c9c4Sjoerg     OS << "None";
441*e038c9c4Sjoerg     return;
442*e038c9c4Sjoerg   case APValue::Indeterminate:
443*e038c9c4Sjoerg     OS << "Indeterminate";
444*e038c9c4Sjoerg     return;
445*e038c9c4Sjoerg   case APValue::Int:
446*e038c9c4Sjoerg     OS << "Int ";
447*e038c9c4Sjoerg     {
448*e038c9c4Sjoerg       ColorScope Color(OS, ShowColors, ValueColor);
449*e038c9c4Sjoerg       OS << Value.getInt();
450*e038c9c4Sjoerg     }
451*e038c9c4Sjoerg     return;
452*e038c9c4Sjoerg   case APValue::Float:
453*e038c9c4Sjoerg     OS << "Float ";
454*e038c9c4Sjoerg     {
455*e038c9c4Sjoerg       ColorScope Color(OS, ShowColors, ValueColor);
456*e038c9c4Sjoerg       OS << GetApproxValue(Value.getFloat());
457*e038c9c4Sjoerg     }
458*e038c9c4Sjoerg     return;
459*e038c9c4Sjoerg   case APValue::FixedPoint:
460*e038c9c4Sjoerg     OS << "FixedPoint ";
461*e038c9c4Sjoerg     {
462*e038c9c4Sjoerg       ColorScope Color(OS, ShowColors, ValueColor);
463*e038c9c4Sjoerg       OS << Value.getFixedPoint();
464*e038c9c4Sjoerg     }
465*e038c9c4Sjoerg     return;
466*e038c9c4Sjoerg   case APValue::Vector: {
467*e038c9c4Sjoerg     unsigned VectorLength = Value.getVectorLength();
468*e038c9c4Sjoerg     OS << "Vector length=" << VectorLength;
469*e038c9c4Sjoerg 
470*e038c9c4Sjoerg     dumpAPValueChildren(
471*e038c9c4Sjoerg         Value, Ty,
472*e038c9c4Sjoerg         [](const APValue &Value, unsigned Index) -> const APValue & {
473*e038c9c4Sjoerg           return Value.getVectorElt(Index);
474*e038c9c4Sjoerg         },
475*e038c9c4Sjoerg         VectorLength, "element", "elements");
476*e038c9c4Sjoerg     return;
477*e038c9c4Sjoerg   }
478*e038c9c4Sjoerg   case APValue::ComplexInt:
479*e038c9c4Sjoerg     OS << "ComplexInt ";
480*e038c9c4Sjoerg     {
481*e038c9c4Sjoerg       ColorScope Color(OS, ShowColors, ValueColor);
482*e038c9c4Sjoerg       OS << Value.getComplexIntReal() << " + " << Value.getComplexIntImag()
483*e038c9c4Sjoerg          << 'i';
484*e038c9c4Sjoerg     }
485*e038c9c4Sjoerg     return;
486*e038c9c4Sjoerg   case APValue::ComplexFloat:
487*e038c9c4Sjoerg     OS << "ComplexFloat ";
488*e038c9c4Sjoerg     {
489*e038c9c4Sjoerg       ColorScope Color(OS, ShowColors, ValueColor);
490*e038c9c4Sjoerg       OS << GetApproxValue(Value.getComplexFloatReal()) << " + "
491*e038c9c4Sjoerg          << GetApproxValue(Value.getComplexFloatImag()) << 'i';
492*e038c9c4Sjoerg     }
493*e038c9c4Sjoerg     return;
494*e038c9c4Sjoerg   case APValue::LValue:
495*e038c9c4Sjoerg     (void)Context;
496*e038c9c4Sjoerg     OS << "LValue <todo>";
497*e038c9c4Sjoerg     return;
498*e038c9c4Sjoerg   case APValue::Array: {
499*e038c9c4Sjoerg     unsigned ArraySize = Value.getArraySize();
500*e038c9c4Sjoerg     unsigned NumInitializedElements = Value.getArrayInitializedElts();
501*e038c9c4Sjoerg     OS << "Array size=" << ArraySize;
502*e038c9c4Sjoerg 
503*e038c9c4Sjoerg     dumpAPValueChildren(
504*e038c9c4Sjoerg         Value, Ty,
505*e038c9c4Sjoerg         [](const APValue &Value, unsigned Index) -> const APValue & {
506*e038c9c4Sjoerg           return Value.getArrayInitializedElt(Index);
507*e038c9c4Sjoerg         },
508*e038c9c4Sjoerg         NumInitializedElements, "element", "elements");
509*e038c9c4Sjoerg 
510*e038c9c4Sjoerg     if (Value.hasArrayFiller()) {
511*e038c9c4Sjoerg       AddChild("filler", [=] {
512*e038c9c4Sjoerg         {
513*e038c9c4Sjoerg           ColorScope Color(OS, ShowColors, ValueColor);
514*e038c9c4Sjoerg           OS << ArraySize - NumInitializedElements << " x ";
515*e038c9c4Sjoerg         }
516*e038c9c4Sjoerg         Visit(Value.getArrayFiller(), Ty);
517*e038c9c4Sjoerg       });
518*e038c9c4Sjoerg     }
519*e038c9c4Sjoerg 
520*e038c9c4Sjoerg     return;
521*e038c9c4Sjoerg   }
522*e038c9c4Sjoerg   case APValue::Struct: {
523*e038c9c4Sjoerg     OS << "Struct";
524*e038c9c4Sjoerg 
525*e038c9c4Sjoerg     dumpAPValueChildren(
526*e038c9c4Sjoerg         Value, Ty,
527*e038c9c4Sjoerg         [](const APValue &Value, unsigned Index) -> const APValue & {
528*e038c9c4Sjoerg           return Value.getStructBase(Index);
529*e038c9c4Sjoerg         },
530*e038c9c4Sjoerg         Value.getStructNumBases(), "base", "bases");
531*e038c9c4Sjoerg 
532*e038c9c4Sjoerg     dumpAPValueChildren(
533*e038c9c4Sjoerg         Value, Ty,
534*e038c9c4Sjoerg         [](const APValue &Value, unsigned Index) -> const APValue & {
535*e038c9c4Sjoerg           return Value.getStructField(Index);
536*e038c9c4Sjoerg         },
537*e038c9c4Sjoerg         Value.getStructNumFields(), "field", "fields");
538*e038c9c4Sjoerg 
539*e038c9c4Sjoerg     return;
540*e038c9c4Sjoerg   }
541*e038c9c4Sjoerg   case APValue::Union: {
542*e038c9c4Sjoerg     OS << "Union";
543*e038c9c4Sjoerg     {
544*e038c9c4Sjoerg       ColorScope Color(OS, ShowColors, ValueColor);
545*e038c9c4Sjoerg       if (const FieldDecl *FD = Value.getUnionField())
546*e038c9c4Sjoerg         OS << " ." << *cast<NamedDecl>(FD);
547*e038c9c4Sjoerg     }
548*e038c9c4Sjoerg     // If the union value is considered to be simple, fold it into the
549*e038c9c4Sjoerg     // current line to save some vertical space.
550*e038c9c4Sjoerg     const APValue &UnionValue = Value.getUnionValue();
551*e038c9c4Sjoerg     if (isSimpleAPValue(UnionValue)) {
552*e038c9c4Sjoerg       OS << ' ';
553*e038c9c4Sjoerg       Visit(UnionValue, Ty);
554*e038c9c4Sjoerg     } else {
555*e038c9c4Sjoerg       AddChild([=] { Visit(UnionValue, Ty); });
556*e038c9c4Sjoerg     }
557*e038c9c4Sjoerg 
558*e038c9c4Sjoerg     return;
559*e038c9c4Sjoerg   }
560*e038c9c4Sjoerg   case APValue::MemberPointer:
561*e038c9c4Sjoerg     OS << "MemberPointer <todo>";
562*e038c9c4Sjoerg     return;
563*e038c9c4Sjoerg   case APValue::AddrLabelDiff:
564*e038c9c4Sjoerg     OS << "AddrLabelDiff <todo>";
565*e038c9c4Sjoerg     return;
566*e038c9c4Sjoerg   }
567*e038c9c4Sjoerg   llvm_unreachable("Unknown APValue kind!");
568*e038c9c4Sjoerg }
569*e038c9c4Sjoerg 
dumpPointer(const void * Ptr)5707330f729Sjoerg void TextNodeDumper::dumpPointer(const void *Ptr) {
5717330f729Sjoerg   ColorScope Color(OS, ShowColors, AddressColor);
5727330f729Sjoerg   OS << ' ' << Ptr;
5737330f729Sjoerg }
5747330f729Sjoerg 
dumpLocation(SourceLocation Loc)5757330f729Sjoerg void TextNodeDumper::dumpLocation(SourceLocation Loc) {
5767330f729Sjoerg   if (!SM)
5777330f729Sjoerg     return;
5787330f729Sjoerg 
5797330f729Sjoerg   ColorScope Color(OS, ShowColors, LocationColor);
5807330f729Sjoerg   SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
5817330f729Sjoerg 
5827330f729Sjoerg   // The general format we print out is filename:line:col, but we drop pieces
5837330f729Sjoerg   // that haven't changed since the last loc printed.
5847330f729Sjoerg   PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
5857330f729Sjoerg 
5867330f729Sjoerg   if (PLoc.isInvalid()) {
5877330f729Sjoerg     OS << "<invalid sloc>";
5887330f729Sjoerg     return;
5897330f729Sjoerg   }
5907330f729Sjoerg 
5917330f729Sjoerg   if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
5927330f729Sjoerg     OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':'
5937330f729Sjoerg        << PLoc.getColumn();
5947330f729Sjoerg     LastLocFilename = PLoc.getFilename();
5957330f729Sjoerg     LastLocLine = PLoc.getLine();
5967330f729Sjoerg   } else if (PLoc.getLine() != LastLocLine) {
5977330f729Sjoerg     OS << "line" << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
5987330f729Sjoerg     LastLocLine = PLoc.getLine();
5997330f729Sjoerg   } else {
6007330f729Sjoerg     OS << "col" << ':' << PLoc.getColumn();
6017330f729Sjoerg   }
6027330f729Sjoerg }
6037330f729Sjoerg 
dumpSourceRange(SourceRange R)6047330f729Sjoerg void TextNodeDumper::dumpSourceRange(SourceRange R) {
6057330f729Sjoerg   // Can't translate locations if a SourceManager isn't available.
6067330f729Sjoerg   if (!SM)
6077330f729Sjoerg     return;
6087330f729Sjoerg 
6097330f729Sjoerg   OS << " <";
6107330f729Sjoerg   dumpLocation(R.getBegin());
6117330f729Sjoerg   if (R.getBegin() != R.getEnd()) {
6127330f729Sjoerg     OS << ", ";
6137330f729Sjoerg     dumpLocation(R.getEnd());
6147330f729Sjoerg   }
6157330f729Sjoerg   OS << ">";
6167330f729Sjoerg 
6177330f729Sjoerg   // <t2.c:123:421[blah], t2.c:412:321>
6187330f729Sjoerg }
6197330f729Sjoerg 
dumpBareType(QualType T,bool Desugar)6207330f729Sjoerg void TextNodeDumper::dumpBareType(QualType T, bool Desugar) {
6217330f729Sjoerg   ColorScope Color(OS, ShowColors, TypeColor);
6227330f729Sjoerg 
6237330f729Sjoerg   SplitQualType T_split = T.split();
6247330f729Sjoerg   OS << "'" << QualType::getAsString(T_split, PrintPolicy) << "'";
6257330f729Sjoerg 
6267330f729Sjoerg   if (Desugar && !T.isNull()) {
6277330f729Sjoerg     // If the type is sugared, also dump a (shallow) desugared type.
6287330f729Sjoerg     SplitQualType D_split = T.getSplitDesugaredType();
6297330f729Sjoerg     if (T_split != D_split)
6307330f729Sjoerg       OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'";
6317330f729Sjoerg   }
6327330f729Sjoerg }
6337330f729Sjoerg 
dumpType(QualType T)6347330f729Sjoerg void TextNodeDumper::dumpType(QualType T) {
6357330f729Sjoerg   OS << ' ';
6367330f729Sjoerg   dumpBareType(T);
6377330f729Sjoerg }
6387330f729Sjoerg 
dumpBareDeclRef(const Decl * D)6397330f729Sjoerg void TextNodeDumper::dumpBareDeclRef(const Decl *D) {
6407330f729Sjoerg   if (!D) {
6417330f729Sjoerg     ColorScope Color(OS, ShowColors, NullColor);
6427330f729Sjoerg     OS << "<<<NULL>>>";
6437330f729Sjoerg     return;
6447330f729Sjoerg   }
6457330f729Sjoerg 
6467330f729Sjoerg   {
6477330f729Sjoerg     ColorScope Color(OS, ShowColors, DeclKindNameColor);
6487330f729Sjoerg     OS << D->getDeclKindName();
6497330f729Sjoerg   }
6507330f729Sjoerg   dumpPointer(D);
6517330f729Sjoerg 
6527330f729Sjoerg   if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
6537330f729Sjoerg     ColorScope Color(OS, ShowColors, DeclNameColor);
6547330f729Sjoerg     OS << " '" << ND->getDeclName() << '\'';
6557330f729Sjoerg   }
6567330f729Sjoerg 
6577330f729Sjoerg   if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
6587330f729Sjoerg     dumpType(VD->getType());
6597330f729Sjoerg }
6607330f729Sjoerg 
dumpName(const NamedDecl * ND)6617330f729Sjoerg void TextNodeDumper::dumpName(const NamedDecl *ND) {
6627330f729Sjoerg   if (ND->getDeclName()) {
6637330f729Sjoerg     ColorScope Color(OS, ShowColors, DeclNameColor);
664*e038c9c4Sjoerg     OS << ' ' << ND->getDeclName();
6657330f729Sjoerg   }
6667330f729Sjoerg }
6677330f729Sjoerg 
dumpAccessSpecifier(AccessSpecifier AS)6687330f729Sjoerg void TextNodeDumper::dumpAccessSpecifier(AccessSpecifier AS) {
669*e038c9c4Sjoerg   const auto AccessSpelling = getAccessSpelling(AS);
670*e038c9c4Sjoerg   if (AccessSpelling.empty())
671*e038c9c4Sjoerg     return;
672*e038c9c4Sjoerg   OS << AccessSpelling;
6737330f729Sjoerg }
674*e038c9c4Sjoerg 
dumpCleanupObject(const ExprWithCleanups::CleanupObject & C)675*e038c9c4Sjoerg void TextNodeDumper::dumpCleanupObject(
676*e038c9c4Sjoerg     const ExprWithCleanups::CleanupObject &C) {
677*e038c9c4Sjoerg   if (auto *BD = C.dyn_cast<BlockDecl *>())
678*e038c9c4Sjoerg     dumpDeclRef(BD, "cleanup");
679*e038c9c4Sjoerg   else if (auto *CLE = C.dyn_cast<CompoundLiteralExpr *>())
680*e038c9c4Sjoerg     AddChild([=] {
681*e038c9c4Sjoerg       OS << "cleanup ";
682*e038c9c4Sjoerg       {
683*e038c9c4Sjoerg         ColorScope Color(OS, ShowColors, StmtColor);
684*e038c9c4Sjoerg         OS << CLE->getStmtClassName();
685*e038c9c4Sjoerg       }
686*e038c9c4Sjoerg       dumpPointer(CLE);
687*e038c9c4Sjoerg     });
688*e038c9c4Sjoerg   else
689*e038c9c4Sjoerg     llvm_unreachable("unexpected cleanup type");
6907330f729Sjoerg }
6917330f729Sjoerg 
dumpDeclRef(const Decl * D,StringRef Label)6927330f729Sjoerg void TextNodeDumper::dumpDeclRef(const Decl *D, StringRef Label) {
6937330f729Sjoerg   if (!D)
6947330f729Sjoerg     return;
6957330f729Sjoerg 
6967330f729Sjoerg   AddChild([=] {
6977330f729Sjoerg     if (!Label.empty())
6987330f729Sjoerg       OS << Label << ' ';
6997330f729Sjoerg     dumpBareDeclRef(D);
7007330f729Sjoerg   });
7017330f729Sjoerg }
7027330f729Sjoerg 
getCommandName(unsigned CommandID)7037330f729Sjoerg const char *TextNodeDumper::getCommandName(unsigned CommandID) {
7047330f729Sjoerg   if (Traits)
7057330f729Sjoerg     return Traits->getCommandInfo(CommandID)->Name;
7067330f729Sjoerg   const comments::CommandInfo *Info =
7077330f729Sjoerg       comments::CommandTraits::getBuiltinCommandInfo(CommandID);
7087330f729Sjoerg   if (Info)
7097330f729Sjoerg     return Info->Name;
7107330f729Sjoerg   return "<not a builtin command>";
7117330f729Sjoerg }
7127330f729Sjoerg 
printFPOptions(FPOptionsOverride FPO)713*e038c9c4Sjoerg void TextNodeDumper::printFPOptions(FPOptionsOverride FPO) {
714*e038c9c4Sjoerg #define OPTION(NAME, TYPE, WIDTH, PREVIOUS)                                    \
715*e038c9c4Sjoerg   if (FPO.has##NAME##Override())                                               \
716*e038c9c4Sjoerg     OS << " " #NAME "=" << FPO.get##NAME##Override();
717*e038c9c4Sjoerg #include "clang/Basic/FPOptions.def"
718*e038c9c4Sjoerg }
719*e038c9c4Sjoerg 
visitTextComment(const comments::TextComment * C,const comments::FullComment *)7207330f729Sjoerg void TextNodeDumper::visitTextComment(const comments::TextComment *C,
7217330f729Sjoerg                                       const comments::FullComment *) {
7227330f729Sjoerg   OS << " Text=\"" << C->getText() << "\"";
7237330f729Sjoerg }
7247330f729Sjoerg 
visitInlineCommandComment(const comments::InlineCommandComment * C,const comments::FullComment *)7257330f729Sjoerg void TextNodeDumper::visitInlineCommandComment(
7267330f729Sjoerg     const comments::InlineCommandComment *C, const comments::FullComment *) {
7277330f729Sjoerg   OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
7287330f729Sjoerg   switch (C->getRenderKind()) {
7297330f729Sjoerg   case comments::InlineCommandComment::RenderNormal:
7307330f729Sjoerg     OS << " RenderNormal";
7317330f729Sjoerg     break;
7327330f729Sjoerg   case comments::InlineCommandComment::RenderBold:
7337330f729Sjoerg     OS << " RenderBold";
7347330f729Sjoerg     break;
7357330f729Sjoerg   case comments::InlineCommandComment::RenderMonospaced:
7367330f729Sjoerg     OS << " RenderMonospaced";
7377330f729Sjoerg     break;
7387330f729Sjoerg   case comments::InlineCommandComment::RenderEmphasized:
7397330f729Sjoerg     OS << " RenderEmphasized";
7407330f729Sjoerg     break;
741*e038c9c4Sjoerg   case comments::InlineCommandComment::RenderAnchor:
742*e038c9c4Sjoerg     OS << " RenderAnchor";
743*e038c9c4Sjoerg     break;
7447330f729Sjoerg   }
7457330f729Sjoerg 
7467330f729Sjoerg   for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
7477330f729Sjoerg     OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
7487330f729Sjoerg }
7497330f729Sjoerg 
visitHTMLStartTagComment(const comments::HTMLStartTagComment * C,const comments::FullComment *)7507330f729Sjoerg void TextNodeDumper::visitHTMLStartTagComment(
7517330f729Sjoerg     const comments::HTMLStartTagComment *C, const comments::FullComment *) {
7527330f729Sjoerg   OS << " Name=\"" << C->getTagName() << "\"";
7537330f729Sjoerg   if (C->getNumAttrs() != 0) {
7547330f729Sjoerg     OS << " Attrs: ";
7557330f729Sjoerg     for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
7567330f729Sjoerg       const comments::HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
7577330f729Sjoerg       OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
7587330f729Sjoerg     }
7597330f729Sjoerg   }
7607330f729Sjoerg   if (C->isSelfClosing())
7617330f729Sjoerg     OS << " SelfClosing";
7627330f729Sjoerg }
7637330f729Sjoerg 
visitHTMLEndTagComment(const comments::HTMLEndTagComment * C,const comments::FullComment *)7647330f729Sjoerg void TextNodeDumper::visitHTMLEndTagComment(
7657330f729Sjoerg     const comments::HTMLEndTagComment *C, const comments::FullComment *) {
7667330f729Sjoerg   OS << " Name=\"" << C->getTagName() << "\"";
7677330f729Sjoerg }
7687330f729Sjoerg 
visitBlockCommandComment(const comments::BlockCommandComment * C,const comments::FullComment *)7697330f729Sjoerg void TextNodeDumper::visitBlockCommandComment(
7707330f729Sjoerg     const comments::BlockCommandComment *C, const comments::FullComment *) {
7717330f729Sjoerg   OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
7727330f729Sjoerg   for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
7737330f729Sjoerg     OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
7747330f729Sjoerg }
7757330f729Sjoerg 
visitParamCommandComment(const comments::ParamCommandComment * C,const comments::FullComment * FC)7767330f729Sjoerg void TextNodeDumper::visitParamCommandComment(
7777330f729Sjoerg     const comments::ParamCommandComment *C, const comments::FullComment *FC) {
7787330f729Sjoerg   OS << " "
7797330f729Sjoerg      << comments::ParamCommandComment::getDirectionAsString(C->getDirection());
7807330f729Sjoerg 
7817330f729Sjoerg   if (C->isDirectionExplicit())
7827330f729Sjoerg     OS << " explicitly";
7837330f729Sjoerg   else
7847330f729Sjoerg     OS << " implicitly";
7857330f729Sjoerg 
7867330f729Sjoerg   if (C->hasParamName()) {
7877330f729Sjoerg     if (C->isParamIndexValid())
7887330f729Sjoerg       OS << " Param=\"" << C->getParamName(FC) << "\"";
7897330f729Sjoerg     else
7907330f729Sjoerg       OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
7917330f729Sjoerg   }
7927330f729Sjoerg 
7937330f729Sjoerg   if (C->isParamIndexValid() && !C->isVarArgParam())
7947330f729Sjoerg     OS << " ParamIndex=" << C->getParamIndex();
7957330f729Sjoerg }
7967330f729Sjoerg 
visitTParamCommandComment(const comments::TParamCommandComment * C,const comments::FullComment * FC)7977330f729Sjoerg void TextNodeDumper::visitTParamCommandComment(
7987330f729Sjoerg     const comments::TParamCommandComment *C, const comments::FullComment *FC) {
7997330f729Sjoerg   if (C->hasParamName()) {
8007330f729Sjoerg     if (C->isPositionValid())
8017330f729Sjoerg       OS << " Param=\"" << C->getParamName(FC) << "\"";
8027330f729Sjoerg     else
8037330f729Sjoerg       OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
8047330f729Sjoerg   }
8057330f729Sjoerg 
8067330f729Sjoerg   if (C->isPositionValid()) {
8077330f729Sjoerg     OS << " Position=<";
8087330f729Sjoerg     for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
8097330f729Sjoerg       OS << C->getIndex(i);
8107330f729Sjoerg       if (i != e - 1)
8117330f729Sjoerg         OS << ", ";
8127330f729Sjoerg     }
8137330f729Sjoerg     OS << ">";
8147330f729Sjoerg   }
8157330f729Sjoerg }
8167330f729Sjoerg 
visitVerbatimBlockComment(const comments::VerbatimBlockComment * C,const comments::FullComment *)8177330f729Sjoerg void TextNodeDumper::visitVerbatimBlockComment(
8187330f729Sjoerg     const comments::VerbatimBlockComment *C, const comments::FullComment *) {
8197330f729Sjoerg   OS << " Name=\"" << getCommandName(C->getCommandID())
8207330f729Sjoerg      << "\""
8217330f729Sjoerg         " CloseName=\""
8227330f729Sjoerg      << C->getCloseName() << "\"";
8237330f729Sjoerg }
8247330f729Sjoerg 
visitVerbatimBlockLineComment(const comments::VerbatimBlockLineComment * C,const comments::FullComment *)8257330f729Sjoerg void TextNodeDumper::visitVerbatimBlockLineComment(
8267330f729Sjoerg     const comments::VerbatimBlockLineComment *C,
8277330f729Sjoerg     const comments::FullComment *) {
8287330f729Sjoerg   OS << " Text=\"" << C->getText() << "\"";
8297330f729Sjoerg }
8307330f729Sjoerg 
visitVerbatimLineComment(const comments::VerbatimLineComment * C,const comments::FullComment *)8317330f729Sjoerg void TextNodeDumper::visitVerbatimLineComment(
8327330f729Sjoerg     const comments::VerbatimLineComment *C, const comments::FullComment *) {
8337330f729Sjoerg   OS << " Text=\"" << C->getText() << "\"";
8347330f729Sjoerg }
8357330f729Sjoerg 
VisitNullTemplateArgument(const TemplateArgument &)8367330f729Sjoerg void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument &) {
8377330f729Sjoerg   OS << " null";
8387330f729Sjoerg }
8397330f729Sjoerg 
VisitTypeTemplateArgument(const TemplateArgument & TA)8407330f729Sjoerg void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) {
8417330f729Sjoerg   OS << " type";
8427330f729Sjoerg   dumpType(TA.getAsType());
8437330f729Sjoerg }
8447330f729Sjoerg 
VisitDeclarationTemplateArgument(const TemplateArgument & TA)8457330f729Sjoerg void TextNodeDumper::VisitDeclarationTemplateArgument(
8467330f729Sjoerg     const TemplateArgument &TA) {
8477330f729Sjoerg   OS << " decl";
8487330f729Sjoerg   dumpDeclRef(TA.getAsDecl());
8497330f729Sjoerg }
8507330f729Sjoerg 
VisitNullPtrTemplateArgument(const TemplateArgument &)8517330f729Sjoerg void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &) {
8527330f729Sjoerg   OS << " nullptr";
8537330f729Sjoerg }
8547330f729Sjoerg 
VisitIntegralTemplateArgument(const TemplateArgument & TA)8557330f729Sjoerg void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) {
8567330f729Sjoerg   OS << " integral " << TA.getAsIntegral();
8577330f729Sjoerg }
8587330f729Sjoerg 
VisitTemplateTemplateArgument(const TemplateArgument & TA)8597330f729Sjoerg void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) {
8607330f729Sjoerg   OS << " template ";
8617330f729Sjoerg   TA.getAsTemplate().dump(OS);
8627330f729Sjoerg }
8637330f729Sjoerg 
VisitTemplateExpansionTemplateArgument(const TemplateArgument & TA)8647330f729Sjoerg void TextNodeDumper::VisitTemplateExpansionTemplateArgument(
8657330f729Sjoerg     const TemplateArgument &TA) {
8667330f729Sjoerg   OS << " template expansion ";
8677330f729Sjoerg   TA.getAsTemplateOrTemplatePattern().dump(OS);
8687330f729Sjoerg }
8697330f729Sjoerg 
VisitExpressionTemplateArgument(const TemplateArgument &)8707330f729Sjoerg void TextNodeDumper::VisitExpressionTemplateArgument(const TemplateArgument &) {
8717330f729Sjoerg   OS << " expr";
8727330f729Sjoerg }
8737330f729Sjoerg 
VisitPackTemplateArgument(const TemplateArgument &)8747330f729Sjoerg void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &) {
8757330f729Sjoerg   OS << " pack";
8767330f729Sjoerg }
8777330f729Sjoerg 
dumpBasePath(raw_ostream & OS,const CastExpr * Node)8787330f729Sjoerg static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
8797330f729Sjoerg   if (Node->path_empty())
8807330f729Sjoerg     return;
8817330f729Sjoerg 
8827330f729Sjoerg   OS << " (";
8837330f729Sjoerg   bool First = true;
8847330f729Sjoerg   for (CastExpr::path_const_iterator I = Node->path_begin(),
8857330f729Sjoerg                                      E = Node->path_end();
8867330f729Sjoerg        I != E; ++I) {
8877330f729Sjoerg     const CXXBaseSpecifier *Base = *I;
8887330f729Sjoerg     if (!First)
8897330f729Sjoerg       OS << " -> ";
8907330f729Sjoerg 
8917330f729Sjoerg     const auto *RD =
8927330f729Sjoerg         cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl());
8937330f729Sjoerg 
8947330f729Sjoerg     if (Base->isVirtual())
8957330f729Sjoerg       OS << "virtual ";
8967330f729Sjoerg     OS << RD->getName();
8977330f729Sjoerg     First = false;
8987330f729Sjoerg   }
8997330f729Sjoerg 
9007330f729Sjoerg   OS << ')';
9017330f729Sjoerg }
9027330f729Sjoerg 
VisitIfStmt(const IfStmt * Node)9037330f729Sjoerg void TextNodeDumper::VisitIfStmt(const IfStmt *Node) {
9047330f729Sjoerg   if (Node->hasInitStorage())
9057330f729Sjoerg     OS << " has_init";
9067330f729Sjoerg   if (Node->hasVarStorage())
9077330f729Sjoerg     OS << " has_var";
9087330f729Sjoerg   if (Node->hasElseStorage())
9097330f729Sjoerg     OS << " has_else";
9107330f729Sjoerg }
9117330f729Sjoerg 
VisitSwitchStmt(const SwitchStmt * Node)9127330f729Sjoerg void TextNodeDumper::VisitSwitchStmt(const SwitchStmt *Node) {
9137330f729Sjoerg   if (Node->hasInitStorage())
9147330f729Sjoerg     OS << " has_init";
9157330f729Sjoerg   if (Node->hasVarStorage())
9167330f729Sjoerg     OS << " has_var";
9177330f729Sjoerg }
9187330f729Sjoerg 
VisitWhileStmt(const WhileStmt * Node)9197330f729Sjoerg void TextNodeDumper::VisitWhileStmt(const WhileStmt *Node) {
9207330f729Sjoerg   if (Node->hasVarStorage())
9217330f729Sjoerg     OS << " has_var";
9227330f729Sjoerg }
9237330f729Sjoerg 
VisitLabelStmt(const LabelStmt * Node)9247330f729Sjoerg void TextNodeDumper::VisitLabelStmt(const LabelStmt *Node) {
9257330f729Sjoerg   OS << " '" << Node->getName() << "'";
926*e038c9c4Sjoerg   if (Node->isSideEntry())
927*e038c9c4Sjoerg     OS << " side_entry";
9287330f729Sjoerg }
9297330f729Sjoerg 
VisitGotoStmt(const GotoStmt * Node)9307330f729Sjoerg void TextNodeDumper::VisitGotoStmt(const GotoStmt *Node) {
9317330f729Sjoerg   OS << " '" << Node->getLabel()->getName() << "'";
9327330f729Sjoerg   dumpPointer(Node->getLabel());
9337330f729Sjoerg }
9347330f729Sjoerg 
VisitCaseStmt(const CaseStmt * Node)9357330f729Sjoerg void TextNodeDumper::VisitCaseStmt(const CaseStmt *Node) {
9367330f729Sjoerg   if (Node->caseStmtIsGNURange())
9377330f729Sjoerg     OS << " gnu_range";
9387330f729Sjoerg }
9397330f729Sjoerg 
VisitConstantExpr(const ConstantExpr * Node)9407330f729Sjoerg void TextNodeDumper::VisitConstantExpr(const ConstantExpr *Node) {
941*e038c9c4Sjoerg   if (Node->hasAPValueResult())
942*e038c9c4Sjoerg     AddChild("value",
943*e038c9c4Sjoerg              [=] { Visit(Node->getAPValueResult(), Node->getType()); });
9447330f729Sjoerg }
9457330f729Sjoerg 
VisitCallExpr(const CallExpr * Node)9467330f729Sjoerg void TextNodeDumper::VisitCallExpr(const CallExpr *Node) {
9477330f729Sjoerg   if (Node->usesADL())
9487330f729Sjoerg     OS << " adl";
949*e038c9c4Sjoerg   if (Node->hasStoredFPFeatures())
950*e038c9c4Sjoerg     printFPOptions(Node->getFPFeatures());
951*e038c9c4Sjoerg }
952*e038c9c4Sjoerg 
VisitCXXOperatorCallExpr(const CXXOperatorCallExpr * Node)953*e038c9c4Sjoerg void TextNodeDumper::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *Node) {
954*e038c9c4Sjoerg   const char *OperatorSpelling = clang::getOperatorSpelling(Node->getOperator());
955*e038c9c4Sjoerg   if (OperatorSpelling)
956*e038c9c4Sjoerg     OS << " '" << OperatorSpelling << "'";
957*e038c9c4Sjoerg 
958*e038c9c4Sjoerg   VisitCallExpr(Node);
9597330f729Sjoerg }
9607330f729Sjoerg 
VisitCastExpr(const CastExpr * Node)9617330f729Sjoerg void TextNodeDumper::VisitCastExpr(const CastExpr *Node) {
9627330f729Sjoerg   OS << " <";
9637330f729Sjoerg   {
9647330f729Sjoerg     ColorScope Color(OS, ShowColors, CastColor);
9657330f729Sjoerg     OS << Node->getCastKindName();
9667330f729Sjoerg   }
9677330f729Sjoerg   dumpBasePath(OS, Node);
9687330f729Sjoerg   OS << ">";
969*e038c9c4Sjoerg   if (Node->hasStoredFPFeatures())
970*e038c9c4Sjoerg     printFPOptions(Node->getFPFeatures());
9717330f729Sjoerg }
9727330f729Sjoerg 
VisitImplicitCastExpr(const ImplicitCastExpr * Node)9737330f729Sjoerg void TextNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) {
9747330f729Sjoerg   VisitCastExpr(Node);
9757330f729Sjoerg   if (Node->isPartOfExplicitCast())
9767330f729Sjoerg     OS << " part_of_explicit_cast";
9777330f729Sjoerg }
9787330f729Sjoerg 
VisitDeclRefExpr(const DeclRefExpr * Node)9797330f729Sjoerg void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
9807330f729Sjoerg   OS << " ";
9817330f729Sjoerg   dumpBareDeclRef(Node->getDecl());
9827330f729Sjoerg   if (Node->getDecl() != Node->getFoundDecl()) {
9837330f729Sjoerg     OS << " (";
9847330f729Sjoerg     dumpBareDeclRef(Node->getFoundDecl());
9857330f729Sjoerg     OS << ")";
9867330f729Sjoerg   }
9877330f729Sjoerg   switch (Node->isNonOdrUse()) {
9887330f729Sjoerg   case NOUR_None: break;
9897330f729Sjoerg   case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break;
9907330f729Sjoerg   case NOUR_Constant: OS << " non_odr_use_constant"; break;
9917330f729Sjoerg   case NOUR_Discarded: OS << " non_odr_use_discarded"; break;
9927330f729Sjoerg   }
9937330f729Sjoerg }
9947330f729Sjoerg 
VisitUnresolvedLookupExpr(const UnresolvedLookupExpr * Node)9957330f729Sjoerg void TextNodeDumper::VisitUnresolvedLookupExpr(
9967330f729Sjoerg     const UnresolvedLookupExpr *Node) {
9977330f729Sjoerg   OS << " (";
9987330f729Sjoerg   if (!Node->requiresADL())
9997330f729Sjoerg     OS << "no ";
10007330f729Sjoerg   OS << "ADL) = '" << Node->getName() << '\'';
10017330f729Sjoerg 
10027330f729Sjoerg   UnresolvedLookupExpr::decls_iterator I = Node->decls_begin(),
10037330f729Sjoerg                                        E = Node->decls_end();
10047330f729Sjoerg   if (I == E)
10057330f729Sjoerg     OS << " empty";
10067330f729Sjoerg   for (; I != E; ++I)
10077330f729Sjoerg     dumpPointer(*I);
10087330f729Sjoerg }
10097330f729Sjoerg 
VisitObjCIvarRefExpr(const ObjCIvarRefExpr * Node)10107330f729Sjoerg void TextNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) {
10117330f729Sjoerg   {
10127330f729Sjoerg     ColorScope Color(OS, ShowColors, DeclKindNameColor);
10137330f729Sjoerg     OS << " " << Node->getDecl()->getDeclKindName() << "Decl";
10147330f729Sjoerg   }
10157330f729Sjoerg   OS << "='" << *Node->getDecl() << "'";
10167330f729Sjoerg   dumpPointer(Node->getDecl());
10177330f729Sjoerg   if (Node->isFreeIvar())
10187330f729Sjoerg     OS << " isFreeIvar";
10197330f729Sjoerg }
10207330f729Sjoerg 
VisitPredefinedExpr(const PredefinedExpr * Node)10217330f729Sjoerg void TextNodeDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
10227330f729Sjoerg   OS << " " << PredefinedExpr::getIdentKindName(Node->getIdentKind());
10237330f729Sjoerg }
10247330f729Sjoerg 
VisitCharacterLiteral(const CharacterLiteral * Node)10257330f729Sjoerg void TextNodeDumper::VisitCharacterLiteral(const CharacterLiteral *Node) {
10267330f729Sjoerg   ColorScope Color(OS, ShowColors, ValueColor);
10277330f729Sjoerg   OS << " " << Node->getValue();
10287330f729Sjoerg }
10297330f729Sjoerg 
VisitIntegerLiteral(const IntegerLiteral * Node)10307330f729Sjoerg void TextNodeDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
10317330f729Sjoerg   bool isSigned = Node->getType()->isSignedIntegerType();
10327330f729Sjoerg   ColorScope Color(OS, ShowColors, ValueColor);
10337330f729Sjoerg   OS << " " << Node->getValue().toString(10, isSigned);
10347330f729Sjoerg }
10357330f729Sjoerg 
VisitFixedPointLiteral(const FixedPointLiteral * Node)10367330f729Sjoerg void TextNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *Node) {
10377330f729Sjoerg   ColorScope Color(OS, ShowColors, ValueColor);
10387330f729Sjoerg   OS << " " << Node->getValueAsString(/*Radix=*/10);
10397330f729Sjoerg }
10407330f729Sjoerg 
VisitFloatingLiteral(const FloatingLiteral * Node)10417330f729Sjoerg void TextNodeDumper::VisitFloatingLiteral(const FloatingLiteral *Node) {
10427330f729Sjoerg   ColorScope Color(OS, ShowColors, ValueColor);
10437330f729Sjoerg   OS << " " << Node->getValueAsApproximateDouble();
10447330f729Sjoerg }
10457330f729Sjoerg 
VisitStringLiteral(const StringLiteral * Str)10467330f729Sjoerg void TextNodeDumper::VisitStringLiteral(const StringLiteral *Str) {
10477330f729Sjoerg   ColorScope Color(OS, ShowColors, ValueColor);
10487330f729Sjoerg   OS << " ";
10497330f729Sjoerg   Str->outputString(OS);
10507330f729Sjoerg }
10517330f729Sjoerg 
VisitInitListExpr(const InitListExpr * ILE)10527330f729Sjoerg void TextNodeDumper::VisitInitListExpr(const InitListExpr *ILE) {
10537330f729Sjoerg   if (auto *Field = ILE->getInitializedFieldInUnion()) {
10547330f729Sjoerg     OS << " field ";
10557330f729Sjoerg     dumpBareDeclRef(Field);
10567330f729Sjoerg   }
10577330f729Sjoerg }
10587330f729Sjoerg 
VisitGenericSelectionExpr(const GenericSelectionExpr * E)10597330f729Sjoerg void TextNodeDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
10607330f729Sjoerg   if (E->isResultDependent())
10617330f729Sjoerg     OS << " result_dependent";
10627330f729Sjoerg }
10637330f729Sjoerg 
VisitUnaryOperator(const UnaryOperator * Node)10647330f729Sjoerg void TextNodeDumper::VisitUnaryOperator(const UnaryOperator *Node) {
10657330f729Sjoerg   OS << " " << (Node->isPostfix() ? "postfix" : "prefix") << " '"
10667330f729Sjoerg      << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
10677330f729Sjoerg   if (!Node->canOverflow())
10687330f729Sjoerg     OS << " cannot overflow";
1069*e038c9c4Sjoerg   if (Node->hasStoredFPFeatures())
1070*e038c9c4Sjoerg     printFPOptions(Node->getStoredFPFeatures());
10717330f729Sjoerg }
10727330f729Sjoerg 
VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr * Node)10737330f729Sjoerg void TextNodeDumper::VisitUnaryExprOrTypeTraitExpr(
10747330f729Sjoerg     const UnaryExprOrTypeTraitExpr *Node) {
1075*e038c9c4Sjoerg   OS << " " << getTraitSpelling(Node->getKind());
1076*e038c9c4Sjoerg 
10777330f729Sjoerg   if (Node->isArgumentType())
10787330f729Sjoerg     dumpType(Node->getArgumentType());
10797330f729Sjoerg }
10807330f729Sjoerg 
VisitMemberExpr(const MemberExpr * Node)10817330f729Sjoerg void TextNodeDumper::VisitMemberExpr(const MemberExpr *Node) {
10827330f729Sjoerg   OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl();
10837330f729Sjoerg   dumpPointer(Node->getMemberDecl());
10847330f729Sjoerg   switch (Node->isNonOdrUse()) {
10857330f729Sjoerg   case NOUR_None: break;
10867330f729Sjoerg   case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break;
10877330f729Sjoerg   case NOUR_Constant: OS << " non_odr_use_constant"; break;
10887330f729Sjoerg   case NOUR_Discarded: OS << " non_odr_use_discarded"; break;
10897330f729Sjoerg   }
10907330f729Sjoerg }
10917330f729Sjoerg 
VisitExtVectorElementExpr(const ExtVectorElementExpr * Node)10927330f729Sjoerg void TextNodeDumper::VisitExtVectorElementExpr(
10937330f729Sjoerg     const ExtVectorElementExpr *Node) {
10947330f729Sjoerg   OS << " " << Node->getAccessor().getNameStart();
10957330f729Sjoerg }
10967330f729Sjoerg 
VisitBinaryOperator(const BinaryOperator * Node)10977330f729Sjoerg void TextNodeDumper::VisitBinaryOperator(const BinaryOperator *Node) {
10987330f729Sjoerg   OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1099*e038c9c4Sjoerg   if (Node->hasStoredFPFeatures())
1100*e038c9c4Sjoerg     printFPOptions(Node->getStoredFPFeatures());
11017330f729Sjoerg }
11027330f729Sjoerg 
VisitCompoundAssignOperator(const CompoundAssignOperator * Node)11037330f729Sjoerg void TextNodeDumper::VisitCompoundAssignOperator(
11047330f729Sjoerg     const CompoundAssignOperator *Node) {
11057330f729Sjoerg   OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
11067330f729Sjoerg      << "' ComputeLHSTy=";
11077330f729Sjoerg   dumpBareType(Node->getComputationLHSType());
11087330f729Sjoerg   OS << " ComputeResultTy=";
11097330f729Sjoerg   dumpBareType(Node->getComputationResultType());
1110*e038c9c4Sjoerg   if (Node->hasStoredFPFeatures())
1111*e038c9c4Sjoerg     printFPOptions(Node->getStoredFPFeatures());
11127330f729Sjoerg }
11137330f729Sjoerg 
VisitAddrLabelExpr(const AddrLabelExpr * Node)11147330f729Sjoerg void TextNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) {
11157330f729Sjoerg   OS << " " << Node->getLabel()->getName();
11167330f729Sjoerg   dumpPointer(Node->getLabel());
11177330f729Sjoerg }
11187330f729Sjoerg 
VisitCXXNamedCastExpr(const CXXNamedCastExpr * Node)11197330f729Sjoerg void TextNodeDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) {
11207330f729Sjoerg   OS << " " << Node->getCastName() << "<"
11217330f729Sjoerg      << Node->getTypeAsWritten().getAsString() << ">"
11227330f729Sjoerg      << " <" << Node->getCastKindName();
11237330f729Sjoerg   dumpBasePath(OS, Node);
11247330f729Sjoerg   OS << ">";
11257330f729Sjoerg }
11267330f729Sjoerg 
VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr * Node)11277330f729Sjoerg void TextNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
11287330f729Sjoerg   OS << " " << (Node->getValue() ? "true" : "false");
11297330f729Sjoerg }
11307330f729Sjoerg 
VisitCXXThisExpr(const CXXThisExpr * Node)11317330f729Sjoerg void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
11327330f729Sjoerg   if (Node->isImplicit())
11337330f729Sjoerg     OS << " implicit";
11347330f729Sjoerg   OS << " this";
11357330f729Sjoerg }
11367330f729Sjoerg 
VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr * Node)11377330f729Sjoerg void TextNodeDumper::VisitCXXFunctionalCastExpr(
11387330f729Sjoerg     const CXXFunctionalCastExpr *Node) {
11397330f729Sjoerg   OS << " functional cast to " << Node->getTypeAsWritten().getAsString() << " <"
11407330f729Sjoerg      << Node->getCastKindName() << ">";
1141*e038c9c4Sjoerg   if (Node->hasStoredFPFeatures())
1142*e038c9c4Sjoerg     printFPOptions(Node->getFPFeatures());
1143*e038c9c4Sjoerg }
1144*e038c9c4Sjoerg 
VisitCXXStaticCastExpr(const CXXStaticCastExpr * Node)1145*e038c9c4Sjoerg void TextNodeDumper::VisitCXXStaticCastExpr(const CXXStaticCastExpr *Node) {
1146*e038c9c4Sjoerg   VisitCXXNamedCastExpr(Node);
1147*e038c9c4Sjoerg   if (Node->hasStoredFPFeatures())
1148*e038c9c4Sjoerg     printFPOptions(Node->getFPFeatures());
11497330f729Sjoerg }
11507330f729Sjoerg 
VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr * Node)11517330f729Sjoerg void TextNodeDumper::VisitCXXUnresolvedConstructExpr(
11527330f729Sjoerg     const CXXUnresolvedConstructExpr *Node) {
11537330f729Sjoerg   dumpType(Node->getTypeAsWritten());
11547330f729Sjoerg   if (Node->isListInitialization())
11557330f729Sjoerg     OS << " list";
11567330f729Sjoerg }
11577330f729Sjoerg 
VisitCXXConstructExpr(const CXXConstructExpr * Node)11587330f729Sjoerg void TextNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
11597330f729Sjoerg   CXXConstructorDecl *Ctor = Node->getConstructor();
11607330f729Sjoerg   dumpType(Ctor->getType());
11617330f729Sjoerg   if (Node->isElidable())
11627330f729Sjoerg     OS << " elidable";
11637330f729Sjoerg   if (Node->isListInitialization())
11647330f729Sjoerg     OS << " list";
11657330f729Sjoerg   if (Node->isStdInitListInitialization())
11667330f729Sjoerg     OS << " std::initializer_list";
11677330f729Sjoerg   if (Node->requiresZeroInitialization())
11687330f729Sjoerg     OS << " zeroing";
11697330f729Sjoerg }
11707330f729Sjoerg 
VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr * Node)11717330f729Sjoerg void TextNodeDumper::VisitCXXBindTemporaryExpr(
11727330f729Sjoerg     const CXXBindTemporaryExpr *Node) {
11737330f729Sjoerg   OS << " (CXXTemporary";
11747330f729Sjoerg   dumpPointer(Node);
11757330f729Sjoerg   OS << ")";
11767330f729Sjoerg }
11777330f729Sjoerg 
VisitCXXNewExpr(const CXXNewExpr * Node)11787330f729Sjoerg void TextNodeDumper::VisitCXXNewExpr(const CXXNewExpr *Node) {
11797330f729Sjoerg   if (Node->isGlobalNew())
11807330f729Sjoerg     OS << " global";
11817330f729Sjoerg   if (Node->isArray())
11827330f729Sjoerg     OS << " array";
11837330f729Sjoerg   if (Node->getOperatorNew()) {
11847330f729Sjoerg     OS << ' ';
11857330f729Sjoerg     dumpBareDeclRef(Node->getOperatorNew());
11867330f729Sjoerg   }
11877330f729Sjoerg   // We could dump the deallocation function used in case of error, but it's
11887330f729Sjoerg   // usually not that interesting.
11897330f729Sjoerg }
11907330f729Sjoerg 
VisitCXXDeleteExpr(const CXXDeleteExpr * Node)11917330f729Sjoerg void TextNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *Node) {
11927330f729Sjoerg   if (Node->isGlobalDelete())
11937330f729Sjoerg     OS << " global";
11947330f729Sjoerg   if (Node->isArrayForm())
11957330f729Sjoerg     OS << " array";
11967330f729Sjoerg   if (Node->getOperatorDelete()) {
11977330f729Sjoerg     OS << ' ';
11987330f729Sjoerg     dumpBareDeclRef(Node->getOperatorDelete());
11997330f729Sjoerg   }
12007330f729Sjoerg }
12017330f729Sjoerg 
VisitTypeTraitExpr(const TypeTraitExpr * Node)1202*e038c9c4Sjoerg void TextNodeDumper::VisitTypeTraitExpr(const TypeTraitExpr *Node) {
1203*e038c9c4Sjoerg   OS << " " << getTraitSpelling(Node->getTrait());
1204*e038c9c4Sjoerg }
1205*e038c9c4Sjoerg 
VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr * Node)1206*e038c9c4Sjoerg void TextNodeDumper::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *Node) {
1207*e038c9c4Sjoerg   OS << " " << getTraitSpelling(Node->getTrait());
1208*e038c9c4Sjoerg }
1209*e038c9c4Sjoerg 
VisitExpressionTraitExpr(const ExpressionTraitExpr * Node)1210*e038c9c4Sjoerg void TextNodeDumper::VisitExpressionTraitExpr(const ExpressionTraitExpr *Node) {
1211*e038c9c4Sjoerg   OS << " " << getTraitSpelling(Node->getTrait());
1212*e038c9c4Sjoerg }
1213*e038c9c4Sjoerg 
VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr * Node)12147330f729Sjoerg void TextNodeDumper::VisitMaterializeTemporaryExpr(
12157330f729Sjoerg     const MaterializeTemporaryExpr *Node) {
12167330f729Sjoerg   if (const ValueDecl *VD = Node->getExtendingDecl()) {
12177330f729Sjoerg     OS << " extended by ";
12187330f729Sjoerg     dumpBareDeclRef(VD);
12197330f729Sjoerg   }
12207330f729Sjoerg }
12217330f729Sjoerg 
VisitExprWithCleanups(const ExprWithCleanups * Node)12227330f729Sjoerg void TextNodeDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) {
12237330f729Sjoerg   for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
1224*e038c9c4Sjoerg     dumpCleanupObject(Node->getObject(i));
12257330f729Sjoerg }
12267330f729Sjoerg 
VisitSizeOfPackExpr(const SizeOfPackExpr * Node)12277330f729Sjoerg void TextNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
12287330f729Sjoerg   dumpPointer(Node->getPack());
12297330f729Sjoerg   dumpName(Node->getPack());
12307330f729Sjoerg }
12317330f729Sjoerg 
VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr * Node)12327330f729Sjoerg void TextNodeDumper::VisitCXXDependentScopeMemberExpr(
12337330f729Sjoerg     const CXXDependentScopeMemberExpr *Node) {
12347330f729Sjoerg   OS << " " << (Node->isArrow() ? "->" : ".") << Node->getMember();
12357330f729Sjoerg }
12367330f729Sjoerg 
VisitObjCMessageExpr(const ObjCMessageExpr * Node)12377330f729Sjoerg void TextNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
12387330f729Sjoerg   OS << " selector=";
12397330f729Sjoerg   Node->getSelector().print(OS);
12407330f729Sjoerg   switch (Node->getReceiverKind()) {
12417330f729Sjoerg   case ObjCMessageExpr::Instance:
12427330f729Sjoerg     break;
12437330f729Sjoerg 
12447330f729Sjoerg   case ObjCMessageExpr::Class:
12457330f729Sjoerg     OS << " class=";
12467330f729Sjoerg     dumpBareType(Node->getClassReceiver());
12477330f729Sjoerg     break;
12487330f729Sjoerg 
12497330f729Sjoerg   case ObjCMessageExpr::SuperInstance:
12507330f729Sjoerg     OS << " super (instance)";
12517330f729Sjoerg     break;
12527330f729Sjoerg 
12537330f729Sjoerg   case ObjCMessageExpr::SuperClass:
12547330f729Sjoerg     OS << " super (class)";
12557330f729Sjoerg     break;
12567330f729Sjoerg   }
12577330f729Sjoerg }
12587330f729Sjoerg 
VisitObjCBoxedExpr(const ObjCBoxedExpr * Node)12597330f729Sjoerg void TextNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
12607330f729Sjoerg   if (auto *BoxingMethod = Node->getBoxingMethod()) {
12617330f729Sjoerg     OS << " selector=";
12627330f729Sjoerg     BoxingMethod->getSelector().print(OS);
12637330f729Sjoerg   }
12647330f729Sjoerg }
12657330f729Sjoerg 
VisitObjCAtCatchStmt(const ObjCAtCatchStmt * Node)12667330f729Sjoerg void TextNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
12677330f729Sjoerg   if (!Node->getCatchParamDecl())
12687330f729Sjoerg     OS << " catch all";
12697330f729Sjoerg }
12707330f729Sjoerg 
VisitObjCEncodeExpr(const ObjCEncodeExpr * Node)12717330f729Sjoerg void TextNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
12727330f729Sjoerg   dumpType(Node->getEncodedType());
12737330f729Sjoerg }
12747330f729Sjoerg 
VisitObjCSelectorExpr(const ObjCSelectorExpr * Node)12757330f729Sjoerg void TextNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
12767330f729Sjoerg   OS << " ";
12777330f729Sjoerg   Node->getSelector().print(OS);
12787330f729Sjoerg }
12797330f729Sjoerg 
VisitObjCProtocolExpr(const ObjCProtocolExpr * Node)12807330f729Sjoerg void TextNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
12817330f729Sjoerg   OS << ' ' << *Node->getProtocol();
12827330f729Sjoerg }
12837330f729Sjoerg 
VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr * Node)12847330f729Sjoerg void TextNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) {
12857330f729Sjoerg   if (Node->isImplicitProperty()) {
12867330f729Sjoerg     OS << " Kind=MethodRef Getter=\"";
12877330f729Sjoerg     if (Node->getImplicitPropertyGetter())
12887330f729Sjoerg       Node->getImplicitPropertyGetter()->getSelector().print(OS);
12897330f729Sjoerg     else
12907330f729Sjoerg       OS << "(null)";
12917330f729Sjoerg 
12927330f729Sjoerg     OS << "\" Setter=\"";
12937330f729Sjoerg     if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
12947330f729Sjoerg       Setter->getSelector().print(OS);
12957330f729Sjoerg     else
12967330f729Sjoerg       OS << "(null)";
12977330f729Sjoerg     OS << "\"";
12987330f729Sjoerg   } else {
12997330f729Sjoerg     OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty()
13007330f729Sjoerg        << '"';
13017330f729Sjoerg   }
13027330f729Sjoerg 
13037330f729Sjoerg   if (Node->isSuperReceiver())
13047330f729Sjoerg     OS << " super";
13057330f729Sjoerg 
13067330f729Sjoerg   OS << " Messaging=";
13077330f729Sjoerg   if (Node->isMessagingGetter() && Node->isMessagingSetter())
13087330f729Sjoerg     OS << "Getter&Setter";
13097330f729Sjoerg   else if (Node->isMessagingGetter())
13107330f729Sjoerg     OS << "Getter";
13117330f729Sjoerg   else if (Node->isMessagingSetter())
13127330f729Sjoerg     OS << "Setter";
13137330f729Sjoerg }
13147330f729Sjoerg 
VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr * Node)13157330f729Sjoerg void TextNodeDumper::VisitObjCSubscriptRefExpr(
13167330f729Sjoerg     const ObjCSubscriptRefExpr *Node) {
13177330f729Sjoerg   if (Node->isArraySubscriptRefExpr())
13187330f729Sjoerg     OS << " Kind=ArraySubscript GetterForArray=\"";
13197330f729Sjoerg   else
13207330f729Sjoerg     OS << " Kind=DictionarySubscript GetterForDictionary=\"";
13217330f729Sjoerg   if (Node->getAtIndexMethodDecl())
13227330f729Sjoerg     Node->getAtIndexMethodDecl()->getSelector().print(OS);
13237330f729Sjoerg   else
13247330f729Sjoerg     OS << "(null)";
13257330f729Sjoerg 
13267330f729Sjoerg   if (Node->isArraySubscriptRefExpr())
13277330f729Sjoerg     OS << "\" SetterForArray=\"";
13287330f729Sjoerg   else
13297330f729Sjoerg     OS << "\" SetterForDictionary=\"";
13307330f729Sjoerg   if (Node->setAtIndexMethodDecl())
13317330f729Sjoerg     Node->setAtIndexMethodDecl()->getSelector().print(OS);
13327330f729Sjoerg   else
13337330f729Sjoerg     OS << "(null)";
13347330f729Sjoerg }
13357330f729Sjoerg 
VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr * Node)13367330f729Sjoerg void TextNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) {
13377330f729Sjoerg   OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
13387330f729Sjoerg }
13397330f729Sjoerg 
VisitOMPIteratorExpr(const OMPIteratorExpr * Node)1340*e038c9c4Sjoerg void TextNodeDumper::VisitOMPIteratorExpr(const OMPIteratorExpr *Node) {
1341*e038c9c4Sjoerg   OS << " ";
1342*e038c9c4Sjoerg   for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) {
1343*e038c9c4Sjoerg     Visit(Node->getIteratorDecl(I));
1344*e038c9c4Sjoerg     OS << " = ";
1345*e038c9c4Sjoerg     const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I);
1346*e038c9c4Sjoerg     OS << " begin ";
1347*e038c9c4Sjoerg     Visit(Range.Begin);
1348*e038c9c4Sjoerg     OS << " end ";
1349*e038c9c4Sjoerg     Visit(Range.End);
1350*e038c9c4Sjoerg     if (Range.Step) {
1351*e038c9c4Sjoerg       OS << " step ";
1352*e038c9c4Sjoerg       Visit(Range.Step);
1353*e038c9c4Sjoerg     }
1354*e038c9c4Sjoerg   }
1355*e038c9c4Sjoerg }
1356*e038c9c4Sjoerg 
VisitConceptSpecializationExpr(const ConceptSpecializationExpr * Node)1357*e038c9c4Sjoerg void TextNodeDumper::VisitConceptSpecializationExpr(
1358*e038c9c4Sjoerg     const ConceptSpecializationExpr *Node) {
1359*e038c9c4Sjoerg   OS << " ";
1360*e038c9c4Sjoerg   dumpBareDeclRef(Node->getFoundDecl());
1361*e038c9c4Sjoerg }
1362*e038c9c4Sjoerg 
VisitRValueReferenceType(const ReferenceType * T)13637330f729Sjoerg void TextNodeDumper::VisitRValueReferenceType(const ReferenceType *T) {
13647330f729Sjoerg   if (T->isSpelledAsLValue())
13657330f729Sjoerg     OS << " written as lvalue reference";
13667330f729Sjoerg }
13677330f729Sjoerg 
VisitArrayType(const ArrayType * T)13687330f729Sjoerg void TextNodeDumper::VisitArrayType(const ArrayType *T) {
13697330f729Sjoerg   switch (T->getSizeModifier()) {
13707330f729Sjoerg   case ArrayType::Normal:
13717330f729Sjoerg     break;
13727330f729Sjoerg   case ArrayType::Static:
13737330f729Sjoerg     OS << " static";
13747330f729Sjoerg     break;
13757330f729Sjoerg   case ArrayType::Star:
13767330f729Sjoerg     OS << " *";
13777330f729Sjoerg     break;
13787330f729Sjoerg   }
13797330f729Sjoerg   OS << " " << T->getIndexTypeQualifiers().getAsString();
13807330f729Sjoerg }
13817330f729Sjoerg 
VisitConstantArrayType(const ConstantArrayType * T)13827330f729Sjoerg void TextNodeDumper::VisitConstantArrayType(const ConstantArrayType *T) {
13837330f729Sjoerg   OS << " " << T->getSize();
13847330f729Sjoerg   VisitArrayType(T);
13857330f729Sjoerg }
13867330f729Sjoerg 
VisitVariableArrayType(const VariableArrayType * T)13877330f729Sjoerg void TextNodeDumper::VisitVariableArrayType(const VariableArrayType *T) {
13887330f729Sjoerg   OS << " ";
13897330f729Sjoerg   dumpSourceRange(T->getBracketsRange());
13907330f729Sjoerg   VisitArrayType(T);
13917330f729Sjoerg }
13927330f729Sjoerg 
VisitDependentSizedArrayType(const DependentSizedArrayType * T)13937330f729Sjoerg void TextNodeDumper::VisitDependentSizedArrayType(
13947330f729Sjoerg     const DependentSizedArrayType *T) {
13957330f729Sjoerg   VisitArrayType(T);
13967330f729Sjoerg   OS << " ";
13977330f729Sjoerg   dumpSourceRange(T->getBracketsRange());
13987330f729Sjoerg }
13997330f729Sjoerg 
VisitDependentSizedExtVectorType(const DependentSizedExtVectorType * T)14007330f729Sjoerg void TextNodeDumper::VisitDependentSizedExtVectorType(
14017330f729Sjoerg     const DependentSizedExtVectorType *T) {
14027330f729Sjoerg   OS << " ";
14037330f729Sjoerg   dumpLocation(T->getAttributeLoc());
14047330f729Sjoerg }
14057330f729Sjoerg 
VisitVectorType(const VectorType * T)14067330f729Sjoerg void TextNodeDumper::VisitVectorType(const VectorType *T) {
14077330f729Sjoerg   switch (T->getVectorKind()) {
14087330f729Sjoerg   case VectorType::GenericVector:
14097330f729Sjoerg     break;
14107330f729Sjoerg   case VectorType::AltiVecVector:
14117330f729Sjoerg     OS << " altivec";
14127330f729Sjoerg     break;
14137330f729Sjoerg   case VectorType::AltiVecPixel:
14147330f729Sjoerg     OS << " altivec pixel";
14157330f729Sjoerg     break;
14167330f729Sjoerg   case VectorType::AltiVecBool:
14177330f729Sjoerg     OS << " altivec bool";
14187330f729Sjoerg     break;
14197330f729Sjoerg   case VectorType::NeonVector:
14207330f729Sjoerg     OS << " neon";
14217330f729Sjoerg     break;
14227330f729Sjoerg   case VectorType::NeonPolyVector:
14237330f729Sjoerg     OS << " neon poly";
14247330f729Sjoerg     break;
1425*e038c9c4Sjoerg   case VectorType::SveFixedLengthDataVector:
1426*e038c9c4Sjoerg     OS << " fixed-length sve data vector";
1427*e038c9c4Sjoerg     break;
1428*e038c9c4Sjoerg   case VectorType::SveFixedLengthPredicateVector:
1429*e038c9c4Sjoerg     OS << " fixed-length sve predicate vector";
1430*e038c9c4Sjoerg     break;
14317330f729Sjoerg   }
14327330f729Sjoerg   OS << " " << T->getNumElements();
14337330f729Sjoerg }
14347330f729Sjoerg 
VisitFunctionType(const FunctionType * T)14357330f729Sjoerg void TextNodeDumper::VisitFunctionType(const FunctionType *T) {
14367330f729Sjoerg   auto EI = T->getExtInfo();
14377330f729Sjoerg   if (EI.getNoReturn())
14387330f729Sjoerg     OS << " noreturn";
14397330f729Sjoerg   if (EI.getProducesResult())
14407330f729Sjoerg     OS << " produces_result";
14417330f729Sjoerg   if (EI.getHasRegParm())
14427330f729Sjoerg     OS << " regparm " << EI.getRegParm();
14437330f729Sjoerg   OS << " " << FunctionType::getNameForCallConv(EI.getCC());
14447330f729Sjoerg }
14457330f729Sjoerg 
VisitFunctionProtoType(const FunctionProtoType * T)14467330f729Sjoerg void TextNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) {
14477330f729Sjoerg   auto EPI = T->getExtProtoInfo();
14487330f729Sjoerg   if (EPI.HasTrailingReturn)
14497330f729Sjoerg     OS << " trailing_return";
14507330f729Sjoerg   if (T->isConst())
14517330f729Sjoerg     OS << " const";
14527330f729Sjoerg   if (T->isVolatile())
14537330f729Sjoerg     OS << " volatile";
14547330f729Sjoerg   if (T->isRestrict())
14557330f729Sjoerg     OS << " restrict";
14567330f729Sjoerg   if (T->getExtProtoInfo().Variadic)
14577330f729Sjoerg     OS << " variadic";
14587330f729Sjoerg   switch (EPI.RefQualifier) {
14597330f729Sjoerg   case RQ_None:
14607330f729Sjoerg     break;
14617330f729Sjoerg   case RQ_LValue:
14627330f729Sjoerg     OS << " &";
14637330f729Sjoerg     break;
14647330f729Sjoerg   case RQ_RValue:
14657330f729Sjoerg     OS << " &&";
14667330f729Sjoerg     break;
14677330f729Sjoerg   }
14687330f729Sjoerg   // FIXME: Exception specification.
14697330f729Sjoerg   // FIXME: Consumed parameters.
14707330f729Sjoerg   VisitFunctionType(T);
14717330f729Sjoerg }
14727330f729Sjoerg 
VisitUnresolvedUsingType(const UnresolvedUsingType * T)14737330f729Sjoerg void TextNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
14747330f729Sjoerg   dumpDeclRef(T->getDecl());
14757330f729Sjoerg }
14767330f729Sjoerg 
VisitTypedefType(const TypedefType * T)14777330f729Sjoerg void TextNodeDumper::VisitTypedefType(const TypedefType *T) {
14787330f729Sjoerg   dumpDeclRef(T->getDecl());
14797330f729Sjoerg }
14807330f729Sjoerg 
VisitUnaryTransformType(const UnaryTransformType * T)14817330f729Sjoerg void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType *T) {
14827330f729Sjoerg   switch (T->getUTTKind()) {
14837330f729Sjoerg   case UnaryTransformType::EnumUnderlyingType:
14847330f729Sjoerg     OS << " underlying_type";
14857330f729Sjoerg     break;
14867330f729Sjoerg   }
14877330f729Sjoerg }
14887330f729Sjoerg 
VisitTagType(const TagType * T)14897330f729Sjoerg void TextNodeDumper::VisitTagType(const TagType *T) {
14907330f729Sjoerg   dumpDeclRef(T->getDecl());
14917330f729Sjoerg }
14927330f729Sjoerg 
VisitTemplateTypeParmType(const TemplateTypeParmType * T)14937330f729Sjoerg void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
14947330f729Sjoerg   OS << " depth " << T->getDepth() << " index " << T->getIndex();
14957330f729Sjoerg   if (T->isParameterPack())
14967330f729Sjoerg     OS << " pack";
14977330f729Sjoerg   dumpDeclRef(T->getDecl());
14987330f729Sjoerg }
14997330f729Sjoerg 
VisitAutoType(const AutoType * T)15007330f729Sjoerg void TextNodeDumper::VisitAutoType(const AutoType *T) {
15017330f729Sjoerg   if (T->isDecltypeAuto())
15027330f729Sjoerg     OS << " decltype(auto)";
15037330f729Sjoerg   if (!T->isDeduced())
15047330f729Sjoerg     OS << " undeduced";
1505*e038c9c4Sjoerg   if (T->isConstrained()) {
1506*e038c9c4Sjoerg     dumpDeclRef(T->getTypeConstraintConcept());
1507*e038c9c4Sjoerg     for (const auto &Arg : T->getTypeConstraintArguments())
1508*e038c9c4Sjoerg       VisitTemplateArgument(Arg);
1509*e038c9c4Sjoerg   }
15107330f729Sjoerg }
15117330f729Sjoerg 
VisitTemplateSpecializationType(const TemplateSpecializationType * T)15127330f729Sjoerg void TextNodeDumper::VisitTemplateSpecializationType(
15137330f729Sjoerg     const TemplateSpecializationType *T) {
15147330f729Sjoerg   if (T->isTypeAlias())
15157330f729Sjoerg     OS << " alias";
15167330f729Sjoerg   OS << " ";
15177330f729Sjoerg   T->getTemplateName().dump(OS);
15187330f729Sjoerg }
15197330f729Sjoerg 
VisitInjectedClassNameType(const InjectedClassNameType * T)15207330f729Sjoerg void TextNodeDumper::VisitInjectedClassNameType(
15217330f729Sjoerg     const InjectedClassNameType *T) {
15227330f729Sjoerg   dumpDeclRef(T->getDecl());
15237330f729Sjoerg }
15247330f729Sjoerg 
VisitObjCInterfaceType(const ObjCInterfaceType * T)15257330f729Sjoerg void TextNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
15267330f729Sjoerg   dumpDeclRef(T->getDecl());
15277330f729Sjoerg }
15287330f729Sjoerg 
VisitPackExpansionType(const PackExpansionType * T)15297330f729Sjoerg void TextNodeDumper::VisitPackExpansionType(const PackExpansionType *T) {
15307330f729Sjoerg   if (auto N = T->getNumExpansions())
15317330f729Sjoerg     OS << " expansions " << *N;
15327330f729Sjoerg }
15337330f729Sjoerg 
VisitLabelDecl(const LabelDecl * D)15347330f729Sjoerg void TextNodeDumper::VisitLabelDecl(const LabelDecl *D) { dumpName(D); }
15357330f729Sjoerg 
VisitTypedefDecl(const TypedefDecl * D)15367330f729Sjoerg void TextNodeDumper::VisitTypedefDecl(const TypedefDecl *D) {
15377330f729Sjoerg   dumpName(D);
15387330f729Sjoerg   dumpType(D->getUnderlyingType());
15397330f729Sjoerg   if (D->isModulePrivate())
15407330f729Sjoerg     OS << " __module_private__";
15417330f729Sjoerg }
15427330f729Sjoerg 
VisitEnumDecl(const EnumDecl * D)15437330f729Sjoerg void TextNodeDumper::VisitEnumDecl(const EnumDecl *D) {
15447330f729Sjoerg   if (D->isScoped()) {
15457330f729Sjoerg     if (D->isScopedUsingClassTag())
15467330f729Sjoerg       OS << " class";
15477330f729Sjoerg     else
15487330f729Sjoerg       OS << " struct";
15497330f729Sjoerg   }
15507330f729Sjoerg   dumpName(D);
15517330f729Sjoerg   if (D->isModulePrivate())
15527330f729Sjoerg     OS << " __module_private__";
15537330f729Sjoerg   if (D->isFixed())
15547330f729Sjoerg     dumpType(D->getIntegerType());
15557330f729Sjoerg }
15567330f729Sjoerg 
VisitRecordDecl(const RecordDecl * D)15577330f729Sjoerg void TextNodeDumper::VisitRecordDecl(const RecordDecl *D) {
15587330f729Sjoerg   OS << ' ' << D->getKindName();
15597330f729Sjoerg   dumpName(D);
15607330f729Sjoerg   if (D->isModulePrivate())
15617330f729Sjoerg     OS << " __module_private__";
15627330f729Sjoerg   if (D->isCompleteDefinition())
15637330f729Sjoerg     OS << " definition";
15647330f729Sjoerg }
15657330f729Sjoerg 
VisitEnumConstantDecl(const EnumConstantDecl * D)15667330f729Sjoerg void TextNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
15677330f729Sjoerg   dumpName(D);
15687330f729Sjoerg   dumpType(D->getType());
15697330f729Sjoerg }
15707330f729Sjoerg 
VisitIndirectFieldDecl(const IndirectFieldDecl * D)15717330f729Sjoerg void TextNodeDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
15727330f729Sjoerg   dumpName(D);
15737330f729Sjoerg   dumpType(D->getType());
15747330f729Sjoerg 
15757330f729Sjoerg   for (const auto *Child : D->chain())
15767330f729Sjoerg     dumpDeclRef(Child);
15777330f729Sjoerg }
15787330f729Sjoerg 
VisitFunctionDecl(const FunctionDecl * D)15797330f729Sjoerg void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) {
15807330f729Sjoerg   dumpName(D);
15817330f729Sjoerg   dumpType(D->getType());
15827330f729Sjoerg 
15837330f729Sjoerg   StorageClass SC = D->getStorageClass();
15847330f729Sjoerg   if (SC != SC_None)
15857330f729Sjoerg     OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
15867330f729Sjoerg   if (D->isInlineSpecified())
15877330f729Sjoerg     OS << " inline";
15887330f729Sjoerg   if (D->isVirtualAsWritten())
15897330f729Sjoerg     OS << " virtual";
15907330f729Sjoerg   if (D->isModulePrivate())
15917330f729Sjoerg     OS << " __module_private__";
15927330f729Sjoerg 
15937330f729Sjoerg   if (D->isPure())
15947330f729Sjoerg     OS << " pure";
15957330f729Sjoerg   if (D->isDefaulted()) {
15967330f729Sjoerg     OS << " default";
15977330f729Sjoerg     if (D->isDeleted())
15987330f729Sjoerg       OS << "_delete";
15997330f729Sjoerg   }
16007330f729Sjoerg   if (D->isDeletedAsWritten())
16017330f729Sjoerg     OS << " delete";
16027330f729Sjoerg   if (D->isTrivial())
16037330f729Sjoerg     OS << " trivial";
16047330f729Sjoerg 
16057330f729Sjoerg   if (const auto *FPT = D->getType()->getAs<FunctionProtoType>()) {
16067330f729Sjoerg     FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
16077330f729Sjoerg     switch (EPI.ExceptionSpec.Type) {
16087330f729Sjoerg     default:
16097330f729Sjoerg       break;
16107330f729Sjoerg     case EST_Unevaluated:
16117330f729Sjoerg       OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl;
16127330f729Sjoerg       break;
16137330f729Sjoerg     case EST_Uninstantiated:
16147330f729Sjoerg       OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate;
16157330f729Sjoerg       break;
16167330f729Sjoerg     }
16177330f729Sjoerg   }
16187330f729Sjoerg 
16197330f729Sjoerg   if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
16207330f729Sjoerg     if (MD->size_overridden_methods() != 0) {
16217330f729Sjoerg       auto dumpOverride = [=](const CXXMethodDecl *D) {
16227330f729Sjoerg         SplitQualType T_split = D->getType().split();
1623*e038c9c4Sjoerg         OS << D << " " << D->getParent()->getName() << "::" << D->getDeclName()
1624*e038c9c4Sjoerg            << " '" << QualType::getAsString(T_split, PrintPolicy) << "'";
16257330f729Sjoerg       };
16267330f729Sjoerg 
16277330f729Sjoerg       AddChild([=] {
16287330f729Sjoerg         auto Overrides = MD->overridden_methods();
16297330f729Sjoerg         OS << "Overrides: [ ";
16307330f729Sjoerg         dumpOverride(*Overrides.begin());
16317330f729Sjoerg         for (const auto *Override :
16327330f729Sjoerg              llvm::make_range(Overrides.begin() + 1, Overrides.end())) {
16337330f729Sjoerg           OS << ", ";
16347330f729Sjoerg           dumpOverride(Override);
16357330f729Sjoerg         }
16367330f729Sjoerg         OS << " ]";
16377330f729Sjoerg       });
16387330f729Sjoerg     }
16397330f729Sjoerg   }
16407330f729Sjoerg 
16417330f729Sjoerg   // Since NumParams comes from the FunctionProtoType of the FunctionDecl and
16427330f729Sjoerg   // the Params are set later, it is possible for a dump during debugging to
16437330f729Sjoerg   // encounter a FunctionDecl that has been created but hasn't been assigned
16447330f729Sjoerg   // ParmVarDecls yet.
16457330f729Sjoerg   if (!D->param_empty() && !D->param_begin())
16467330f729Sjoerg     OS << " <<<NULL params x " << D->getNumParams() << ">>>";
16477330f729Sjoerg }
16487330f729Sjoerg 
VisitLifetimeExtendedTemporaryDecl(const LifetimeExtendedTemporaryDecl * D)1649*e038c9c4Sjoerg void TextNodeDumper::VisitLifetimeExtendedTemporaryDecl(
1650*e038c9c4Sjoerg     const LifetimeExtendedTemporaryDecl *D) {
1651*e038c9c4Sjoerg   OS << " extended by ";
1652*e038c9c4Sjoerg   dumpBareDeclRef(D->getExtendingDecl());
1653*e038c9c4Sjoerg   OS << " mangling ";
1654*e038c9c4Sjoerg   {
1655*e038c9c4Sjoerg     ColorScope Color(OS, ShowColors, ValueColor);
1656*e038c9c4Sjoerg     OS << D->getManglingNumber();
1657*e038c9c4Sjoerg   }
1658*e038c9c4Sjoerg }
1659*e038c9c4Sjoerg 
VisitFieldDecl(const FieldDecl * D)16607330f729Sjoerg void TextNodeDumper::VisitFieldDecl(const FieldDecl *D) {
16617330f729Sjoerg   dumpName(D);
16627330f729Sjoerg   dumpType(D->getType());
16637330f729Sjoerg   if (D->isMutable())
16647330f729Sjoerg     OS << " mutable";
16657330f729Sjoerg   if (D->isModulePrivate())
16667330f729Sjoerg     OS << " __module_private__";
16677330f729Sjoerg }
16687330f729Sjoerg 
VisitVarDecl(const VarDecl * D)16697330f729Sjoerg void TextNodeDumper::VisitVarDecl(const VarDecl *D) {
16707330f729Sjoerg   dumpName(D);
16717330f729Sjoerg   dumpType(D->getType());
16727330f729Sjoerg   StorageClass SC = D->getStorageClass();
16737330f729Sjoerg   if (SC != SC_None)
16747330f729Sjoerg     OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
16757330f729Sjoerg   switch (D->getTLSKind()) {
16767330f729Sjoerg   case VarDecl::TLS_None:
16777330f729Sjoerg     break;
16787330f729Sjoerg   case VarDecl::TLS_Static:
16797330f729Sjoerg     OS << " tls";
16807330f729Sjoerg     break;
16817330f729Sjoerg   case VarDecl::TLS_Dynamic:
16827330f729Sjoerg     OS << " tls_dynamic";
16837330f729Sjoerg     break;
16847330f729Sjoerg   }
16857330f729Sjoerg   if (D->isModulePrivate())
16867330f729Sjoerg     OS << " __module_private__";
16877330f729Sjoerg   if (D->isNRVOVariable())
16887330f729Sjoerg     OS << " nrvo";
16897330f729Sjoerg   if (D->isInline())
16907330f729Sjoerg     OS << " inline";
16917330f729Sjoerg   if (D->isConstexpr())
16927330f729Sjoerg     OS << " constexpr";
16937330f729Sjoerg   if (D->hasInit()) {
16947330f729Sjoerg     switch (D->getInitStyle()) {
16957330f729Sjoerg     case VarDecl::CInit:
16967330f729Sjoerg       OS << " cinit";
16977330f729Sjoerg       break;
16987330f729Sjoerg     case VarDecl::CallInit:
16997330f729Sjoerg       OS << " callinit";
17007330f729Sjoerg       break;
17017330f729Sjoerg     case VarDecl::ListInit:
17027330f729Sjoerg       OS << " listinit";
17037330f729Sjoerg       break;
17047330f729Sjoerg     }
17057330f729Sjoerg   }
17067330f729Sjoerg   if (D->needsDestruction(D->getASTContext()))
17077330f729Sjoerg     OS << " destroyed";
17087330f729Sjoerg   if (D->isParameterPack())
17097330f729Sjoerg     OS << " pack";
1710*e038c9c4Sjoerg 
1711*e038c9c4Sjoerg   if (D->hasInit()) {
1712*e038c9c4Sjoerg     const Expr *E = D->getInit();
1713*e038c9c4Sjoerg     // Only dump the value of constexpr VarDecls for now.
1714*e038c9c4Sjoerg     if (E && !E->isValueDependent() && D->isConstexpr()) {
1715*e038c9c4Sjoerg       const APValue *Value = D->evaluateValue();
1716*e038c9c4Sjoerg       if (Value)
1717*e038c9c4Sjoerg         AddChild("value", [=] { Visit(*Value, E->getType()); });
1718*e038c9c4Sjoerg     }
1719*e038c9c4Sjoerg   }
17207330f729Sjoerg }
17217330f729Sjoerg 
VisitBindingDecl(const BindingDecl * D)17227330f729Sjoerg void TextNodeDumper::VisitBindingDecl(const BindingDecl *D) {
17237330f729Sjoerg   dumpName(D);
17247330f729Sjoerg   dumpType(D->getType());
17257330f729Sjoerg }
17267330f729Sjoerg 
VisitCapturedDecl(const CapturedDecl * D)17277330f729Sjoerg void TextNodeDumper::VisitCapturedDecl(const CapturedDecl *D) {
17287330f729Sjoerg   if (D->isNothrow())
17297330f729Sjoerg     OS << " nothrow";
17307330f729Sjoerg }
17317330f729Sjoerg 
VisitImportDecl(const ImportDecl * D)17327330f729Sjoerg void TextNodeDumper::VisitImportDecl(const ImportDecl *D) {
17337330f729Sjoerg   OS << ' ' << D->getImportedModule()->getFullModuleName();
17347330f729Sjoerg 
17357330f729Sjoerg   for (Decl *InitD :
17367330f729Sjoerg        D->getASTContext().getModuleInitializers(D->getImportedModule()))
17377330f729Sjoerg     dumpDeclRef(InitD, "initializer");
17387330f729Sjoerg }
17397330f729Sjoerg 
VisitPragmaCommentDecl(const PragmaCommentDecl * D)17407330f729Sjoerg void TextNodeDumper::VisitPragmaCommentDecl(const PragmaCommentDecl *D) {
17417330f729Sjoerg   OS << ' ';
17427330f729Sjoerg   switch (D->getCommentKind()) {
17437330f729Sjoerg   case PCK_Unknown:
17447330f729Sjoerg     llvm_unreachable("unexpected pragma comment kind");
17457330f729Sjoerg   case PCK_Compiler:
17467330f729Sjoerg     OS << "compiler";
17477330f729Sjoerg     break;
17487330f729Sjoerg   case PCK_ExeStr:
17497330f729Sjoerg     OS << "exestr";
17507330f729Sjoerg     break;
17517330f729Sjoerg   case PCK_Lib:
17527330f729Sjoerg     OS << "lib";
17537330f729Sjoerg     break;
17547330f729Sjoerg   case PCK_Linker:
17557330f729Sjoerg     OS << "linker";
17567330f729Sjoerg     break;
17577330f729Sjoerg   case PCK_User:
17587330f729Sjoerg     OS << "user";
17597330f729Sjoerg     break;
17607330f729Sjoerg   }
17617330f729Sjoerg   StringRef Arg = D->getArg();
17627330f729Sjoerg   if (!Arg.empty())
17637330f729Sjoerg     OS << " \"" << Arg << "\"";
17647330f729Sjoerg }
17657330f729Sjoerg 
VisitPragmaDetectMismatchDecl(const PragmaDetectMismatchDecl * D)17667330f729Sjoerg void TextNodeDumper::VisitPragmaDetectMismatchDecl(
17677330f729Sjoerg     const PragmaDetectMismatchDecl *D) {
17687330f729Sjoerg   OS << " \"" << D->getName() << "\" \"" << D->getValue() << "\"";
17697330f729Sjoerg }
17707330f729Sjoerg 
VisitOMPExecutableDirective(const OMPExecutableDirective * D)17717330f729Sjoerg void TextNodeDumper::VisitOMPExecutableDirective(
17727330f729Sjoerg     const OMPExecutableDirective *D) {
17737330f729Sjoerg   if (D->isStandaloneDirective())
17747330f729Sjoerg     OS << " openmp_standalone_directive";
17757330f729Sjoerg }
17767330f729Sjoerg 
VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl * D)17777330f729Sjoerg void TextNodeDumper::VisitOMPDeclareReductionDecl(
17787330f729Sjoerg     const OMPDeclareReductionDecl *D) {
17797330f729Sjoerg   dumpName(D);
17807330f729Sjoerg   dumpType(D->getType());
17817330f729Sjoerg   OS << " combiner";
17827330f729Sjoerg   dumpPointer(D->getCombiner());
17837330f729Sjoerg   if (const auto *Initializer = D->getInitializer()) {
17847330f729Sjoerg     OS << " initializer";
17857330f729Sjoerg     dumpPointer(Initializer);
17867330f729Sjoerg     switch (D->getInitializerKind()) {
17877330f729Sjoerg     case OMPDeclareReductionDecl::DirectInit:
17887330f729Sjoerg       OS << " omp_priv = ";
17897330f729Sjoerg       break;
17907330f729Sjoerg     case OMPDeclareReductionDecl::CopyInit:
17917330f729Sjoerg       OS << " omp_priv ()";
17927330f729Sjoerg       break;
17937330f729Sjoerg     case OMPDeclareReductionDecl::CallInit:
17947330f729Sjoerg       break;
17957330f729Sjoerg     }
17967330f729Sjoerg   }
17977330f729Sjoerg }
17987330f729Sjoerg 
VisitOMPRequiresDecl(const OMPRequiresDecl * D)17997330f729Sjoerg void TextNodeDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) {
18007330f729Sjoerg   for (const auto *C : D->clauselists()) {
18017330f729Sjoerg     AddChild([=] {
18027330f729Sjoerg       if (!C) {
18037330f729Sjoerg         ColorScope Color(OS, ShowColors, NullColor);
18047330f729Sjoerg         OS << "<<<NULL>>> OMPClause";
18057330f729Sjoerg         return;
18067330f729Sjoerg       }
18077330f729Sjoerg       {
18087330f729Sjoerg         ColorScope Color(OS, ShowColors, AttrColor);
1809*e038c9c4Sjoerg         StringRef ClauseName(
1810*e038c9c4Sjoerg             llvm::omp::getOpenMPClauseName(C->getClauseKind()));
18117330f729Sjoerg         OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
18127330f729Sjoerg            << ClauseName.drop_front() << "Clause";
18137330f729Sjoerg       }
18147330f729Sjoerg       dumpPointer(C);
18157330f729Sjoerg       dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
18167330f729Sjoerg     });
18177330f729Sjoerg   }
18187330f729Sjoerg }
18197330f729Sjoerg 
VisitOMPCapturedExprDecl(const OMPCapturedExprDecl * D)18207330f729Sjoerg void TextNodeDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
18217330f729Sjoerg   dumpName(D);
18227330f729Sjoerg   dumpType(D->getType());
18237330f729Sjoerg }
18247330f729Sjoerg 
VisitNamespaceDecl(const NamespaceDecl * D)18257330f729Sjoerg void TextNodeDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
18267330f729Sjoerg   dumpName(D);
18277330f729Sjoerg   if (D->isInline())
18287330f729Sjoerg     OS << " inline";
18297330f729Sjoerg   if (!D->isOriginalNamespace())
18307330f729Sjoerg     dumpDeclRef(D->getOriginalNamespace(), "original");
18317330f729Sjoerg }
18327330f729Sjoerg 
VisitUsingDirectiveDecl(const UsingDirectiveDecl * D)18337330f729Sjoerg void TextNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
18347330f729Sjoerg   OS << ' ';
18357330f729Sjoerg   dumpBareDeclRef(D->getNominatedNamespace());
18367330f729Sjoerg }
18377330f729Sjoerg 
VisitNamespaceAliasDecl(const NamespaceAliasDecl * D)18387330f729Sjoerg void TextNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
18397330f729Sjoerg   dumpName(D);
18407330f729Sjoerg   dumpDeclRef(D->getAliasedNamespace());
18417330f729Sjoerg }
18427330f729Sjoerg 
VisitTypeAliasDecl(const TypeAliasDecl * D)18437330f729Sjoerg void TextNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
18447330f729Sjoerg   dumpName(D);
18457330f729Sjoerg   dumpType(D->getUnderlyingType());
18467330f729Sjoerg }
18477330f729Sjoerg 
VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl * D)18487330f729Sjoerg void TextNodeDumper::VisitTypeAliasTemplateDecl(
18497330f729Sjoerg     const TypeAliasTemplateDecl *D) {
18507330f729Sjoerg   dumpName(D);
18517330f729Sjoerg }
18527330f729Sjoerg 
VisitCXXRecordDecl(const CXXRecordDecl * D)18537330f729Sjoerg void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
18547330f729Sjoerg   VisitRecordDecl(D);
18557330f729Sjoerg   if (!D->isCompleteDefinition())
18567330f729Sjoerg     return;
18577330f729Sjoerg 
18587330f729Sjoerg   AddChild([=] {
18597330f729Sjoerg     {
18607330f729Sjoerg       ColorScope Color(OS, ShowColors, DeclKindNameColor);
18617330f729Sjoerg       OS << "DefinitionData";
18627330f729Sjoerg     }
18637330f729Sjoerg #define FLAG(fn, name)                                                         \
18647330f729Sjoerg   if (D->fn())                                                                 \
18657330f729Sjoerg     OS << " " #name;
18667330f729Sjoerg     FLAG(isParsingBaseSpecifiers, parsing_base_specifiers);
18677330f729Sjoerg 
18687330f729Sjoerg     FLAG(isGenericLambda, generic);
18697330f729Sjoerg     FLAG(isLambda, lambda);
18707330f729Sjoerg 
18717330f729Sjoerg     FLAG(isAnonymousStructOrUnion, is_anonymous);
18727330f729Sjoerg     FLAG(canPassInRegisters, pass_in_registers);
18737330f729Sjoerg     FLAG(isEmpty, empty);
18747330f729Sjoerg     FLAG(isAggregate, aggregate);
18757330f729Sjoerg     FLAG(isStandardLayout, standard_layout);
18767330f729Sjoerg     FLAG(isTriviallyCopyable, trivially_copyable);
18777330f729Sjoerg     FLAG(isPOD, pod);
18787330f729Sjoerg     FLAG(isTrivial, trivial);
18797330f729Sjoerg     FLAG(isPolymorphic, polymorphic);
18807330f729Sjoerg     FLAG(isAbstract, abstract);
18817330f729Sjoerg     FLAG(isLiteral, literal);
18827330f729Sjoerg 
18837330f729Sjoerg     FLAG(hasUserDeclaredConstructor, has_user_declared_ctor);
18847330f729Sjoerg     FLAG(hasConstexprNonCopyMoveConstructor, has_constexpr_non_copy_move_ctor);
18857330f729Sjoerg     FLAG(hasMutableFields, has_mutable_fields);
18867330f729Sjoerg     FLAG(hasVariantMembers, has_variant_members);
18877330f729Sjoerg     FLAG(allowConstDefaultInit, can_const_default_init);
18887330f729Sjoerg 
18897330f729Sjoerg     AddChild([=] {
18907330f729Sjoerg       {
18917330f729Sjoerg         ColorScope Color(OS, ShowColors, DeclKindNameColor);
18927330f729Sjoerg         OS << "DefaultConstructor";
18937330f729Sjoerg       }
18947330f729Sjoerg       FLAG(hasDefaultConstructor, exists);
18957330f729Sjoerg       FLAG(hasTrivialDefaultConstructor, trivial);
18967330f729Sjoerg       FLAG(hasNonTrivialDefaultConstructor, non_trivial);
18977330f729Sjoerg       FLAG(hasUserProvidedDefaultConstructor, user_provided);
18987330f729Sjoerg       FLAG(hasConstexprDefaultConstructor, constexpr);
18997330f729Sjoerg       FLAG(needsImplicitDefaultConstructor, needs_implicit);
19007330f729Sjoerg       FLAG(defaultedDefaultConstructorIsConstexpr, defaulted_is_constexpr);
19017330f729Sjoerg     });
19027330f729Sjoerg 
19037330f729Sjoerg     AddChild([=] {
19047330f729Sjoerg       {
19057330f729Sjoerg         ColorScope Color(OS, ShowColors, DeclKindNameColor);
19067330f729Sjoerg         OS << "CopyConstructor";
19077330f729Sjoerg       }
19087330f729Sjoerg       FLAG(hasSimpleCopyConstructor, simple);
19097330f729Sjoerg       FLAG(hasTrivialCopyConstructor, trivial);
19107330f729Sjoerg       FLAG(hasNonTrivialCopyConstructor, non_trivial);
19117330f729Sjoerg       FLAG(hasUserDeclaredCopyConstructor, user_declared);
19127330f729Sjoerg       FLAG(hasCopyConstructorWithConstParam, has_const_param);
19137330f729Sjoerg       FLAG(needsImplicitCopyConstructor, needs_implicit);
19147330f729Sjoerg       FLAG(needsOverloadResolutionForCopyConstructor,
19157330f729Sjoerg            needs_overload_resolution);
19167330f729Sjoerg       if (!D->needsOverloadResolutionForCopyConstructor())
19177330f729Sjoerg         FLAG(defaultedCopyConstructorIsDeleted, defaulted_is_deleted);
19187330f729Sjoerg       FLAG(implicitCopyConstructorHasConstParam, implicit_has_const_param);
19197330f729Sjoerg     });
19207330f729Sjoerg 
19217330f729Sjoerg     AddChild([=] {
19227330f729Sjoerg       {
19237330f729Sjoerg         ColorScope Color(OS, ShowColors, DeclKindNameColor);
19247330f729Sjoerg         OS << "MoveConstructor";
19257330f729Sjoerg       }
19267330f729Sjoerg       FLAG(hasMoveConstructor, exists);
19277330f729Sjoerg       FLAG(hasSimpleMoveConstructor, simple);
19287330f729Sjoerg       FLAG(hasTrivialMoveConstructor, trivial);
19297330f729Sjoerg       FLAG(hasNonTrivialMoveConstructor, non_trivial);
19307330f729Sjoerg       FLAG(hasUserDeclaredMoveConstructor, user_declared);
19317330f729Sjoerg       FLAG(needsImplicitMoveConstructor, needs_implicit);
19327330f729Sjoerg       FLAG(needsOverloadResolutionForMoveConstructor,
19337330f729Sjoerg            needs_overload_resolution);
19347330f729Sjoerg       if (!D->needsOverloadResolutionForMoveConstructor())
19357330f729Sjoerg         FLAG(defaultedMoveConstructorIsDeleted, defaulted_is_deleted);
19367330f729Sjoerg     });
19377330f729Sjoerg 
19387330f729Sjoerg     AddChild([=] {
19397330f729Sjoerg       {
19407330f729Sjoerg         ColorScope Color(OS, ShowColors, DeclKindNameColor);
19417330f729Sjoerg         OS << "CopyAssignment";
19427330f729Sjoerg       }
1943*e038c9c4Sjoerg       FLAG(hasSimpleCopyAssignment, simple);
19447330f729Sjoerg       FLAG(hasTrivialCopyAssignment, trivial);
19457330f729Sjoerg       FLAG(hasNonTrivialCopyAssignment, non_trivial);
19467330f729Sjoerg       FLAG(hasCopyAssignmentWithConstParam, has_const_param);
19477330f729Sjoerg       FLAG(hasUserDeclaredCopyAssignment, user_declared);
19487330f729Sjoerg       FLAG(needsImplicitCopyAssignment, needs_implicit);
19497330f729Sjoerg       FLAG(needsOverloadResolutionForCopyAssignment, needs_overload_resolution);
19507330f729Sjoerg       FLAG(implicitCopyAssignmentHasConstParam, implicit_has_const_param);
19517330f729Sjoerg     });
19527330f729Sjoerg 
19537330f729Sjoerg     AddChild([=] {
19547330f729Sjoerg       {
19557330f729Sjoerg         ColorScope Color(OS, ShowColors, DeclKindNameColor);
19567330f729Sjoerg         OS << "MoveAssignment";
19577330f729Sjoerg       }
19587330f729Sjoerg       FLAG(hasMoveAssignment, exists);
19597330f729Sjoerg       FLAG(hasSimpleMoveAssignment, simple);
19607330f729Sjoerg       FLAG(hasTrivialMoveAssignment, trivial);
19617330f729Sjoerg       FLAG(hasNonTrivialMoveAssignment, non_trivial);
19627330f729Sjoerg       FLAG(hasUserDeclaredMoveAssignment, user_declared);
19637330f729Sjoerg       FLAG(needsImplicitMoveAssignment, needs_implicit);
19647330f729Sjoerg       FLAG(needsOverloadResolutionForMoveAssignment, needs_overload_resolution);
19657330f729Sjoerg     });
19667330f729Sjoerg 
19677330f729Sjoerg     AddChild([=] {
19687330f729Sjoerg       {
19697330f729Sjoerg         ColorScope Color(OS, ShowColors, DeclKindNameColor);
19707330f729Sjoerg         OS << "Destructor";
19717330f729Sjoerg       }
19727330f729Sjoerg       FLAG(hasSimpleDestructor, simple);
19737330f729Sjoerg       FLAG(hasIrrelevantDestructor, irrelevant);
19747330f729Sjoerg       FLAG(hasTrivialDestructor, trivial);
19757330f729Sjoerg       FLAG(hasNonTrivialDestructor, non_trivial);
19767330f729Sjoerg       FLAG(hasUserDeclaredDestructor, user_declared);
19777330f729Sjoerg       FLAG(hasConstexprDestructor, constexpr);
19787330f729Sjoerg       FLAG(needsImplicitDestructor, needs_implicit);
19797330f729Sjoerg       FLAG(needsOverloadResolutionForDestructor, needs_overload_resolution);
19807330f729Sjoerg       if (!D->needsOverloadResolutionForDestructor())
19817330f729Sjoerg         FLAG(defaultedDestructorIsDeleted, defaulted_is_deleted);
19827330f729Sjoerg     });
19837330f729Sjoerg   });
19847330f729Sjoerg 
19857330f729Sjoerg   for (const auto &I : D->bases()) {
19867330f729Sjoerg     AddChild([=] {
19877330f729Sjoerg       if (I.isVirtual())
19887330f729Sjoerg         OS << "virtual ";
19897330f729Sjoerg       dumpAccessSpecifier(I.getAccessSpecifier());
19907330f729Sjoerg       dumpType(I.getType());
19917330f729Sjoerg       if (I.isPackExpansion())
19927330f729Sjoerg         OS << "...";
19937330f729Sjoerg     });
19947330f729Sjoerg   }
19957330f729Sjoerg }
19967330f729Sjoerg 
VisitFunctionTemplateDecl(const FunctionTemplateDecl * D)19977330f729Sjoerg void TextNodeDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
19987330f729Sjoerg   dumpName(D);
19997330f729Sjoerg }
20007330f729Sjoerg 
VisitClassTemplateDecl(const ClassTemplateDecl * D)20017330f729Sjoerg void TextNodeDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
20027330f729Sjoerg   dumpName(D);
20037330f729Sjoerg }
20047330f729Sjoerg 
VisitVarTemplateDecl(const VarTemplateDecl * D)20057330f729Sjoerg void TextNodeDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
20067330f729Sjoerg   dumpName(D);
20077330f729Sjoerg }
20087330f729Sjoerg 
VisitBuiltinTemplateDecl(const BuiltinTemplateDecl * D)20097330f729Sjoerg void TextNodeDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
20107330f729Sjoerg   dumpName(D);
20117330f729Sjoerg }
20127330f729Sjoerg 
VisitTemplateTypeParmDecl(const TemplateTypeParmDecl * D)20137330f729Sjoerg void TextNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
2014*e038c9c4Sjoerg   if (const auto *TC = D->getTypeConstraint()) {
2015*e038c9c4Sjoerg     OS << " ";
2016*e038c9c4Sjoerg     dumpBareDeclRef(TC->getNamedConcept());
2017*e038c9c4Sjoerg     if (TC->getNamedConcept() != TC->getFoundDecl()) {
2018*e038c9c4Sjoerg       OS << " (";
2019*e038c9c4Sjoerg       dumpBareDeclRef(TC->getFoundDecl());
2020*e038c9c4Sjoerg       OS << ")";
2021*e038c9c4Sjoerg     }
2022*e038c9c4Sjoerg   } else if (D->wasDeclaredWithTypename())
20237330f729Sjoerg     OS << " typename";
20247330f729Sjoerg   else
20257330f729Sjoerg     OS << " class";
20267330f729Sjoerg   OS << " depth " << D->getDepth() << " index " << D->getIndex();
20277330f729Sjoerg   if (D->isParameterPack())
20287330f729Sjoerg     OS << " ...";
20297330f729Sjoerg   dumpName(D);
20307330f729Sjoerg }
20317330f729Sjoerg 
VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl * D)20327330f729Sjoerg void TextNodeDumper::VisitNonTypeTemplateParmDecl(
20337330f729Sjoerg     const NonTypeTemplateParmDecl *D) {
20347330f729Sjoerg   dumpType(D->getType());
20357330f729Sjoerg   OS << " depth " << D->getDepth() << " index " << D->getIndex();
20367330f729Sjoerg   if (D->isParameterPack())
20377330f729Sjoerg     OS << " ...";
20387330f729Sjoerg   dumpName(D);
20397330f729Sjoerg }
20407330f729Sjoerg 
VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl * D)20417330f729Sjoerg void TextNodeDumper::VisitTemplateTemplateParmDecl(
20427330f729Sjoerg     const TemplateTemplateParmDecl *D) {
20437330f729Sjoerg   OS << " depth " << D->getDepth() << " index " << D->getIndex();
20447330f729Sjoerg   if (D->isParameterPack())
20457330f729Sjoerg     OS << " ...";
20467330f729Sjoerg   dumpName(D);
20477330f729Sjoerg }
20487330f729Sjoerg 
VisitUsingDecl(const UsingDecl * D)20497330f729Sjoerg void TextNodeDumper::VisitUsingDecl(const UsingDecl *D) {
20507330f729Sjoerg   OS << ' ';
20517330f729Sjoerg   if (D->getQualifier())
20527330f729Sjoerg     D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2053*e038c9c4Sjoerg   OS << D->getDeclName();
20547330f729Sjoerg }
20557330f729Sjoerg 
VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl * D)20567330f729Sjoerg void TextNodeDumper::VisitUnresolvedUsingTypenameDecl(
20577330f729Sjoerg     const UnresolvedUsingTypenameDecl *D) {
20587330f729Sjoerg   OS << ' ';
20597330f729Sjoerg   if (D->getQualifier())
20607330f729Sjoerg     D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2061*e038c9c4Sjoerg   OS << D->getDeclName();
20627330f729Sjoerg }
20637330f729Sjoerg 
VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl * D)20647330f729Sjoerg void TextNodeDumper::VisitUnresolvedUsingValueDecl(
20657330f729Sjoerg     const UnresolvedUsingValueDecl *D) {
20667330f729Sjoerg   OS << ' ';
20677330f729Sjoerg   if (D->getQualifier())
20687330f729Sjoerg     D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
2069*e038c9c4Sjoerg   OS << D->getDeclName();
20707330f729Sjoerg   dumpType(D->getType());
20717330f729Sjoerg }
20727330f729Sjoerg 
VisitUsingShadowDecl(const UsingShadowDecl * D)20737330f729Sjoerg void TextNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
20747330f729Sjoerg   OS << ' ';
20757330f729Sjoerg   dumpBareDeclRef(D->getTargetDecl());
20767330f729Sjoerg }
20777330f729Sjoerg 
VisitConstructorUsingShadowDecl(const ConstructorUsingShadowDecl * D)20787330f729Sjoerg void TextNodeDumper::VisitConstructorUsingShadowDecl(
20797330f729Sjoerg     const ConstructorUsingShadowDecl *D) {
20807330f729Sjoerg   if (D->constructsVirtualBase())
20817330f729Sjoerg     OS << " virtual";
20827330f729Sjoerg 
20837330f729Sjoerg   AddChild([=] {
20847330f729Sjoerg     OS << "target ";
20857330f729Sjoerg     dumpBareDeclRef(D->getTargetDecl());
20867330f729Sjoerg   });
20877330f729Sjoerg 
20887330f729Sjoerg   AddChild([=] {
20897330f729Sjoerg     OS << "nominated ";
20907330f729Sjoerg     dumpBareDeclRef(D->getNominatedBaseClass());
20917330f729Sjoerg     OS << ' ';
20927330f729Sjoerg     dumpBareDeclRef(D->getNominatedBaseClassShadowDecl());
20937330f729Sjoerg   });
20947330f729Sjoerg 
20957330f729Sjoerg   AddChild([=] {
20967330f729Sjoerg     OS << "constructed ";
20977330f729Sjoerg     dumpBareDeclRef(D->getConstructedBaseClass());
20987330f729Sjoerg     OS << ' ';
20997330f729Sjoerg     dumpBareDeclRef(D->getConstructedBaseClassShadowDecl());
21007330f729Sjoerg   });
21017330f729Sjoerg }
21027330f729Sjoerg 
VisitLinkageSpecDecl(const LinkageSpecDecl * D)21037330f729Sjoerg void TextNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
21047330f729Sjoerg   switch (D->getLanguage()) {
21057330f729Sjoerg   case LinkageSpecDecl::lang_c:
21067330f729Sjoerg     OS << " C";
21077330f729Sjoerg     break;
21087330f729Sjoerg   case LinkageSpecDecl::lang_cxx:
21097330f729Sjoerg     OS << " C++";
21107330f729Sjoerg     break;
21117330f729Sjoerg   }
21127330f729Sjoerg }
21137330f729Sjoerg 
VisitAccessSpecDecl(const AccessSpecDecl * D)21147330f729Sjoerg void TextNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
21157330f729Sjoerg   OS << ' ';
21167330f729Sjoerg   dumpAccessSpecifier(D->getAccess());
21177330f729Sjoerg }
21187330f729Sjoerg 
VisitFriendDecl(const FriendDecl * D)21197330f729Sjoerg void TextNodeDumper::VisitFriendDecl(const FriendDecl *D) {
21207330f729Sjoerg   if (TypeSourceInfo *T = D->getFriendType())
21217330f729Sjoerg     dumpType(T->getType());
21227330f729Sjoerg }
21237330f729Sjoerg 
VisitObjCIvarDecl(const ObjCIvarDecl * D)21247330f729Sjoerg void TextNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
21257330f729Sjoerg   dumpName(D);
21267330f729Sjoerg   dumpType(D->getType());
21277330f729Sjoerg   if (D->getSynthesize())
21287330f729Sjoerg     OS << " synthesize";
21297330f729Sjoerg 
21307330f729Sjoerg   switch (D->getAccessControl()) {
21317330f729Sjoerg   case ObjCIvarDecl::None:
21327330f729Sjoerg     OS << " none";
21337330f729Sjoerg     break;
21347330f729Sjoerg   case ObjCIvarDecl::Private:
21357330f729Sjoerg     OS << " private";
21367330f729Sjoerg     break;
21377330f729Sjoerg   case ObjCIvarDecl::Protected:
21387330f729Sjoerg     OS << " protected";
21397330f729Sjoerg     break;
21407330f729Sjoerg   case ObjCIvarDecl::Public:
21417330f729Sjoerg     OS << " public";
21427330f729Sjoerg     break;
21437330f729Sjoerg   case ObjCIvarDecl::Package:
21447330f729Sjoerg     OS << " package";
21457330f729Sjoerg     break;
21467330f729Sjoerg   }
21477330f729Sjoerg }
21487330f729Sjoerg 
VisitObjCMethodDecl(const ObjCMethodDecl * D)21497330f729Sjoerg void TextNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
21507330f729Sjoerg   if (D->isInstanceMethod())
21517330f729Sjoerg     OS << " -";
21527330f729Sjoerg   else
21537330f729Sjoerg     OS << " +";
21547330f729Sjoerg   dumpName(D);
21557330f729Sjoerg   dumpType(D->getReturnType());
21567330f729Sjoerg 
21577330f729Sjoerg   if (D->isVariadic())
21587330f729Sjoerg     OS << " variadic";
21597330f729Sjoerg }
21607330f729Sjoerg 
VisitObjCTypeParamDecl(const ObjCTypeParamDecl * D)21617330f729Sjoerg void TextNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
21627330f729Sjoerg   dumpName(D);
21637330f729Sjoerg   switch (D->getVariance()) {
21647330f729Sjoerg   case ObjCTypeParamVariance::Invariant:
21657330f729Sjoerg     break;
21667330f729Sjoerg 
21677330f729Sjoerg   case ObjCTypeParamVariance::Covariant:
21687330f729Sjoerg     OS << " covariant";
21697330f729Sjoerg     break;
21707330f729Sjoerg 
21717330f729Sjoerg   case ObjCTypeParamVariance::Contravariant:
21727330f729Sjoerg     OS << " contravariant";
21737330f729Sjoerg     break;
21747330f729Sjoerg   }
21757330f729Sjoerg 
21767330f729Sjoerg   if (D->hasExplicitBound())
21777330f729Sjoerg     OS << " bounded";
21787330f729Sjoerg   dumpType(D->getUnderlyingType());
21797330f729Sjoerg }
21807330f729Sjoerg 
VisitObjCCategoryDecl(const ObjCCategoryDecl * D)21817330f729Sjoerg void TextNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
21827330f729Sjoerg   dumpName(D);
21837330f729Sjoerg   dumpDeclRef(D->getClassInterface());
21847330f729Sjoerg   dumpDeclRef(D->getImplementation());
21857330f729Sjoerg   for (const auto *P : D->protocols())
21867330f729Sjoerg     dumpDeclRef(P);
21877330f729Sjoerg }
21887330f729Sjoerg 
VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl * D)21897330f729Sjoerg void TextNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
21907330f729Sjoerg   dumpName(D);
21917330f729Sjoerg   dumpDeclRef(D->getClassInterface());
21927330f729Sjoerg   dumpDeclRef(D->getCategoryDecl());
21937330f729Sjoerg }
21947330f729Sjoerg 
VisitObjCProtocolDecl(const ObjCProtocolDecl * D)21957330f729Sjoerg void TextNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
21967330f729Sjoerg   dumpName(D);
21977330f729Sjoerg 
21987330f729Sjoerg   for (const auto *Child : D->protocols())
21997330f729Sjoerg     dumpDeclRef(Child);
22007330f729Sjoerg }
22017330f729Sjoerg 
VisitObjCInterfaceDecl(const ObjCInterfaceDecl * D)22027330f729Sjoerg void TextNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
22037330f729Sjoerg   dumpName(D);
22047330f729Sjoerg   dumpDeclRef(D->getSuperClass(), "super");
22057330f729Sjoerg 
22067330f729Sjoerg   dumpDeclRef(D->getImplementation());
22077330f729Sjoerg   for (const auto *Child : D->protocols())
22087330f729Sjoerg     dumpDeclRef(Child);
22097330f729Sjoerg }
22107330f729Sjoerg 
VisitObjCImplementationDecl(const ObjCImplementationDecl * D)22117330f729Sjoerg void TextNodeDumper::VisitObjCImplementationDecl(
22127330f729Sjoerg     const ObjCImplementationDecl *D) {
22137330f729Sjoerg   dumpName(D);
22147330f729Sjoerg   dumpDeclRef(D->getSuperClass(), "super");
22157330f729Sjoerg   dumpDeclRef(D->getClassInterface());
22167330f729Sjoerg }
22177330f729Sjoerg 
VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl * D)22187330f729Sjoerg void TextNodeDumper::VisitObjCCompatibleAliasDecl(
22197330f729Sjoerg     const ObjCCompatibleAliasDecl *D) {
22207330f729Sjoerg   dumpName(D);
22217330f729Sjoerg   dumpDeclRef(D->getClassInterface());
22227330f729Sjoerg }
22237330f729Sjoerg 
VisitObjCPropertyDecl(const ObjCPropertyDecl * D)22247330f729Sjoerg void TextNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
22257330f729Sjoerg   dumpName(D);
22267330f729Sjoerg   dumpType(D->getType());
22277330f729Sjoerg 
22287330f729Sjoerg   if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
22297330f729Sjoerg     OS << " required";
22307330f729Sjoerg   else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
22317330f729Sjoerg     OS << " optional";
22327330f729Sjoerg 
2233*e038c9c4Sjoerg   ObjCPropertyAttribute::Kind Attrs = D->getPropertyAttributes();
2234*e038c9c4Sjoerg   if (Attrs != ObjCPropertyAttribute::kind_noattr) {
2235*e038c9c4Sjoerg     if (Attrs & ObjCPropertyAttribute::kind_readonly)
22367330f729Sjoerg       OS << " readonly";
2237*e038c9c4Sjoerg     if (Attrs & ObjCPropertyAttribute::kind_assign)
22387330f729Sjoerg       OS << " assign";
2239*e038c9c4Sjoerg     if (Attrs & ObjCPropertyAttribute::kind_readwrite)
22407330f729Sjoerg       OS << " readwrite";
2241*e038c9c4Sjoerg     if (Attrs & ObjCPropertyAttribute::kind_retain)
22427330f729Sjoerg       OS << " retain";
2243*e038c9c4Sjoerg     if (Attrs & ObjCPropertyAttribute::kind_copy)
22447330f729Sjoerg       OS << " copy";
2245*e038c9c4Sjoerg     if (Attrs & ObjCPropertyAttribute::kind_nonatomic)
22467330f729Sjoerg       OS << " nonatomic";
2247*e038c9c4Sjoerg     if (Attrs & ObjCPropertyAttribute::kind_atomic)
22487330f729Sjoerg       OS << " atomic";
2249*e038c9c4Sjoerg     if (Attrs & ObjCPropertyAttribute::kind_weak)
22507330f729Sjoerg       OS << " weak";
2251*e038c9c4Sjoerg     if (Attrs & ObjCPropertyAttribute::kind_strong)
22527330f729Sjoerg       OS << " strong";
2253*e038c9c4Sjoerg     if (Attrs & ObjCPropertyAttribute::kind_unsafe_unretained)
22547330f729Sjoerg       OS << " unsafe_unretained";
2255*e038c9c4Sjoerg     if (Attrs & ObjCPropertyAttribute::kind_class)
22567330f729Sjoerg       OS << " class";
2257*e038c9c4Sjoerg     if (Attrs & ObjCPropertyAttribute::kind_direct)
2258*e038c9c4Sjoerg       OS << " direct";
2259*e038c9c4Sjoerg     if (Attrs & ObjCPropertyAttribute::kind_getter)
22607330f729Sjoerg       dumpDeclRef(D->getGetterMethodDecl(), "getter");
2261*e038c9c4Sjoerg     if (Attrs & ObjCPropertyAttribute::kind_setter)
22627330f729Sjoerg       dumpDeclRef(D->getSetterMethodDecl(), "setter");
22637330f729Sjoerg   }
22647330f729Sjoerg }
22657330f729Sjoerg 
VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl * D)22667330f729Sjoerg void TextNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
22677330f729Sjoerg   dumpName(D->getPropertyDecl());
22687330f729Sjoerg   if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
22697330f729Sjoerg     OS << " synthesize";
22707330f729Sjoerg   else
22717330f729Sjoerg     OS << " dynamic";
22727330f729Sjoerg   dumpDeclRef(D->getPropertyDecl());
22737330f729Sjoerg   dumpDeclRef(D->getPropertyIvarDecl());
22747330f729Sjoerg }
22757330f729Sjoerg 
VisitBlockDecl(const BlockDecl * D)22767330f729Sjoerg void TextNodeDumper::VisitBlockDecl(const BlockDecl *D) {
22777330f729Sjoerg   if (D->isVariadic())
22787330f729Sjoerg     OS << " variadic";
22797330f729Sjoerg 
22807330f729Sjoerg   if (D->capturesCXXThis())
22817330f729Sjoerg     OS << " captures_this";
22827330f729Sjoerg }
22837330f729Sjoerg 
VisitConceptDecl(const ConceptDecl * D)22847330f729Sjoerg void TextNodeDumper::VisitConceptDecl(const ConceptDecl *D) {
22857330f729Sjoerg   dumpName(D);
22867330f729Sjoerg }
2287