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