10b57cec5SDimitry Andric //===- StmtPrinter.cpp - Printing implementation for Stmt ASTs ------------===// 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 the Stmt::dumpPretty/Stmt::printPretty methods, which 100b57cec5SDimitry Andric // pretty print the AST back out to C code. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "clang/AST/ASTContext.h" 150b57cec5SDimitry Andric #include "clang/AST/Attr.h" 160b57cec5SDimitry Andric #include "clang/AST/Decl.h" 170b57cec5SDimitry Andric #include "clang/AST/DeclBase.h" 180b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h" 190b57cec5SDimitry Andric #include "clang/AST/DeclObjC.h" 200b57cec5SDimitry Andric #include "clang/AST/DeclOpenMP.h" 210b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h" 220b57cec5SDimitry Andric #include "clang/AST/Expr.h" 230b57cec5SDimitry Andric #include "clang/AST/ExprCXX.h" 240b57cec5SDimitry Andric #include "clang/AST/ExprObjC.h" 250b57cec5SDimitry Andric #include "clang/AST/ExprOpenMP.h" 260b57cec5SDimitry Andric #include "clang/AST/NestedNameSpecifier.h" 270b57cec5SDimitry Andric #include "clang/AST/OpenMPClause.h" 280b57cec5SDimitry Andric #include "clang/AST/PrettyPrinter.h" 290b57cec5SDimitry Andric #include "clang/AST/Stmt.h" 300b57cec5SDimitry Andric #include "clang/AST/StmtCXX.h" 310b57cec5SDimitry Andric #include "clang/AST/StmtObjC.h" 320b57cec5SDimitry Andric #include "clang/AST/StmtOpenMP.h" 330b57cec5SDimitry Andric #include "clang/AST/StmtVisitor.h" 340b57cec5SDimitry Andric #include "clang/AST/TemplateBase.h" 350b57cec5SDimitry Andric #include "clang/AST/Type.h" 360b57cec5SDimitry Andric #include "clang/Basic/CharInfo.h" 370b57cec5SDimitry Andric #include "clang/Basic/ExpressionTraits.h" 380b57cec5SDimitry Andric #include "clang/Basic/IdentifierTable.h" 390b57cec5SDimitry Andric #include "clang/Basic/JsonSupport.h" 400b57cec5SDimitry Andric #include "clang/Basic/LLVM.h" 410b57cec5SDimitry Andric #include "clang/Basic/Lambda.h" 420b57cec5SDimitry Andric #include "clang/Basic/OpenMPKinds.h" 430b57cec5SDimitry Andric #include "clang/Basic/OperatorKinds.h" 440b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h" 450b57cec5SDimitry Andric #include "clang/Basic/TypeTraits.h" 460b57cec5SDimitry Andric #include "clang/Lex/Lexer.h" 470b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 480b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h" 490b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 50fe6060f1SDimitry Andric #include "llvm/ADT/StringExtras.h" 510b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 520b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 530b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 540b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 550b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 560b57cec5SDimitry Andric #include <cassert> 57bdd1243dSDimitry Andric #include <optional> 580b57cec5SDimitry Andric #include <string> 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric using namespace clang; 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 630b57cec5SDimitry Andric // StmtPrinter Visitor 640b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric namespace { 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric class StmtPrinter : public StmtVisitor<StmtPrinter> { 690b57cec5SDimitry Andric raw_ostream &OS; 700b57cec5SDimitry Andric unsigned IndentLevel; 710b57cec5SDimitry Andric PrinterHelper* Helper; 720b57cec5SDimitry Andric PrintingPolicy Policy; 730b57cec5SDimitry Andric std::string NL; 740b57cec5SDimitry Andric const ASTContext *Context; 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric public: 770b57cec5SDimitry Andric StmtPrinter(raw_ostream &os, PrinterHelper *helper, 780b57cec5SDimitry Andric const PrintingPolicy &Policy, unsigned Indentation = 0, 795ffd83dbSDimitry Andric StringRef NL = "\n", const ASTContext *Context = nullptr) 800b57cec5SDimitry Andric : OS(os), IndentLevel(Indentation), Helper(helper), Policy(Policy), 810b57cec5SDimitry Andric NL(NL), Context(Context) {} 820b57cec5SDimitry Andric 835ffd83dbSDimitry Andric void PrintStmt(Stmt *S) { PrintStmt(S, Policy.Indentation); } 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric void PrintStmt(Stmt *S, int SubIndent) { 860b57cec5SDimitry Andric IndentLevel += SubIndent; 87*0fca6ea1SDimitry Andric if (isa_and_nonnull<Expr>(S)) { 880b57cec5SDimitry Andric // If this is an expr used in a stmt context, indent and newline it. 890b57cec5SDimitry Andric Indent(); 900b57cec5SDimitry Andric Visit(S); 910b57cec5SDimitry Andric OS << ";" << NL; 920b57cec5SDimitry Andric } else if (S) { 930b57cec5SDimitry Andric Visit(S); 940b57cec5SDimitry Andric } else { 950b57cec5SDimitry Andric Indent() << "<<<NULL STATEMENT>>>" << NL; 960b57cec5SDimitry Andric } 970b57cec5SDimitry Andric IndentLevel -= SubIndent; 980b57cec5SDimitry Andric } 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric void PrintInitStmt(Stmt *S, unsigned PrefixWidth) { 1010b57cec5SDimitry Andric // FIXME: Cope better with odd prefix widths. 1020b57cec5SDimitry Andric IndentLevel += (PrefixWidth + 1) / 2; 1030b57cec5SDimitry Andric if (auto *DS = dyn_cast<DeclStmt>(S)) 1040b57cec5SDimitry Andric PrintRawDeclStmt(DS); 1050b57cec5SDimitry Andric else 1060b57cec5SDimitry Andric PrintExpr(cast<Expr>(S)); 1070b57cec5SDimitry Andric OS << "; "; 1080b57cec5SDimitry Andric IndentLevel -= (PrefixWidth + 1) / 2; 1090b57cec5SDimitry Andric } 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric void PrintControlledStmt(Stmt *S) { 1120b57cec5SDimitry Andric if (auto *CS = dyn_cast<CompoundStmt>(S)) { 1130b57cec5SDimitry Andric OS << " "; 1140b57cec5SDimitry Andric PrintRawCompoundStmt(CS); 1150b57cec5SDimitry Andric OS << NL; 1160b57cec5SDimitry Andric } else { 1170b57cec5SDimitry Andric OS << NL; 1180b57cec5SDimitry Andric PrintStmt(S); 1190b57cec5SDimitry Andric } 1200b57cec5SDimitry Andric } 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric void PrintRawCompoundStmt(CompoundStmt *S); 1230b57cec5SDimitry Andric void PrintRawDecl(Decl *D); 1240b57cec5SDimitry Andric void PrintRawDeclStmt(const DeclStmt *S); 1250b57cec5SDimitry Andric void PrintRawIfStmt(IfStmt *If); 1260b57cec5SDimitry Andric void PrintRawCXXCatchStmt(CXXCatchStmt *Catch); 1270b57cec5SDimitry Andric void PrintCallArgs(CallExpr *E); 1280b57cec5SDimitry Andric void PrintRawSEHExceptHandler(SEHExceptStmt *S); 1290b57cec5SDimitry Andric void PrintRawSEHFinallyStmt(SEHFinallyStmt *S); 1300b57cec5SDimitry Andric void PrintOMPExecutableDirective(OMPExecutableDirective *S, 1310b57cec5SDimitry Andric bool ForceNoStmt = false); 13281ad6265SDimitry Andric void PrintFPPragmas(CompoundStmt *S); 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric void PrintExpr(Expr *E) { 1350b57cec5SDimitry Andric if (E) 1360b57cec5SDimitry Andric Visit(E); 1370b57cec5SDimitry Andric else 1380b57cec5SDimitry Andric OS << "<null expr>"; 1390b57cec5SDimitry Andric } 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric raw_ostream &Indent(int Delta = 0) { 1420b57cec5SDimitry Andric for (int i = 0, e = IndentLevel+Delta; i < e; ++i) 1430b57cec5SDimitry Andric OS << " "; 1440b57cec5SDimitry Andric return OS; 1450b57cec5SDimitry Andric } 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric void Visit(Stmt* S) { 1480b57cec5SDimitry Andric if (Helper && Helper->handledStmt(S,OS)) 1490b57cec5SDimitry Andric return; 1500b57cec5SDimitry Andric else StmtVisitor<StmtPrinter>::Visit(S); 1510b57cec5SDimitry Andric } 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andric void VisitStmt(Stmt *Node) LLVM_ATTRIBUTE_UNUSED { 1540b57cec5SDimitry Andric Indent() << "<<unknown stmt type>>" << NL; 1550b57cec5SDimitry Andric } 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric void VisitExpr(Expr *Node) LLVM_ATTRIBUTE_UNUSED { 1580b57cec5SDimitry Andric OS << "<<unknown expr type>>"; 1590b57cec5SDimitry Andric } 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node); 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric #define ABSTRACT_STMT(CLASS) 1640b57cec5SDimitry Andric #define STMT(CLASS, PARENT) \ 1650b57cec5SDimitry Andric void Visit##CLASS(CLASS *Node); 1660b57cec5SDimitry Andric #include "clang/AST/StmtNodes.inc" 1670b57cec5SDimitry Andric }; 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andric } // namespace 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1720b57cec5SDimitry Andric // Stmt printing methods. 1730b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric /// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and 1760b57cec5SDimitry Andric /// with no newline after the }. 1770b57cec5SDimitry Andric void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) { 1785f757f3fSDimitry Andric assert(Node && "Compound statement cannot be null"); 1790b57cec5SDimitry Andric OS << "{" << NL; 18081ad6265SDimitry Andric PrintFPPragmas(Node); 1810b57cec5SDimitry Andric for (auto *I : Node->body()) 1820b57cec5SDimitry Andric PrintStmt(I); 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric Indent() << "}"; 1850b57cec5SDimitry Andric } 1860b57cec5SDimitry Andric 18781ad6265SDimitry Andric void StmtPrinter::PrintFPPragmas(CompoundStmt *S) { 18881ad6265SDimitry Andric if (!S->hasStoredFPFeatures()) 18981ad6265SDimitry Andric return; 19081ad6265SDimitry Andric FPOptionsOverride FPO = S->getStoredFPFeatures(); 19181ad6265SDimitry Andric bool FEnvAccess = false; 19281ad6265SDimitry Andric if (FPO.hasAllowFEnvAccessOverride()) { 19381ad6265SDimitry Andric FEnvAccess = FPO.getAllowFEnvAccessOverride(); 19481ad6265SDimitry Andric Indent() << "#pragma STDC FENV_ACCESS " << (FEnvAccess ? "ON" : "OFF") 19581ad6265SDimitry Andric << NL; 19681ad6265SDimitry Andric } 19781ad6265SDimitry Andric if (FPO.hasSpecifiedExceptionModeOverride()) { 19881ad6265SDimitry Andric LangOptions::FPExceptionModeKind EM = 19981ad6265SDimitry Andric FPO.getSpecifiedExceptionModeOverride(); 20081ad6265SDimitry Andric if (!FEnvAccess || EM != LangOptions::FPE_Strict) { 20181ad6265SDimitry Andric Indent() << "#pragma clang fp exceptions("; 20281ad6265SDimitry Andric switch (FPO.getSpecifiedExceptionModeOverride()) { 20381ad6265SDimitry Andric default: 20481ad6265SDimitry Andric break; 20581ad6265SDimitry Andric case LangOptions::FPE_Ignore: 20681ad6265SDimitry Andric OS << "ignore"; 20781ad6265SDimitry Andric break; 20881ad6265SDimitry Andric case LangOptions::FPE_MayTrap: 20981ad6265SDimitry Andric OS << "maytrap"; 21081ad6265SDimitry Andric break; 21181ad6265SDimitry Andric case LangOptions::FPE_Strict: 21281ad6265SDimitry Andric OS << "strict"; 21381ad6265SDimitry Andric break; 21481ad6265SDimitry Andric } 21581ad6265SDimitry Andric OS << ")\n"; 21681ad6265SDimitry Andric } 21781ad6265SDimitry Andric } 21881ad6265SDimitry Andric if (FPO.hasConstRoundingModeOverride()) { 21981ad6265SDimitry Andric LangOptions::RoundingMode RM = FPO.getConstRoundingModeOverride(); 22081ad6265SDimitry Andric Indent() << "#pragma STDC FENV_ROUND "; 22181ad6265SDimitry Andric switch (RM) { 22281ad6265SDimitry Andric case llvm::RoundingMode::TowardZero: 22381ad6265SDimitry Andric OS << "FE_TOWARDZERO"; 22481ad6265SDimitry Andric break; 22581ad6265SDimitry Andric case llvm::RoundingMode::NearestTiesToEven: 22681ad6265SDimitry Andric OS << "FE_TONEAREST"; 22781ad6265SDimitry Andric break; 22881ad6265SDimitry Andric case llvm::RoundingMode::TowardPositive: 22981ad6265SDimitry Andric OS << "FE_UPWARD"; 23081ad6265SDimitry Andric break; 23181ad6265SDimitry Andric case llvm::RoundingMode::TowardNegative: 23281ad6265SDimitry Andric OS << "FE_DOWNWARD"; 23381ad6265SDimitry Andric break; 23481ad6265SDimitry Andric case llvm::RoundingMode::NearestTiesToAway: 23581ad6265SDimitry Andric OS << "FE_TONEARESTFROMZERO"; 23681ad6265SDimitry Andric break; 23781ad6265SDimitry Andric case llvm::RoundingMode::Dynamic: 23881ad6265SDimitry Andric OS << "FE_DYNAMIC"; 23981ad6265SDimitry Andric break; 24081ad6265SDimitry Andric default: 24181ad6265SDimitry Andric llvm_unreachable("Invalid rounding mode"); 24281ad6265SDimitry Andric } 24381ad6265SDimitry Andric OS << NL; 24481ad6265SDimitry Andric } 24581ad6265SDimitry Andric } 24681ad6265SDimitry Andric 2470b57cec5SDimitry Andric void StmtPrinter::PrintRawDecl(Decl *D) { 2480b57cec5SDimitry Andric D->print(OS, Policy, IndentLevel); 2490b57cec5SDimitry Andric } 2500b57cec5SDimitry Andric 2510b57cec5SDimitry Andric void StmtPrinter::PrintRawDeclStmt(const DeclStmt *S) { 2520b57cec5SDimitry Andric SmallVector<Decl *, 2> Decls(S->decls()); 2530b57cec5SDimitry Andric Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel); 2540b57cec5SDimitry Andric } 2550b57cec5SDimitry Andric 2560b57cec5SDimitry Andric void StmtPrinter::VisitNullStmt(NullStmt *Node) { 2570b57cec5SDimitry Andric Indent() << ";" << NL; 2580b57cec5SDimitry Andric } 2590b57cec5SDimitry Andric 2600b57cec5SDimitry Andric void StmtPrinter::VisitDeclStmt(DeclStmt *Node) { 2610b57cec5SDimitry Andric Indent(); 2620b57cec5SDimitry Andric PrintRawDeclStmt(Node); 2630b57cec5SDimitry Andric OS << ";" << NL; 2640b57cec5SDimitry Andric } 2650b57cec5SDimitry Andric 2660b57cec5SDimitry Andric void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) { 2670b57cec5SDimitry Andric Indent(); 2680b57cec5SDimitry Andric PrintRawCompoundStmt(Node); 2690b57cec5SDimitry Andric OS << "" << NL; 2700b57cec5SDimitry Andric } 2710b57cec5SDimitry Andric 2720b57cec5SDimitry Andric void StmtPrinter::VisitCaseStmt(CaseStmt *Node) { 2730b57cec5SDimitry Andric Indent(-1) << "case "; 2740b57cec5SDimitry Andric PrintExpr(Node->getLHS()); 2750b57cec5SDimitry Andric if (Node->getRHS()) { 2760b57cec5SDimitry Andric OS << " ... "; 2770b57cec5SDimitry Andric PrintExpr(Node->getRHS()); 2780b57cec5SDimitry Andric } 2790b57cec5SDimitry Andric OS << ":" << NL; 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andric PrintStmt(Node->getSubStmt(), 0); 2820b57cec5SDimitry Andric } 2830b57cec5SDimitry Andric 2840b57cec5SDimitry Andric void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) { 2850b57cec5SDimitry Andric Indent(-1) << "default:" << NL; 2860b57cec5SDimitry Andric PrintStmt(Node->getSubStmt(), 0); 2870b57cec5SDimitry Andric } 2880b57cec5SDimitry Andric 2890b57cec5SDimitry Andric void StmtPrinter::VisitLabelStmt(LabelStmt *Node) { 2900b57cec5SDimitry Andric Indent(-1) << Node->getName() << ":" << NL; 2910b57cec5SDimitry Andric PrintStmt(Node->getSubStmt(), 0); 2920b57cec5SDimitry Andric } 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andric void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) { 295*0fca6ea1SDimitry Andric llvm::ArrayRef<const Attr *> Attrs = Node->getAttrs(); 296*0fca6ea1SDimitry Andric for (const auto *Attr : Attrs) { 2970b57cec5SDimitry Andric Attr->printPretty(OS, Policy); 298*0fca6ea1SDimitry Andric if (Attr != Attrs.back()) 299*0fca6ea1SDimitry Andric OS << ' '; 3000b57cec5SDimitry Andric } 3010b57cec5SDimitry Andric 3020b57cec5SDimitry Andric PrintStmt(Node->getSubStmt(), 0); 3030b57cec5SDimitry Andric } 3040b57cec5SDimitry Andric 3050b57cec5SDimitry Andric void StmtPrinter::PrintRawIfStmt(IfStmt *If) { 306349cc55cSDimitry Andric if (If->isConsteval()) { 307349cc55cSDimitry Andric OS << "if "; 308349cc55cSDimitry Andric if (If->isNegatedConsteval()) 309349cc55cSDimitry Andric OS << "!"; 310349cc55cSDimitry Andric OS << "consteval"; 311349cc55cSDimitry Andric OS << NL; 312349cc55cSDimitry Andric PrintStmt(If->getThen()); 313349cc55cSDimitry Andric if (Stmt *Else = If->getElse()) { 314349cc55cSDimitry Andric Indent(); 315349cc55cSDimitry Andric OS << "else"; 316349cc55cSDimitry Andric PrintStmt(Else); 317349cc55cSDimitry Andric OS << NL; 318349cc55cSDimitry Andric } 319349cc55cSDimitry Andric return; 320349cc55cSDimitry Andric } 321349cc55cSDimitry Andric 3220b57cec5SDimitry Andric OS << "if ("; 3230b57cec5SDimitry Andric if (If->getInit()) 3240b57cec5SDimitry Andric PrintInitStmt(If->getInit(), 4); 3250b57cec5SDimitry Andric if (const DeclStmt *DS = If->getConditionVariableDeclStmt()) 3260b57cec5SDimitry Andric PrintRawDeclStmt(DS); 3270b57cec5SDimitry Andric else 3280b57cec5SDimitry Andric PrintExpr(If->getCond()); 3290b57cec5SDimitry Andric OS << ')'; 3300b57cec5SDimitry Andric 3310b57cec5SDimitry Andric if (auto *CS = dyn_cast<CompoundStmt>(If->getThen())) { 3320b57cec5SDimitry Andric OS << ' '; 3330b57cec5SDimitry Andric PrintRawCompoundStmt(CS); 3340b57cec5SDimitry Andric OS << (If->getElse() ? " " : NL); 3350b57cec5SDimitry Andric } else { 3360b57cec5SDimitry Andric OS << NL; 3370b57cec5SDimitry Andric PrintStmt(If->getThen()); 3380b57cec5SDimitry Andric if (If->getElse()) Indent(); 3390b57cec5SDimitry Andric } 3400b57cec5SDimitry Andric 3410b57cec5SDimitry Andric if (Stmt *Else = If->getElse()) { 3420b57cec5SDimitry Andric OS << "else"; 3430b57cec5SDimitry Andric 3440b57cec5SDimitry Andric if (auto *CS = dyn_cast<CompoundStmt>(Else)) { 3450b57cec5SDimitry Andric OS << ' '; 3460b57cec5SDimitry Andric PrintRawCompoundStmt(CS); 3470b57cec5SDimitry Andric OS << NL; 3480b57cec5SDimitry Andric } else if (auto *ElseIf = dyn_cast<IfStmt>(Else)) { 3490b57cec5SDimitry Andric OS << ' '; 3500b57cec5SDimitry Andric PrintRawIfStmt(ElseIf); 3510b57cec5SDimitry Andric } else { 3520b57cec5SDimitry Andric OS << NL; 3530b57cec5SDimitry Andric PrintStmt(If->getElse()); 3540b57cec5SDimitry Andric } 3550b57cec5SDimitry Andric } 3560b57cec5SDimitry Andric } 3570b57cec5SDimitry Andric 3580b57cec5SDimitry Andric void StmtPrinter::VisitIfStmt(IfStmt *If) { 3590b57cec5SDimitry Andric Indent(); 3600b57cec5SDimitry Andric PrintRawIfStmt(If); 3610b57cec5SDimitry Andric } 3620b57cec5SDimitry Andric 3630b57cec5SDimitry Andric void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) { 3640b57cec5SDimitry Andric Indent() << "switch ("; 3650b57cec5SDimitry Andric if (Node->getInit()) 3660b57cec5SDimitry Andric PrintInitStmt(Node->getInit(), 8); 3670b57cec5SDimitry Andric if (const DeclStmt *DS = Node->getConditionVariableDeclStmt()) 3680b57cec5SDimitry Andric PrintRawDeclStmt(DS); 3690b57cec5SDimitry Andric else 3700b57cec5SDimitry Andric PrintExpr(Node->getCond()); 3710b57cec5SDimitry Andric OS << ")"; 3720b57cec5SDimitry Andric PrintControlledStmt(Node->getBody()); 3730b57cec5SDimitry Andric } 3740b57cec5SDimitry Andric 3750b57cec5SDimitry Andric void StmtPrinter::VisitWhileStmt(WhileStmt *Node) { 3760b57cec5SDimitry Andric Indent() << "while ("; 3770b57cec5SDimitry Andric if (const DeclStmt *DS = Node->getConditionVariableDeclStmt()) 3780b57cec5SDimitry Andric PrintRawDeclStmt(DS); 3790b57cec5SDimitry Andric else 3800b57cec5SDimitry Andric PrintExpr(Node->getCond()); 3810b57cec5SDimitry Andric OS << ")" << NL; 3820b57cec5SDimitry Andric PrintStmt(Node->getBody()); 3830b57cec5SDimitry Andric } 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andric void StmtPrinter::VisitDoStmt(DoStmt *Node) { 3860b57cec5SDimitry Andric Indent() << "do "; 3870b57cec5SDimitry Andric if (auto *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 3880b57cec5SDimitry Andric PrintRawCompoundStmt(CS); 3890b57cec5SDimitry Andric OS << " "; 3900b57cec5SDimitry Andric } else { 3910b57cec5SDimitry Andric OS << NL; 3920b57cec5SDimitry Andric PrintStmt(Node->getBody()); 3930b57cec5SDimitry Andric Indent(); 3940b57cec5SDimitry Andric } 3950b57cec5SDimitry Andric 3960b57cec5SDimitry Andric OS << "while ("; 3970b57cec5SDimitry Andric PrintExpr(Node->getCond()); 3980b57cec5SDimitry Andric OS << ");" << NL; 3990b57cec5SDimitry Andric } 4000b57cec5SDimitry Andric 4010b57cec5SDimitry Andric void StmtPrinter::VisitForStmt(ForStmt *Node) { 4020b57cec5SDimitry Andric Indent() << "for ("; 4030b57cec5SDimitry Andric if (Node->getInit()) 4040b57cec5SDimitry Andric PrintInitStmt(Node->getInit(), 5); 4050b57cec5SDimitry Andric else 4060b57cec5SDimitry Andric OS << (Node->getCond() ? "; " : ";"); 40706c3fb27SDimitry Andric if (const DeclStmt *DS = Node->getConditionVariableDeclStmt()) 40806c3fb27SDimitry Andric PrintRawDeclStmt(DS); 40906c3fb27SDimitry Andric else if (Node->getCond()) 4100b57cec5SDimitry Andric PrintExpr(Node->getCond()); 4110b57cec5SDimitry Andric OS << ";"; 4120b57cec5SDimitry Andric if (Node->getInc()) { 4130b57cec5SDimitry Andric OS << " "; 4140b57cec5SDimitry Andric PrintExpr(Node->getInc()); 4150b57cec5SDimitry Andric } 4160b57cec5SDimitry Andric OS << ")"; 4170b57cec5SDimitry Andric PrintControlledStmt(Node->getBody()); 4180b57cec5SDimitry Andric } 4190b57cec5SDimitry Andric 4200b57cec5SDimitry Andric void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) { 4210b57cec5SDimitry Andric Indent() << "for ("; 4220b57cec5SDimitry Andric if (auto *DS = dyn_cast<DeclStmt>(Node->getElement())) 4230b57cec5SDimitry Andric PrintRawDeclStmt(DS); 4240b57cec5SDimitry Andric else 4250b57cec5SDimitry Andric PrintExpr(cast<Expr>(Node->getElement())); 4260b57cec5SDimitry Andric OS << " in "; 4270b57cec5SDimitry Andric PrintExpr(Node->getCollection()); 4280b57cec5SDimitry Andric OS << ")"; 4290b57cec5SDimitry Andric PrintControlledStmt(Node->getBody()); 4300b57cec5SDimitry Andric } 4310b57cec5SDimitry Andric 4320b57cec5SDimitry Andric void StmtPrinter::VisitCXXForRangeStmt(CXXForRangeStmt *Node) { 4330b57cec5SDimitry Andric Indent() << "for ("; 4340b57cec5SDimitry Andric if (Node->getInit()) 4350b57cec5SDimitry Andric PrintInitStmt(Node->getInit(), 5); 4360b57cec5SDimitry Andric PrintingPolicy SubPolicy(Policy); 4370b57cec5SDimitry Andric SubPolicy.SuppressInitializers = true; 4380b57cec5SDimitry Andric Node->getLoopVariable()->print(OS, SubPolicy, IndentLevel); 4390b57cec5SDimitry Andric OS << " : "; 4400b57cec5SDimitry Andric PrintExpr(Node->getRangeInit()); 4410b57cec5SDimitry Andric OS << ")"; 4420b57cec5SDimitry Andric PrintControlledStmt(Node->getBody()); 4430b57cec5SDimitry Andric } 4440b57cec5SDimitry Andric 4450b57cec5SDimitry Andric void StmtPrinter::VisitMSDependentExistsStmt(MSDependentExistsStmt *Node) { 4460b57cec5SDimitry Andric Indent(); 4470b57cec5SDimitry Andric if (Node->isIfExists()) 4480b57cec5SDimitry Andric OS << "__if_exists ("; 4490b57cec5SDimitry Andric else 4500b57cec5SDimitry Andric OS << "__if_not_exists ("; 4510b57cec5SDimitry Andric 4520b57cec5SDimitry Andric if (NestedNameSpecifier *Qualifier 4530b57cec5SDimitry Andric = Node->getQualifierLoc().getNestedNameSpecifier()) 4540b57cec5SDimitry Andric Qualifier->print(OS, Policy); 4550b57cec5SDimitry Andric 4560b57cec5SDimitry Andric OS << Node->getNameInfo() << ") "; 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andric PrintRawCompoundStmt(Node->getSubStmt()); 4590b57cec5SDimitry Andric } 4600b57cec5SDimitry Andric 4610b57cec5SDimitry Andric void StmtPrinter::VisitGotoStmt(GotoStmt *Node) { 4620b57cec5SDimitry Andric Indent() << "goto " << Node->getLabel()->getName() << ";"; 4630b57cec5SDimitry Andric if (Policy.IncludeNewlines) OS << NL; 4640b57cec5SDimitry Andric } 4650b57cec5SDimitry Andric 4660b57cec5SDimitry Andric void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) { 4670b57cec5SDimitry Andric Indent() << "goto *"; 4680b57cec5SDimitry Andric PrintExpr(Node->getTarget()); 4690b57cec5SDimitry Andric OS << ";"; 4700b57cec5SDimitry Andric if (Policy.IncludeNewlines) OS << NL; 4710b57cec5SDimitry Andric } 4720b57cec5SDimitry Andric 4730b57cec5SDimitry Andric void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) { 4740b57cec5SDimitry Andric Indent() << "continue;"; 4750b57cec5SDimitry Andric if (Policy.IncludeNewlines) OS << NL; 4760b57cec5SDimitry Andric } 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andric void StmtPrinter::VisitBreakStmt(BreakStmt *Node) { 4790b57cec5SDimitry Andric Indent() << "break;"; 4800b57cec5SDimitry Andric if (Policy.IncludeNewlines) OS << NL; 4810b57cec5SDimitry Andric } 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andric void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) { 4840b57cec5SDimitry Andric Indent() << "return"; 4850b57cec5SDimitry Andric if (Node->getRetValue()) { 4860b57cec5SDimitry Andric OS << " "; 4870b57cec5SDimitry Andric PrintExpr(Node->getRetValue()); 4880b57cec5SDimitry Andric } 4890b57cec5SDimitry Andric OS << ";"; 4900b57cec5SDimitry Andric if (Policy.IncludeNewlines) OS << NL; 4910b57cec5SDimitry Andric } 4920b57cec5SDimitry Andric 4930b57cec5SDimitry Andric void StmtPrinter::VisitGCCAsmStmt(GCCAsmStmt *Node) { 4940b57cec5SDimitry Andric Indent() << "asm "; 4950b57cec5SDimitry Andric 4960b57cec5SDimitry Andric if (Node->isVolatile()) 4970b57cec5SDimitry Andric OS << "volatile "; 4980b57cec5SDimitry Andric 4990b57cec5SDimitry Andric if (Node->isAsmGoto()) 5000b57cec5SDimitry Andric OS << "goto "; 5010b57cec5SDimitry Andric 5020b57cec5SDimitry Andric OS << "("; 5030b57cec5SDimitry Andric VisitStringLiteral(Node->getAsmString()); 5040b57cec5SDimitry Andric 5050b57cec5SDimitry Andric // Outputs 5060b57cec5SDimitry Andric if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 || 5070b57cec5SDimitry Andric Node->getNumClobbers() != 0 || Node->getNumLabels() != 0) 5080b57cec5SDimitry Andric OS << " : "; 5090b57cec5SDimitry Andric 5100b57cec5SDimitry Andric for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) { 5110b57cec5SDimitry Andric if (i != 0) 5120b57cec5SDimitry Andric OS << ", "; 5130b57cec5SDimitry Andric 5140b57cec5SDimitry Andric if (!Node->getOutputName(i).empty()) { 5150b57cec5SDimitry Andric OS << '['; 5160b57cec5SDimitry Andric OS << Node->getOutputName(i); 5170b57cec5SDimitry Andric OS << "] "; 5180b57cec5SDimitry Andric } 5190b57cec5SDimitry Andric 5200b57cec5SDimitry Andric VisitStringLiteral(Node->getOutputConstraintLiteral(i)); 5210b57cec5SDimitry Andric OS << " ("; 5220b57cec5SDimitry Andric Visit(Node->getOutputExpr(i)); 5230b57cec5SDimitry Andric OS << ")"; 5240b57cec5SDimitry Andric } 5250b57cec5SDimitry Andric 5260b57cec5SDimitry Andric // Inputs 5270b57cec5SDimitry Andric if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0 || 5280b57cec5SDimitry Andric Node->getNumLabels() != 0) 5290b57cec5SDimitry Andric OS << " : "; 5300b57cec5SDimitry Andric 5310b57cec5SDimitry Andric for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) { 5320b57cec5SDimitry Andric if (i != 0) 5330b57cec5SDimitry Andric OS << ", "; 5340b57cec5SDimitry Andric 5350b57cec5SDimitry Andric if (!Node->getInputName(i).empty()) { 5360b57cec5SDimitry Andric OS << '['; 5370b57cec5SDimitry Andric OS << Node->getInputName(i); 5380b57cec5SDimitry Andric OS << "] "; 5390b57cec5SDimitry Andric } 5400b57cec5SDimitry Andric 5410b57cec5SDimitry Andric VisitStringLiteral(Node->getInputConstraintLiteral(i)); 5420b57cec5SDimitry Andric OS << " ("; 5430b57cec5SDimitry Andric Visit(Node->getInputExpr(i)); 5440b57cec5SDimitry Andric OS << ")"; 5450b57cec5SDimitry Andric } 5460b57cec5SDimitry Andric 5470b57cec5SDimitry Andric // Clobbers 5480b57cec5SDimitry Andric if (Node->getNumClobbers() != 0 || Node->getNumLabels()) 5490b57cec5SDimitry Andric OS << " : "; 5500b57cec5SDimitry Andric 5510b57cec5SDimitry Andric for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) { 5520b57cec5SDimitry Andric if (i != 0) 5530b57cec5SDimitry Andric OS << ", "; 5540b57cec5SDimitry Andric 5550b57cec5SDimitry Andric VisitStringLiteral(Node->getClobberStringLiteral(i)); 5560b57cec5SDimitry Andric } 5570b57cec5SDimitry Andric 5580b57cec5SDimitry Andric // Labels 5590b57cec5SDimitry Andric if (Node->getNumLabels() != 0) 5600b57cec5SDimitry Andric OS << " : "; 5610b57cec5SDimitry Andric 5620b57cec5SDimitry Andric for (unsigned i = 0, e = Node->getNumLabels(); i != e; ++i) { 5630b57cec5SDimitry Andric if (i != 0) 5640b57cec5SDimitry Andric OS << ", "; 5650b57cec5SDimitry Andric OS << Node->getLabelName(i); 5660b57cec5SDimitry Andric } 5670b57cec5SDimitry Andric 5680b57cec5SDimitry Andric OS << ");"; 5690b57cec5SDimitry Andric if (Policy.IncludeNewlines) OS << NL; 5700b57cec5SDimitry Andric } 5710b57cec5SDimitry Andric 5720b57cec5SDimitry Andric void StmtPrinter::VisitMSAsmStmt(MSAsmStmt *Node) { 5730b57cec5SDimitry Andric // FIXME: Implement MS style inline asm statement printer. 5740b57cec5SDimitry Andric Indent() << "__asm "; 5750b57cec5SDimitry Andric if (Node->hasBraces()) 5760b57cec5SDimitry Andric OS << "{" << NL; 5770b57cec5SDimitry Andric OS << Node->getAsmString() << NL; 5780b57cec5SDimitry Andric if (Node->hasBraces()) 5790b57cec5SDimitry Andric Indent() << "}" << NL; 5800b57cec5SDimitry Andric } 5810b57cec5SDimitry Andric 5820b57cec5SDimitry Andric void StmtPrinter::VisitCapturedStmt(CapturedStmt *Node) { 5830b57cec5SDimitry Andric PrintStmt(Node->getCapturedDecl()->getBody()); 5840b57cec5SDimitry Andric } 5850b57cec5SDimitry Andric 5860b57cec5SDimitry Andric void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) { 5870b57cec5SDimitry Andric Indent() << "@try"; 5880b57cec5SDimitry Andric if (auto *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) { 5890b57cec5SDimitry Andric PrintRawCompoundStmt(TS); 5900b57cec5SDimitry Andric OS << NL; 5910b57cec5SDimitry Andric } 5920b57cec5SDimitry Andric 593349cc55cSDimitry Andric for (ObjCAtCatchStmt *catchStmt : Node->catch_stmts()) { 5940b57cec5SDimitry Andric Indent() << "@catch("; 5950b57cec5SDimitry Andric if (Decl *DS = catchStmt->getCatchParamDecl()) 5960b57cec5SDimitry Andric PrintRawDecl(DS); 5970b57cec5SDimitry Andric OS << ")"; 5980b57cec5SDimitry Andric if (auto *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) { 5990b57cec5SDimitry Andric PrintRawCompoundStmt(CS); 6000b57cec5SDimitry Andric OS << NL; 6010b57cec5SDimitry Andric } 6020b57cec5SDimitry Andric } 6030b57cec5SDimitry Andric 6040b57cec5SDimitry Andric if (auto *FS = static_cast<ObjCAtFinallyStmt *>(Node->getFinallyStmt())) { 6050b57cec5SDimitry Andric Indent() << "@finally"; 6065f757f3fSDimitry Andric if (auto *CS = dyn_cast<CompoundStmt>(FS->getFinallyBody())) { 6075f757f3fSDimitry Andric PrintRawCompoundStmt(CS); 6080b57cec5SDimitry Andric OS << NL; 6090b57cec5SDimitry Andric } 6100b57cec5SDimitry Andric } 6115f757f3fSDimitry Andric } 6120b57cec5SDimitry Andric 6130b57cec5SDimitry Andric void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) { 6140b57cec5SDimitry Andric } 6150b57cec5SDimitry Andric 6160b57cec5SDimitry Andric void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) { 6170b57cec5SDimitry Andric Indent() << "@catch (...) { /* todo */ } " << NL; 6180b57cec5SDimitry Andric } 6190b57cec5SDimitry Andric 6200b57cec5SDimitry Andric void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) { 6210b57cec5SDimitry Andric Indent() << "@throw"; 6220b57cec5SDimitry Andric if (Node->getThrowExpr()) { 6230b57cec5SDimitry Andric OS << " "; 6240b57cec5SDimitry Andric PrintExpr(Node->getThrowExpr()); 6250b57cec5SDimitry Andric } 6260b57cec5SDimitry Andric OS << ";" << NL; 6270b57cec5SDimitry Andric } 6280b57cec5SDimitry Andric 6290b57cec5SDimitry Andric void StmtPrinter::VisitObjCAvailabilityCheckExpr( 6300b57cec5SDimitry Andric ObjCAvailabilityCheckExpr *Node) { 6310b57cec5SDimitry Andric OS << "@available(...)"; 6320b57cec5SDimitry Andric } 6330b57cec5SDimitry Andric 6340b57cec5SDimitry Andric void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) { 6350b57cec5SDimitry Andric Indent() << "@synchronized ("; 6360b57cec5SDimitry Andric PrintExpr(Node->getSynchExpr()); 6370b57cec5SDimitry Andric OS << ")"; 6380b57cec5SDimitry Andric PrintRawCompoundStmt(Node->getSynchBody()); 6390b57cec5SDimitry Andric OS << NL; 6400b57cec5SDimitry Andric } 6410b57cec5SDimitry Andric 6420b57cec5SDimitry Andric void StmtPrinter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *Node) { 6430b57cec5SDimitry Andric Indent() << "@autoreleasepool"; 6445f757f3fSDimitry Andric PrintRawCompoundStmt(cast<CompoundStmt>(Node->getSubStmt())); 6450b57cec5SDimitry Andric OS << NL; 6460b57cec5SDimitry Andric } 6470b57cec5SDimitry Andric 6480b57cec5SDimitry Andric void StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) { 6490b57cec5SDimitry Andric OS << "catch ("; 6500b57cec5SDimitry Andric if (Decl *ExDecl = Node->getExceptionDecl()) 6510b57cec5SDimitry Andric PrintRawDecl(ExDecl); 6520b57cec5SDimitry Andric else 6530b57cec5SDimitry Andric OS << "..."; 6540b57cec5SDimitry Andric OS << ") "; 6550b57cec5SDimitry Andric PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock())); 6560b57cec5SDimitry Andric } 6570b57cec5SDimitry Andric 6580b57cec5SDimitry Andric void StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) { 6590b57cec5SDimitry Andric Indent(); 6600b57cec5SDimitry Andric PrintRawCXXCatchStmt(Node); 6610b57cec5SDimitry Andric OS << NL; 6620b57cec5SDimitry Andric } 6630b57cec5SDimitry Andric 6640b57cec5SDimitry Andric void StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) { 6650b57cec5SDimitry Andric Indent() << "try "; 6660b57cec5SDimitry Andric PrintRawCompoundStmt(Node->getTryBlock()); 6670b57cec5SDimitry Andric for (unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) { 6680b57cec5SDimitry Andric OS << " "; 6690b57cec5SDimitry Andric PrintRawCXXCatchStmt(Node->getHandler(i)); 6700b57cec5SDimitry Andric } 6710b57cec5SDimitry Andric OS << NL; 6720b57cec5SDimitry Andric } 6730b57cec5SDimitry Andric 6740b57cec5SDimitry Andric void StmtPrinter::VisitSEHTryStmt(SEHTryStmt *Node) { 6750b57cec5SDimitry Andric Indent() << (Node->getIsCXXTry() ? "try " : "__try "); 6760b57cec5SDimitry Andric PrintRawCompoundStmt(Node->getTryBlock()); 6770b57cec5SDimitry Andric SEHExceptStmt *E = Node->getExceptHandler(); 6780b57cec5SDimitry Andric SEHFinallyStmt *F = Node->getFinallyHandler(); 6790b57cec5SDimitry Andric if(E) 6800b57cec5SDimitry Andric PrintRawSEHExceptHandler(E); 6810b57cec5SDimitry Andric else { 6820b57cec5SDimitry Andric assert(F && "Must have a finally block..."); 6830b57cec5SDimitry Andric PrintRawSEHFinallyStmt(F); 6840b57cec5SDimitry Andric } 6850b57cec5SDimitry Andric OS << NL; 6860b57cec5SDimitry Andric } 6870b57cec5SDimitry Andric 6880b57cec5SDimitry Andric void StmtPrinter::PrintRawSEHFinallyStmt(SEHFinallyStmt *Node) { 6890b57cec5SDimitry Andric OS << "__finally "; 6900b57cec5SDimitry Andric PrintRawCompoundStmt(Node->getBlock()); 6910b57cec5SDimitry Andric OS << NL; 6920b57cec5SDimitry Andric } 6930b57cec5SDimitry Andric 6940b57cec5SDimitry Andric void StmtPrinter::PrintRawSEHExceptHandler(SEHExceptStmt *Node) { 6950b57cec5SDimitry Andric OS << "__except ("; 6960b57cec5SDimitry Andric VisitExpr(Node->getFilterExpr()); 6970b57cec5SDimitry Andric OS << ")" << NL; 6980b57cec5SDimitry Andric PrintRawCompoundStmt(Node->getBlock()); 6990b57cec5SDimitry Andric OS << NL; 7000b57cec5SDimitry Andric } 7010b57cec5SDimitry Andric 7020b57cec5SDimitry Andric void StmtPrinter::VisitSEHExceptStmt(SEHExceptStmt *Node) { 7030b57cec5SDimitry Andric Indent(); 7040b57cec5SDimitry Andric PrintRawSEHExceptHandler(Node); 7050b57cec5SDimitry Andric OS << NL; 7060b57cec5SDimitry Andric } 7070b57cec5SDimitry Andric 7080b57cec5SDimitry Andric void StmtPrinter::VisitSEHFinallyStmt(SEHFinallyStmt *Node) { 7090b57cec5SDimitry Andric Indent(); 7100b57cec5SDimitry Andric PrintRawSEHFinallyStmt(Node); 7110b57cec5SDimitry Andric OS << NL; 7120b57cec5SDimitry Andric } 7130b57cec5SDimitry Andric 7140b57cec5SDimitry Andric void StmtPrinter::VisitSEHLeaveStmt(SEHLeaveStmt *Node) { 7150b57cec5SDimitry Andric Indent() << "__leave;"; 7160b57cec5SDimitry Andric if (Policy.IncludeNewlines) OS << NL; 7170b57cec5SDimitry Andric } 7180b57cec5SDimitry Andric 7190b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 7200b57cec5SDimitry Andric // OpenMP directives printing methods 7210b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 7220b57cec5SDimitry Andric 723fe6060f1SDimitry Andric void StmtPrinter::VisitOMPCanonicalLoop(OMPCanonicalLoop *Node) { 724fe6060f1SDimitry Andric PrintStmt(Node->getLoopStmt()); 725fe6060f1SDimitry Andric } 726fe6060f1SDimitry Andric 7270b57cec5SDimitry Andric void StmtPrinter::PrintOMPExecutableDirective(OMPExecutableDirective *S, 7280b57cec5SDimitry Andric bool ForceNoStmt) { 7290b57cec5SDimitry Andric OMPClausePrinter Printer(OS, Policy); 7300b57cec5SDimitry Andric ArrayRef<OMPClause *> Clauses = S->clauses(); 7310b57cec5SDimitry Andric for (auto *Clause : Clauses) 7320b57cec5SDimitry Andric if (Clause && !Clause->isImplicit()) { 7330b57cec5SDimitry Andric OS << ' '; 7340b57cec5SDimitry Andric Printer.Visit(Clause); 7350b57cec5SDimitry Andric } 7360b57cec5SDimitry Andric OS << NL; 7370b57cec5SDimitry Andric if (!ForceNoStmt && S->hasAssociatedStmt()) 738e8d8bef9SDimitry Andric PrintStmt(S->getRawStmt()); 7390b57cec5SDimitry Andric } 7400b57cec5SDimitry Andric 741349cc55cSDimitry Andric void StmtPrinter::VisitOMPMetaDirective(OMPMetaDirective *Node) { 742349cc55cSDimitry Andric Indent() << "#pragma omp metadirective"; 743349cc55cSDimitry Andric PrintOMPExecutableDirective(Node); 744349cc55cSDimitry Andric } 745349cc55cSDimitry Andric 7460b57cec5SDimitry Andric void StmtPrinter::VisitOMPParallelDirective(OMPParallelDirective *Node) { 7470b57cec5SDimitry Andric Indent() << "#pragma omp parallel"; 7480b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 7490b57cec5SDimitry Andric } 7500b57cec5SDimitry Andric 7510b57cec5SDimitry Andric void StmtPrinter::VisitOMPSimdDirective(OMPSimdDirective *Node) { 7520b57cec5SDimitry Andric Indent() << "#pragma omp simd"; 7530b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 7540b57cec5SDimitry Andric } 7550b57cec5SDimitry Andric 756fe6060f1SDimitry Andric void StmtPrinter::VisitOMPTileDirective(OMPTileDirective *Node) { 757fe6060f1SDimitry Andric Indent() << "#pragma omp tile"; 758fe6060f1SDimitry Andric PrintOMPExecutableDirective(Node); 759fe6060f1SDimitry Andric } 760fe6060f1SDimitry Andric 761fe6060f1SDimitry Andric void StmtPrinter::VisitOMPUnrollDirective(OMPUnrollDirective *Node) { 762fe6060f1SDimitry Andric Indent() << "#pragma omp unroll"; 763fe6060f1SDimitry Andric PrintOMPExecutableDirective(Node); 764fe6060f1SDimitry Andric } 765fe6060f1SDimitry Andric 766*0fca6ea1SDimitry Andric void StmtPrinter::VisitOMPReverseDirective(OMPReverseDirective *Node) { 767*0fca6ea1SDimitry Andric Indent() << "#pragma omp reverse"; 768*0fca6ea1SDimitry Andric PrintOMPExecutableDirective(Node); 769*0fca6ea1SDimitry Andric } 770*0fca6ea1SDimitry Andric 771*0fca6ea1SDimitry Andric void StmtPrinter::VisitOMPInterchangeDirective(OMPInterchangeDirective *Node) { 772*0fca6ea1SDimitry Andric Indent() << "#pragma omp interchange"; 773*0fca6ea1SDimitry Andric PrintOMPExecutableDirective(Node); 774*0fca6ea1SDimitry Andric } 775*0fca6ea1SDimitry Andric 7760b57cec5SDimitry Andric void StmtPrinter::VisitOMPForDirective(OMPForDirective *Node) { 7770b57cec5SDimitry Andric Indent() << "#pragma omp for"; 7780b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 7790b57cec5SDimitry Andric } 7800b57cec5SDimitry Andric 7810b57cec5SDimitry Andric void StmtPrinter::VisitOMPForSimdDirective(OMPForSimdDirective *Node) { 7820b57cec5SDimitry Andric Indent() << "#pragma omp for simd"; 7830b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 7840b57cec5SDimitry Andric } 7850b57cec5SDimitry Andric 7860b57cec5SDimitry Andric void StmtPrinter::VisitOMPSectionsDirective(OMPSectionsDirective *Node) { 7870b57cec5SDimitry Andric Indent() << "#pragma omp sections"; 7880b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 7890b57cec5SDimitry Andric } 7900b57cec5SDimitry Andric 7910b57cec5SDimitry Andric void StmtPrinter::VisitOMPSectionDirective(OMPSectionDirective *Node) { 7920b57cec5SDimitry Andric Indent() << "#pragma omp section"; 7930b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 7940b57cec5SDimitry Andric } 7950b57cec5SDimitry Andric 7965f757f3fSDimitry Andric void StmtPrinter::VisitOMPScopeDirective(OMPScopeDirective *Node) { 7975f757f3fSDimitry Andric Indent() << "#pragma omp scope"; 7985f757f3fSDimitry Andric PrintOMPExecutableDirective(Node); 7995f757f3fSDimitry Andric } 8005f757f3fSDimitry Andric 8010b57cec5SDimitry Andric void StmtPrinter::VisitOMPSingleDirective(OMPSingleDirective *Node) { 8020b57cec5SDimitry Andric Indent() << "#pragma omp single"; 8030b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 8040b57cec5SDimitry Andric } 8050b57cec5SDimitry Andric 8060b57cec5SDimitry Andric void StmtPrinter::VisitOMPMasterDirective(OMPMasterDirective *Node) { 8070b57cec5SDimitry Andric Indent() << "#pragma omp master"; 8080b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 8090b57cec5SDimitry Andric } 8100b57cec5SDimitry Andric 8110b57cec5SDimitry Andric void StmtPrinter::VisitOMPCriticalDirective(OMPCriticalDirective *Node) { 8120b57cec5SDimitry Andric Indent() << "#pragma omp critical"; 8130b57cec5SDimitry Andric if (Node->getDirectiveName().getName()) { 8140b57cec5SDimitry Andric OS << " ("; 815480093f4SDimitry Andric Node->getDirectiveName().printName(OS, Policy); 8160b57cec5SDimitry Andric OS << ")"; 8170b57cec5SDimitry Andric } 8180b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 8190b57cec5SDimitry Andric } 8200b57cec5SDimitry Andric 8210b57cec5SDimitry Andric void StmtPrinter::VisitOMPParallelForDirective(OMPParallelForDirective *Node) { 8220b57cec5SDimitry Andric Indent() << "#pragma omp parallel for"; 8230b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 8240b57cec5SDimitry Andric } 8250b57cec5SDimitry Andric 8260b57cec5SDimitry Andric void StmtPrinter::VisitOMPParallelForSimdDirective( 8270b57cec5SDimitry Andric OMPParallelForSimdDirective *Node) { 8280b57cec5SDimitry Andric Indent() << "#pragma omp parallel for simd"; 8290b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 8300b57cec5SDimitry Andric } 8310b57cec5SDimitry Andric 832480093f4SDimitry Andric void StmtPrinter::VisitOMPParallelMasterDirective( 833480093f4SDimitry Andric OMPParallelMasterDirective *Node) { 834480093f4SDimitry Andric Indent() << "#pragma omp parallel master"; 835480093f4SDimitry Andric PrintOMPExecutableDirective(Node); 836480093f4SDimitry Andric } 837480093f4SDimitry Andric 83881ad6265SDimitry Andric void StmtPrinter::VisitOMPParallelMaskedDirective( 83981ad6265SDimitry Andric OMPParallelMaskedDirective *Node) { 84081ad6265SDimitry Andric Indent() << "#pragma omp parallel masked"; 84181ad6265SDimitry Andric PrintOMPExecutableDirective(Node); 84281ad6265SDimitry Andric } 84381ad6265SDimitry Andric 8440b57cec5SDimitry Andric void StmtPrinter::VisitOMPParallelSectionsDirective( 8450b57cec5SDimitry Andric OMPParallelSectionsDirective *Node) { 8460b57cec5SDimitry Andric Indent() << "#pragma omp parallel sections"; 8470b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 8480b57cec5SDimitry Andric } 8490b57cec5SDimitry Andric 8500b57cec5SDimitry Andric void StmtPrinter::VisitOMPTaskDirective(OMPTaskDirective *Node) { 8510b57cec5SDimitry Andric Indent() << "#pragma omp task"; 8520b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 8530b57cec5SDimitry Andric } 8540b57cec5SDimitry Andric 8550b57cec5SDimitry Andric void StmtPrinter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *Node) { 8560b57cec5SDimitry Andric Indent() << "#pragma omp taskyield"; 8570b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 8580b57cec5SDimitry Andric } 8590b57cec5SDimitry Andric 8600b57cec5SDimitry Andric void StmtPrinter::VisitOMPBarrierDirective(OMPBarrierDirective *Node) { 8610b57cec5SDimitry Andric Indent() << "#pragma omp barrier"; 8620b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 8630b57cec5SDimitry Andric } 8640b57cec5SDimitry Andric 8650b57cec5SDimitry Andric void StmtPrinter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *Node) { 8660b57cec5SDimitry Andric Indent() << "#pragma omp taskwait"; 8670b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 8680b57cec5SDimitry Andric } 8690b57cec5SDimitry Andric 870bdd1243dSDimitry Andric void StmtPrinter::VisitOMPErrorDirective(OMPErrorDirective *Node) { 871bdd1243dSDimitry Andric Indent() << "#pragma omp error"; 872bdd1243dSDimitry Andric PrintOMPExecutableDirective(Node); 873bdd1243dSDimitry Andric } 874bdd1243dSDimitry Andric 8750b57cec5SDimitry Andric void StmtPrinter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *Node) { 8760b57cec5SDimitry Andric Indent() << "#pragma omp taskgroup"; 8770b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 8780b57cec5SDimitry Andric } 8790b57cec5SDimitry Andric 8800b57cec5SDimitry Andric void StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) { 8810b57cec5SDimitry Andric Indent() << "#pragma omp flush"; 8820b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 8830b57cec5SDimitry Andric } 8840b57cec5SDimitry Andric 8855ffd83dbSDimitry Andric void StmtPrinter::VisitOMPDepobjDirective(OMPDepobjDirective *Node) { 8865ffd83dbSDimitry Andric Indent() << "#pragma omp depobj"; 8875ffd83dbSDimitry Andric PrintOMPExecutableDirective(Node); 8885ffd83dbSDimitry Andric } 8895ffd83dbSDimitry Andric 8905ffd83dbSDimitry Andric void StmtPrinter::VisitOMPScanDirective(OMPScanDirective *Node) { 8915ffd83dbSDimitry Andric Indent() << "#pragma omp scan"; 8925ffd83dbSDimitry Andric PrintOMPExecutableDirective(Node); 8935ffd83dbSDimitry Andric } 8945ffd83dbSDimitry Andric 8950b57cec5SDimitry Andric void StmtPrinter::VisitOMPOrderedDirective(OMPOrderedDirective *Node) { 8960b57cec5SDimitry Andric Indent() << "#pragma omp ordered"; 8970b57cec5SDimitry Andric PrintOMPExecutableDirective(Node, Node->hasClausesOfKind<OMPDependClause>()); 8980b57cec5SDimitry Andric } 8990b57cec5SDimitry Andric 9000b57cec5SDimitry Andric void StmtPrinter::VisitOMPAtomicDirective(OMPAtomicDirective *Node) { 9010b57cec5SDimitry Andric Indent() << "#pragma omp atomic"; 9020b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 9030b57cec5SDimitry Andric } 9040b57cec5SDimitry Andric 9050b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetDirective(OMPTargetDirective *Node) { 9060b57cec5SDimitry Andric Indent() << "#pragma omp target"; 9070b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 9080b57cec5SDimitry Andric } 9090b57cec5SDimitry Andric 9100b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetDataDirective(OMPTargetDataDirective *Node) { 9110b57cec5SDimitry Andric Indent() << "#pragma omp target data"; 9120b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 9130b57cec5SDimitry Andric } 9140b57cec5SDimitry Andric 9150b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetEnterDataDirective( 9160b57cec5SDimitry Andric OMPTargetEnterDataDirective *Node) { 9170b57cec5SDimitry Andric Indent() << "#pragma omp target enter data"; 9180b57cec5SDimitry Andric PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true); 9190b57cec5SDimitry Andric } 9200b57cec5SDimitry Andric 9210b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetExitDataDirective( 9220b57cec5SDimitry Andric OMPTargetExitDataDirective *Node) { 9230b57cec5SDimitry Andric Indent() << "#pragma omp target exit data"; 9240b57cec5SDimitry Andric PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true); 9250b57cec5SDimitry Andric } 9260b57cec5SDimitry Andric 9270b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetParallelDirective( 9280b57cec5SDimitry Andric OMPTargetParallelDirective *Node) { 9290b57cec5SDimitry Andric Indent() << "#pragma omp target parallel"; 9300b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 9310b57cec5SDimitry Andric } 9320b57cec5SDimitry Andric 9330b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetParallelForDirective( 9340b57cec5SDimitry Andric OMPTargetParallelForDirective *Node) { 9350b57cec5SDimitry Andric Indent() << "#pragma omp target parallel for"; 9360b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 9370b57cec5SDimitry Andric } 9380b57cec5SDimitry Andric 9390b57cec5SDimitry Andric void StmtPrinter::VisitOMPTeamsDirective(OMPTeamsDirective *Node) { 9400b57cec5SDimitry Andric Indent() << "#pragma omp teams"; 9410b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 9420b57cec5SDimitry Andric } 9430b57cec5SDimitry Andric 9440b57cec5SDimitry Andric void StmtPrinter::VisitOMPCancellationPointDirective( 9450b57cec5SDimitry Andric OMPCancellationPointDirective *Node) { 9460b57cec5SDimitry Andric Indent() << "#pragma omp cancellation point " 9470b57cec5SDimitry Andric << getOpenMPDirectiveName(Node->getCancelRegion()); 9480b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 9490b57cec5SDimitry Andric } 9500b57cec5SDimitry Andric 9510b57cec5SDimitry Andric void StmtPrinter::VisitOMPCancelDirective(OMPCancelDirective *Node) { 9520b57cec5SDimitry Andric Indent() << "#pragma omp cancel " 9530b57cec5SDimitry Andric << getOpenMPDirectiveName(Node->getCancelRegion()); 9540b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 9550b57cec5SDimitry Andric } 9560b57cec5SDimitry Andric 9570b57cec5SDimitry Andric void StmtPrinter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *Node) { 9580b57cec5SDimitry Andric Indent() << "#pragma omp taskloop"; 9590b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 9600b57cec5SDimitry Andric } 9610b57cec5SDimitry Andric 9620b57cec5SDimitry Andric void StmtPrinter::VisitOMPTaskLoopSimdDirective( 9630b57cec5SDimitry Andric OMPTaskLoopSimdDirective *Node) { 9640b57cec5SDimitry Andric Indent() << "#pragma omp taskloop simd"; 9650b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 9660b57cec5SDimitry Andric } 9670b57cec5SDimitry Andric 968a7dea167SDimitry Andric void StmtPrinter::VisitOMPMasterTaskLoopDirective( 969a7dea167SDimitry Andric OMPMasterTaskLoopDirective *Node) { 970a7dea167SDimitry Andric Indent() << "#pragma omp master taskloop"; 971a7dea167SDimitry Andric PrintOMPExecutableDirective(Node); 972a7dea167SDimitry Andric } 973a7dea167SDimitry Andric 97481ad6265SDimitry Andric void StmtPrinter::VisitOMPMaskedTaskLoopDirective( 97581ad6265SDimitry Andric OMPMaskedTaskLoopDirective *Node) { 97681ad6265SDimitry Andric Indent() << "#pragma omp masked taskloop"; 97781ad6265SDimitry Andric PrintOMPExecutableDirective(Node); 97881ad6265SDimitry Andric } 97981ad6265SDimitry Andric 980a7dea167SDimitry Andric void StmtPrinter::VisitOMPMasterTaskLoopSimdDirective( 981a7dea167SDimitry Andric OMPMasterTaskLoopSimdDirective *Node) { 982a7dea167SDimitry Andric Indent() << "#pragma omp master taskloop simd"; 983a7dea167SDimitry Andric PrintOMPExecutableDirective(Node); 984a7dea167SDimitry Andric } 985a7dea167SDimitry Andric 98681ad6265SDimitry Andric void StmtPrinter::VisitOMPMaskedTaskLoopSimdDirective( 98781ad6265SDimitry Andric OMPMaskedTaskLoopSimdDirective *Node) { 98881ad6265SDimitry Andric Indent() << "#pragma omp masked taskloop simd"; 98981ad6265SDimitry Andric PrintOMPExecutableDirective(Node); 99081ad6265SDimitry Andric } 99181ad6265SDimitry Andric 992a7dea167SDimitry Andric void StmtPrinter::VisitOMPParallelMasterTaskLoopDirective( 993a7dea167SDimitry Andric OMPParallelMasterTaskLoopDirective *Node) { 994a7dea167SDimitry Andric Indent() << "#pragma omp parallel master taskloop"; 995a7dea167SDimitry Andric PrintOMPExecutableDirective(Node); 996a7dea167SDimitry Andric } 997a7dea167SDimitry Andric 99881ad6265SDimitry Andric void StmtPrinter::VisitOMPParallelMaskedTaskLoopDirective( 99981ad6265SDimitry Andric OMPParallelMaskedTaskLoopDirective *Node) { 100081ad6265SDimitry Andric Indent() << "#pragma omp parallel masked taskloop"; 100181ad6265SDimitry Andric PrintOMPExecutableDirective(Node); 100281ad6265SDimitry Andric } 100381ad6265SDimitry Andric 1004480093f4SDimitry Andric void StmtPrinter::VisitOMPParallelMasterTaskLoopSimdDirective( 1005480093f4SDimitry Andric OMPParallelMasterTaskLoopSimdDirective *Node) { 1006480093f4SDimitry Andric Indent() << "#pragma omp parallel master taskloop simd"; 1007480093f4SDimitry Andric PrintOMPExecutableDirective(Node); 1008480093f4SDimitry Andric } 1009480093f4SDimitry Andric 101081ad6265SDimitry Andric void StmtPrinter::VisitOMPParallelMaskedTaskLoopSimdDirective( 101181ad6265SDimitry Andric OMPParallelMaskedTaskLoopSimdDirective *Node) { 101281ad6265SDimitry Andric Indent() << "#pragma omp parallel masked taskloop simd"; 101381ad6265SDimitry Andric PrintOMPExecutableDirective(Node); 101481ad6265SDimitry Andric } 101581ad6265SDimitry Andric 10160b57cec5SDimitry Andric void StmtPrinter::VisitOMPDistributeDirective(OMPDistributeDirective *Node) { 10170b57cec5SDimitry Andric Indent() << "#pragma omp distribute"; 10180b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 10190b57cec5SDimitry Andric } 10200b57cec5SDimitry Andric 10210b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetUpdateDirective( 10220b57cec5SDimitry Andric OMPTargetUpdateDirective *Node) { 10230b57cec5SDimitry Andric Indent() << "#pragma omp target update"; 10240b57cec5SDimitry Andric PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true); 10250b57cec5SDimitry Andric } 10260b57cec5SDimitry Andric 10270b57cec5SDimitry Andric void StmtPrinter::VisitOMPDistributeParallelForDirective( 10280b57cec5SDimitry Andric OMPDistributeParallelForDirective *Node) { 10290b57cec5SDimitry Andric Indent() << "#pragma omp distribute parallel for"; 10300b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 10310b57cec5SDimitry Andric } 10320b57cec5SDimitry Andric 10330b57cec5SDimitry Andric void StmtPrinter::VisitOMPDistributeParallelForSimdDirective( 10340b57cec5SDimitry Andric OMPDistributeParallelForSimdDirective *Node) { 10350b57cec5SDimitry Andric Indent() << "#pragma omp distribute parallel for simd"; 10360b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 10370b57cec5SDimitry Andric } 10380b57cec5SDimitry Andric 10390b57cec5SDimitry Andric void StmtPrinter::VisitOMPDistributeSimdDirective( 10400b57cec5SDimitry Andric OMPDistributeSimdDirective *Node) { 10410b57cec5SDimitry Andric Indent() << "#pragma omp distribute simd"; 10420b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 10430b57cec5SDimitry Andric } 10440b57cec5SDimitry Andric 10450b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetParallelForSimdDirective( 10460b57cec5SDimitry Andric OMPTargetParallelForSimdDirective *Node) { 10470b57cec5SDimitry Andric Indent() << "#pragma omp target parallel for simd"; 10480b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 10490b57cec5SDimitry Andric } 10500b57cec5SDimitry Andric 10510b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *Node) { 10520b57cec5SDimitry Andric Indent() << "#pragma omp target simd"; 10530b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 10540b57cec5SDimitry Andric } 10550b57cec5SDimitry Andric 10560b57cec5SDimitry Andric void StmtPrinter::VisitOMPTeamsDistributeDirective( 10570b57cec5SDimitry Andric OMPTeamsDistributeDirective *Node) { 10580b57cec5SDimitry Andric Indent() << "#pragma omp teams distribute"; 10590b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 10600b57cec5SDimitry Andric } 10610b57cec5SDimitry Andric 10620b57cec5SDimitry Andric void StmtPrinter::VisitOMPTeamsDistributeSimdDirective( 10630b57cec5SDimitry Andric OMPTeamsDistributeSimdDirective *Node) { 10640b57cec5SDimitry Andric Indent() << "#pragma omp teams distribute simd"; 10650b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 10660b57cec5SDimitry Andric } 10670b57cec5SDimitry Andric 10680b57cec5SDimitry Andric void StmtPrinter::VisitOMPTeamsDistributeParallelForSimdDirective( 10690b57cec5SDimitry Andric OMPTeamsDistributeParallelForSimdDirective *Node) { 10700b57cec5SDimitry Andric Indent() << "#pragma omp teams distribute parallel for simd"; 10710b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 10720b57cec5SDimitry Andric } 10730b57cec5SDimitry Andric 10740b57cec5SDimitry Andric void StmtPrinter::VisitOMPTeamsDistributeParallelForDirective( 10750b57cec5SDimitry Andric OMPTeamsDistributeParallelForDirective *Node) { 10760b57cec5SDimitry Andric Indent() << "#pragma omp teams distribute parallel for"; 10770b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 10780b57cec5SDimitry Andric } 10790b57cec5SDimitry Andric 10800b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *Node) { 10810b57cec5SDimitry Andric Indent() << "#pragma omp target teams"; 10820b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 10830b57cec5SDimitry Andric } 10840b57cec5SDimitry Andric 10850b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetTeamsDistributeDirective( 10860b57cec5SDimitry Andric OMPTargetTeamsDistributeDirective *Node) { 10870b57cec5SDimitry Andric Indent() << "#pragma omp target teams distribute"; 10880b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 10890b57cec5SDimitry Andric } 10900b57cec5SDimitry Andric 10910b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForDirective( 10920b57cec5SDimitry Andric OMPTargetTeamsDistributeParallelForDirective *Node) { 10930b57cec5SDimitry Andric Indent() << "#pragma omp target teams distribute parallel for"; 10940b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 10950b57cec5SDimitry Andric } 10960b57cec5SDimitry Andric 10970b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForSimdDirective( 10980b57cec5SDimitry Andric OMPTargetTeamsDistributeParallelForSimdDirective *Node) { 10990b57cec5SDimitry Andric Indent() << "#pragma omp target teams distribute parallel for simd"; 11000b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 11010b57cec5SDimitry Andric } 11020b57cec5SDimitry Andric 11030b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetTeamsDistributeSimdDirective( 11040b57cec5SDimitry Andric OMPTargetTeamsDistributeSimdDirective *Node) { 11050b57cec5SDimitry Andric Indent() << "#pragma omp target teams distribute simd"; 11060b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 11070b57cec5SDimitry Andric } 11080b57cec5SDimitry Andric 1109fe6060f1SDimitry Andric void StmtPrinter::VisitOMPInteropDirective(OMPInteropDirective *Node) { 1110fe6060f1SDimitry Andric Indent() << "#pragma omp interop"; 1111fe6060f1SDimitry Andric PrintOMPExecutableDirective(Node); 1112fe6060f1SDimitry Andric } 1113fe6060f1SDimitry Andric 1114fe6060f1SDimitry Andric void StmtPrinter::VisitOMPDispatchDirective(OMPDispatchDirective *Node) { 1115fe6060f1SDimitry Andric Indent() << "#pragma omp dispatch"; 1116fe6060f1SDimitry Andric PrintOMPExecutableDirective(Node); 1117fe6060f1SDimitry Andric } 1118fe6060f1SDimitry Andric 1119fe6060f1SDimitry Andric void StmtPrinter::VisitOMPMaskedDirective(OMPMaskedDirective *Node) { 1120fe6060f1SDimitry Andric Indent() << "#pragma omp masked"; 1121fe6060f1SDimitry Andric PrintOMPExecutableDirective(Node); 1122fe6060f1SDimitry Andric } 1123fe6060f1SDimitry Andric 1124349cc55cSDimitry Andric void StmtPrinter::VisitOMPGenericLoopDirective(OMPGenericLoopDirective *Node) { 1125349cc55cSDimitry Andric Indent() << "#pragma omp loop"; 1126349cc55cSDimitry Andric PrintOMPExecutableDirective(Node); 1127349cc55cSDimitry Andric } 1128349cc55cSDimitry Andric 112981ad6265SDimitry Andric void StmtPrinter::VisitOMPTeamsGenericLoopDirective( 113081ad6265SDimitry Andric OMPTeamsGenericLoopDirective *Node) { 113181ad6265SDimitry Andric Indent() << "#pragma omp teams loop"; 113281ad6265SDimitry Andric PrintOMPExecutableDirective(Node); 113381ad6265SDimitry Andric } 113481ad6265SDimitry Andric 113581ad6265SDimitry Andric void StmtPrinter::VisitOMPTargetTeamsGenericLoopDirective( 113681ad6265SDimitry Andric OMPTargetTeamsGenericLoopDirective *Node) { 113781ad6265SDimitry Andric Indent() << "#pragma omp target teams loop"; 113881ad6265SDimitry Andric PrintOMPExecutableDirective(Node); 113981ad6265SDimitry Andric } 114081ad6265SDimitry Andric 114181ad6265SDimitry Andric void StmtPrinter::VisitOMPParallelGenericLoopDirective( 114281ad6265SDimitry Andric OMPParallelGenericLoopDirective *Node) { 114381ad6265SDimitry Andric Indent() << "#pragma omp parallel loop"; 114481ad6265SDimitry Andric PrintOMPExecutableDirective(Node); 114581ad6265SDimitry Andric } 114681ad6265SDimitry Andric 114781ad6265SDimitry Andric void StmtPrinter::VisitOMPTargetParallelGenericLoopDirective( 114881ad6265SDimitry Andric OMPTargetParallelGenericLoopDirective *Node) { 114981ad6265SDimitry Andric Indent() << "#pragma omp target parallel loop"; 115081ad6265SDimitry Andric PrintOMPExecutableDirective(Node); 115181ad6265SDimitry Andric } 115281ad6265SDimitry Andric 11530b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1154*0fca6ea1SDimitry Andric // OpenACC construct printing methods 1155*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 1156*0fca6ea1SDimitry Andric void StmtPrinter::VisitOpenACCComputeConstruct(OpenACCComputeConstruct *S) { 1157*0fca6ea1SDimitry Andric Indent() << "#pragma acc " << S->getDirectiveKind(); 1158*0fca6ea1SDimitry Andric 1159*0fca6ea1SDimitry Andric if (!S->clauses().empty()) { 1160*0fca6ea1SDimitry Andric OS << ' '; 1161*0fca6ea1SDimitry Andric OpenACCClausePrinter Printer(OS, Policy); 1162*0fca6ea1SDimitry Andric Printer.VisitClauseList(S->clauses()); 1163*0fca6ea1SDimitry Andric } 1164*0fca6ea1SDimitry Andric OS << '\n'; 1165*0fca6ea1SDimitry Andric 1166*0fca6ea1SDimitry Andric PrintStmt(S->getStructuredBlock()); 1167*0fca6ea1SDimitry Andric } 1168*0fca6ea1SDimitry Andric 1169*0fca6ea1SDimitry Andric void StmtPrinter::VisitOpenACCLoopConstruct(OpenACCLoopConstruct *S) { 1170*0fca6ea1SDimitry Andric Indent() << "#pragma acc loop"; 1171*0fca6ea1SDimitry Andric 1172*0fca6ea1SDimitry Andric if (!S->clauses().empty()) { 1173*0fca6ea1SDimitry Andric OS << ' '; 1174*0fca6ea1SDimitry Andric OpenACCClausePrinter Printer(OS, Policy); 1175*0fca6ea1SDimitry Andric Printer.VisitClauseList(S->clauses()); 1176*0fca6ea1SDimitry Andric } 1177*0fca6ea1SDimitry Andric OS << '\n'; 1178*0fca6ea1SDimitry Andric 1179*0fca6ea1SDimitry Andric PrintStmt(S->getLoop()); 1180*0fca6ea1SDimitry Andric } 1181*0fca6ea1SDimitry Andric 1182*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 11830b57cec5SDimitry Andric // Expr printing methods. 11840b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 11850b57cec5SDimitry Andric 11860b57cec5SDimitry Andric void StmtPrinter::VisitSourceLocExpr(SourceLocExpr *Node) { 11870b57cec5SDimitry Andric OS << Node->getBuiltinStr() << "()"; 11880b57cec5SDimitry Andric } 11890b57cec5SDimitry Andric 1190*0fca6ea1SDimitry Andric void StmtPrinter::VisitEmbedExpr(EmbedExpr *Node) { 1191*0fca6ea1SDimitry Andric llvm::report_fatal_error("Not implemented"); 1192*0fca6ea1SDimitry Andric } 1193*0fca6ea1SDimitry Andric 11940b57cec5SDimitry Andric void StmtPrinter::VisitConstantExpr(ConstantExpr *Node) { 11950b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 11960b57cec5SDimitry Andric } 11970b57cec5SDimitry Andric 11980b57cec5SDimitry Andric void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) { 11990b57cec5SDimitry Andric if (const auto *OCED = dyn_cast<OMPCapturedExprDecl>(Node->getDecl())) { 12000b57cec5SDimitry Andric OCED->getInit()->IgnoreImpCasts()->printPretty(OS, nullptr, Policy); 12010b57cec5SDimitry Andric return; 12020b57cec5SDimitry Andric } 1203e8d8bef9SDimitry Andric if (const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(Node->getDecl())) { 120481ad6265SDimitry Andric TPOD->printAsExpr(OS, Policy); 1205e8d8bef9SDimitry Andric return; 1206e8d8bef9SDimitry Andric } 12070b57cec5SDimitry Andric if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 12080b57cec5SDimitry Andric Qualifier->print(OS, Policy); 12090b57cec5SDimitry Andric if (Node->hasTemplateKeyword()) 12100b57cec5SDimitry Andric OS << "template "; 121104eeddc0SDimitry Andric if (Policy.CleanUglifiedParameters && 121204eeddc0SDimitry Andric isa<ParmVarDecl, NonTypeTemplateParmDecl>(Node->getDecl()) && 121304eeddc0SDimitry Andric Node->getDecl()->getIdentifier()) 121404eeddc0SDimitry Andric OS << Node->getDecl()->getIdentifier()->deuglifiedName(); 121504eeddc0SDimitry Andric else 121604eeddc0SDimitry Andric Node->getNameInfo().printName(OS, Policy); 1217fe6060f1SDimitry Andric if (Node->hasExplicitTemplateArgs()) { 1218fe6060f1SDimitry Andric const TemplateParameterList *TPL = nullptr; 1219fe6060f1SDimitry Andric if (!Node->hadMultipleCandidates()) 1220fe6060f1SDimitry Andric if (auto *TD = dyn_cast<TemplateDecl>(Node->getDecl())) 1221fe6060f1SDimitry Andric TPL = TD->getTemplateParameters(); 1222fe6060f1SDimitry Andric printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL); 1223fe6060f1SDimitry Andric } 12240b57cec5SDimitry Andric } 12250b57cec5SDimitry Andric 12260b57cec5SDimitry Andric void StmtPrinter::VisitDependentScopeDeclRefExpr( 12270b57cec5SDimitry Andric DependentScopeDeclRefExpr *Node) { 12280b57cec5SDimitry Andric if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 12290b57cec5SDimitry Andric Qualifier->print(OS, Policy); 12300b57cec5SDimitry Andric if (Node->hasTemplateKeyword()) 12310b57cec5SDimitry Andric OS << "template "; 12320b57cec5SDimitry Andric OS << Node->getNameInfo(); 12330b57cec5SDimitry Andric if (Node->hasExplicitTemplateArgs()) 12340b57cec5SDimitry Andric printTemplateArgumentList(OS, Node->template_arguments(), Policy); 12350b57cec5SDimitry Andric } 12360b57cec5SDimitry Andric 12370b57cec5SDimitry Andric void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) { 12380b57cec5SDimitry Andric if (Node->getQualifier()) 12390b57cec5SDimitry Andric Node->getQualifier()->print(OS, Policy); 12400b57cec5SDimitry Andric if (Node->hasTemplateKeyword()) 12410b57cec5SDimitry Andric OS << "template "; 12420b57cec5SDimitry Andric OS << Node->getNameInfo(); 12430b57cec5SDimitry Andric if (Node->hasExplicitTemplateArgs()) 12440b57cec5SDimitry Andric printTemplateArgumentList(OS, Node->template_arguments(), Policy); 12450b57cec5SDimitry Andric } 12460b57cec5SDimitry Andric 12470b57cec5SDimitry Andric static bool isImplicitSelf(const Expr *E) { 12480b57cec5SDimitry Andric if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) { 12490b57cec5SDimitry Andric if (const auto *PD = dyn_cast<ImplicitParamDecl>(DRE->getDecl())) { 12505f757f3fSDimitry Andric if (PD->getParameterKind() == ImplicitParamKind::ObjCSelf && 12510b57cec5SDimitry Andric DRE->getBeginLoc().isInvalid()) 12520b57cec5SDimitry Andric return true; 12530b57cec5SDimitry Andric } 12540b57cec5SDimitry Andric } 12550b57cec5SDimitry Andric return false; 12560b57cec5SDimitry Andric } 12570b57cec5SDimitry Andric 12580b57cec5SDimitry Andric void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { 12590b57cec5SDimitry Andric if (Node->getBase()) { 12600b57cec5SDimitry Andric if (!Policy.SuppressImplicitBase || 12610b57cec5SDimitry Andric !isImplicitSelf(Node->getBase()->IgnoreImpCasts())) { 12620b57cec5SDimitry Andric PrintExpr(Node->getBase()); 12630b57cec5SDimitry Andric OS << (Node->isArrow() ? "->" : "."); 12640b57cec5SDimitry Andric } 12650b57cec5SDimitry Andric } 12660b57cec5SDimitry Andric OS << *Node->getDecl(); 12670b57cec5SDimitry Andric } 12680b57cec5SDimitry Andric 12690b57cec5SDimitry Andric void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) { 12700b57cec5SDimitry Andric if (Node->isSuperReceiver()) 12710b57cec5SDimitry Andric OS << "super."; 12720b57cec5SDimitry Andric else if (Node->isObjectReceiver() && Node->getBase()) { 12730b57cec5SDimitry Andric PrintExpr(Node->getBase()); 12740b57cec5SDimitry Andric OS << "."; 12750b57cec5SDimitry Andric } else if (Node->isClassReceiver() && Node->getClassReceiver()) { 12760b57cec5SDimitry Andric OS << Node->getClassReceiver()->getName() << "."; 12770b57cec5SDimitry Andric } 12780b57cec5SDimitry Andric 12790b57cec5SDimitry Andric if (Node->isImplicitProperty()) { 12800b57cec5SDimitry Andric if (const auto *Getter = Node->getImplicitPropertyGetter()) 12810b57cec5SDimitry Andric Getter->getSelector().print(OS); 12820b57cec5SDimitry Andric else 12830b57cec5SDimitry Andric OS << SelectorTable::getPropertyNameFromSetterSelector( 12840b57cec5SDimitry Andric Node->getImplicitPropertySetter()->getSelector()); 12850b57cec5SDimitry Andric } else 12860b57cec5SDimitry Andric OS << Node->getExplicitProperty()->getName(); 12870b57cec5SDimitry Andric } 12880b57cec5SDimitry Andric 12890b57cec5SDimitry Andric void StmtPrinter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node) { 12900b57cec5SDimitry Andric PrintExpr(Node->getBaseExpr()); 12910b57cec5SDimitry Andric OS << "["; 12920b57cec5SDimitry Andric PrintExpr(Node->getKeyExpr()); 12930b57cec5SDimitry Andric OS << "]"; 12940b57cec5SDimitry Andric } 12950b57cec5SDimitry Andric 1296fe6060f1SDimitry Andric void StmtPrinter::VisitSYCLUniqueStableNameExpr( 1297fe6060f1SDimitry Andric SYCLUniqueStableNameExpr *Node) { 1298fe6060f1SDimitry Andric OS << "__builtin_sycl_unique_stable_name("; 1299fe6060f1SDimitry Andric Node->getTypeSourceInfo()->getType().print(OS, Policy); 1300fe6060f1SDimitry Andric OS << ")"; 1301fe6060f1SDimitry Andric } 1302fe6060f1SDimitry Andric 13030b57cec5SDimitry Andric void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) { 13040b57cec5SDimitry Andric OS << PredefinedExpr::getIdentKindName(Node->getIdentKind()); 13050b57cec5SDimitry Andric } 13060b57cec5SDimitry Andric 13070b57cec5SDimitry Andric void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) { 1308fe6060f1SDimitry Andric CharacterLiteral::print(Node->getValue(), Node->getKind(), OS); 13090b57cec5SDimitry Andric } 13100b57cec5SDimitry Andric 13110b57cec5SDimitry Andric /// Prints the given expression using the original source text. Returns true on 13120b57cec5SDimitry Andric /// success, false otherwise. 13130b57cec5SDimitry Andric static bool printExprAsWritten(raw_ostream &OS, Expr *E, 13140b57cec5SDimitry Andric const ASTContext *Context) { 13150b57cec5SDimitry Andric if (!Context) 13160b57cec5SDimitry Andric return false; 13170b57cec5SDimitry Andric bool Invalid = false; 13180b57cec5SDimitry Andric StringRef Source = Lexer::getSourceText( 13190b57cec5SDimitry Andric CharSourceRange::getTokenRange(E->getSourceRange()), 13200b57cec5SDimitry Andric Context->getSourceManager(), Context->getLangOpts(), &Invalid); 13210b57cec5SDimitry Andric if (!Invalid) { 13220b57cec5SDimitry Andric OS << Source; 13230b57cec5SDimitry Andric return true; 13240b57cec5SDimitry Andric } 13250b57cec5SDimitry Andric return false; 13260b57cec5SDimitry Andric } 13270b57cec5SDimitry Andric 13280b57cec5SDimitry Andric void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) { 13290b57cec5SDimitry Andric if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context)) 13300b57cec5SDimitry Andric return; 13310b57cec5SDimitry Andric bool isSigned = Node->getType()->isSignedIntegerType(); 1332fe6060f1SDimitry Andric OS << toString(Node->getValue(), 10, isSigned); 13330b57cec5SDimitry Andric 133481ad6265SDimitry Andric if (isa<BitIntType>(Node->getType())) { 133581ad6265SDimitry Andric OS << (isSigned ? "wb" : "uwb"); 133681ad6265SDimitry Andric return; 133781ad6265SDimitry Andric } 133881ad6265SDimitry Andric 13390b57cec5SDimitry Andric // Emit suffixes. Integer literals are always a builtin integer type. 1340a7dea167SDimitry Andric switch (Node->getType()->castAs<BuiltinType>()->getKind()) { 13410b57cec5SDimitry Andric default: llvm_unreachable("Unexpected type for integer literal!"); 13420b57cec5SDimitry Andric case BuiltinType::Char_S: 13430b57cec5SDimitry Andric case BuiltinType::Char_U: OS << "i8"; break; 13440b57cec5SDimitry Andric case BuiltinType::UChar: OS << "Ui8"; break; 1345bdd1243dSDimitry Andric case BuiltinType::SChar: OS << "i8"; break; 13460b57cec5SDimitry Andric case BuiltinType::Short: OS << "i16"; break; 13470b57cec5SDimitry Andric case BuiltinType::UShort: OS << "Ui16"; break; 13480b57cec5SDimitry Andric case BuiltinType::Int: break; // no suffix. 13490b57cec5SDimitry Andric case BuiltinType::UInt: OS << 'U'; break; 13500b57cec5SDimitry Andric case BuiltinType::Long: OS << 'L'; break; 13510b57cec5SDimitry Andric case BuiltinType::ULong: OS << "UL"; break; 13520b57cec5SDimitry Andric case BuiltinType::LongLong: OS << "LL"; break; 13530b57cec5SDimitry Andric case BuiltinType::ULongLong: OS << "ULL"; break; 1354fe6060f1SDimitry Andric case BuiltinType::Int128: 1355fe6060f1SDimitry Andric break; // no suffix. 1356fe6060f1SDimitry Andric case BuiltinType::UInt128: 1357fe6060f1SDimitry Andric break; // no suffix. 1358bdd1243dSDimitry Andric case BuiltinType::WChar_S: 1359bdd1243dSDimitry Andric case BuiltinType::WChar_U: 1360bdd1243dSDimitry Andric break; // no suffix 13610b57cec5SDimitry Andric } 13620b57cec5SDimitry Andric } 13630b57cec5SDimitry Andric 13640b57cec5SDimitry Andric void StmtPrinter::VisitFixedPointLiteral(FixedPointLiteral *Node) { 13650b57cec5SDimitry Andric if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context)) 13660b57cec5SDimitry Andric return; 13670b57cec5SDimitry Andric OS << Node->getValueAsString(/*Radix=*/10); 13680b57cec5SDimitry Andric 1369a7dea167SDimitry Andric switch (Node->getType()->castAs<BuiltinType>()->getKind()) { 13700b57cec5SDimitry Andric default: llvm_unreachable("Unexpected type for fixed point literal!"); 13710b57cec5SDimitry Andric case BuiltinType::ShortFract: OS << "hr"; break; 13720b57cec5SDimitry Andric case BuiltinType::ShortAccum: OS << "hk"; break; 13730b57cec5SDimitry Andric case BuiltinType::UShortFract: OS << "uhr"; break; 13740b57cec5SDimitry Andric case BuiltinType::UShortAccum: OS << "uhk"; break; 13750b57cec5SDimitry Andric case BuiltinType::Fract: OS << "r"; break; 13760b57cec5SDimitry Andric case BuiltinType::Accum: OS << "k"; break; 13770b57cec5SDimitry Andric case BuiltinType::UFract: OS << "ur"; break; 13780b57cec5SDimitry Andric case BuiltinType::UAccum: OS << "uk"; break; 13790b57cec5SDimitry Andric case BuiltinType::LongFract: OS << "lr"; break; 13800b57cec5SDimitry Andric case BuiltinType::LongAccum: OS << "lk"; break; 13810b57cec5SDimitry Andric case BuiltinType::ULongFract: OS << "ulr"; break; 13820b57cec5SDimitry Andric case BuiltinType::ULongAccum: OS << "ulk"; break; 13830b57cec5SDimitry Andric } 13840b57cec5SDimitry Andric } 13850b57cec5SDimitry Andric 13860b57cec5SDimitry Andric static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node, 13870b57cec5SDimitry Andric bool PrintSuffix) { 13880b57cec5SDimitry Andric SmallString<16> Str; 13890b57cec5SDimitry Andric Node->getValue().toString(Str); 13900b57cec5SDimitry Andric OS << Str; 13910b57cec5SDimitry Andric if (Str.find_first_not_of("-0123456789") == StringRef::npos) 13920b57cec5SDimitry Andric OS << '.'; // Trailing dot in order to separate from ints. 13930b57cec5SDimitry Andric 13940b57cec5SDimitry Andric if (!PrintSuffix) 13950b57cec5SDimitry Andric return; 13960b57cec5SDimitry Andric 13970b57cec5SDimitry Andric // Emit suffixes. Float literals are always a builtin float type. 1398a7dea167SDimitry Andric switch (Node->getType()->castAs<BuiltinType>()->getKind()) { 13990b57cec5SDimitry Andric default: llvm_unreachable("Unexpected type for float literal!"); 14000b57cec5SDimitry Andric case BuiltinType::Half: break; // FIXME: suffix? 1401349cc55cSDimitry Andric case BuiltinType::Ibm128: break; // FIXME: No suffix for ibm128 literal 14020b57cec5SDimitry Andric case BuiltinType::Double: break; // no suffix. 14030b57cec5SDimitry Andric case BuiltinType::Float16: OS << "F16"; break; 14040b57cec5SDimitry Andric case BuiltinType::Float: OS << 'F'; break; 14050b57cec5SDimitry Andric case BuiltinType::LongDouble: OS << 'L'; break; 14060b57cec5SDimitry Andric case BuiltinType::Float128: OS << 'Q'; break; 14070b57cec5SDimitry Andric } 14080b57cec5SDimitry Andric } 14090b57cec5SDimitry Andric 14100b57cec5SDimitry Andric void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) { 14110b57cec5SDimitry Andric if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context)) 14120b57cec5SDimitry Andric return; 14130b57cec5SDimitry Andric PrintFloatingLiteral(OS, Node, /*PrintSuffix=*/true); 14140b57cec5SDimitry Andric } 14150b57cec5SDimitry Andric 14160b57cec5SDimitry Andric void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) { 14170b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 14180b57cec5SDimitry Andric OS << "i"; 14190b57cec5SDimitry Andric } 14200b57cec5SDimitry Andric 14210b57cec5SDimitry Andric void StmtPrinter::VisitStringLiteral(StringLiteral *Str) { 14220b57cec5SDimitry Andric Str->outputString(OS); 14230b57cec5SDimitry Andric } 14240b57cec5SDimitry Andric 14250b57cec5SDimitry Andric void StmtPrinter::VisitParenExpr(ParenExpr *Node) { 14260b57cec5SDimitry Andric OS << "("; 14270b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 14280b57cec5SDimitry Andric OS << ")"; 14290b57cec5SDimitry Andric } 14300b57cec5SDimitry Andric 14310b57cec5SDimitry Andric void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) { 14320b57cec5SDimitry Andric if (!Node->isPostfix()) { 14330b57cec5SDimitry Andric OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 14340b57cec5SDimitry Andric 14350b57cec5SDimitry Andric // Print a space if this is an "identifier operator" like __real, or if 14360b57cec5SDimitry Andric // it might be concatenated incorrectly like '+'. 14370b57cec5SDimitry Andric switch (Node->getOpcode()) { 14380b57cec5SDimitry Andric default: break; 14390b57cec5SDimitry Andric case UO_Real: 14400b57cec5SDimitry Andric case UO_Imag: 14410b57cec5SDimitry Andric case UO_Extension: 14420b57cec5SDimitry Andric OS << ' '; 14430b57cec5SDimitry Andric break; 14440b57cec5SDimitry Andric case UO_Plus: 14450b57cec5SDimitry Andric case UO_Minus: 14460b57cec5SDimitry Andric if (isa<UnaryOperator>(Node->getSubExpr())) 14470b57cec5SDimitry Andric OS << ' '; 14480b57cec5SDimitry Andric break; 14490b57cec5SDimitry Andric } 14500b57cec5SDimitry Andric } 14510b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 14520b57cec5SDimitry Andric 14530b57cec5SDimitry Andric if (Node->isPostfix()) 14540b57cec5SDimitry Andric OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 14550b57cec5SDimitry Andric } 14560b57cec5SDimitry Andric 14570b57cec5SDimitry Andric void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) { 14580b57cec5SDimitry Andric OS << "__builtin_offsetof("; 14590b57cec5SDimitry Andric Node->getTypeSourceInfo()->getType().print(OS, Policy); 14600b57cec5SDimitry Andric OS << ", "; 14610b57cec5SDimitry Andric bool PrintedSomething = false; 14620b57cec5SDimitry Andric for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) { 14630b57cec5SDimitry Andric OffsetOfNode ON = Node->getComponent(i); 14640b57cec5SDimitry Andric if (ON.getKind() == OffsetOfNode::Array) { 14650b57cec5SDimitry Andric // Array node 14660b57cec5SDimitry Andric OS << "["; 14670b57cec5SDimitry Andric PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex())); 14680b57cec5SDimitry Andric OS << "]"; 14690b57cec5SDimitry Andric PrintedSomething = true; 14700b57cec5SDimitry Andric continue; 14710b57cec5SDimitry Andric } 14720b57cec5SDimitry Andric 14730b57cec5SDimitry Andric // Skip implicit base indirections. 14740b57cec5SDimitry Andric if (ON.getKind() == OffsetOfNode::Base) 14750b57cec5SDimitry Andric continue; 14760b57cec5SDimitry Andric 14770b57cec5SDimitry Andric // Field or identifier node. 1478*0fca6ea1SDimitry Andric const IdentifierInfo *Id = ON.getFieldName(); 14790b57cec5SDimitry Andric if (!Id) 14800b57cec5SDimitry Andric continue; 14810b57cec5SDimitry Andric 14820b57cec5SDimitry Andric if (PrintedSomething) 14830b57cec5SDimitry Andric OS << "."; 14840b57cec5SDimitry Andric else 14850b57cec5SDimitry Andric PrintedSomething = true; 14860b57cec5SDimitry Andric OS << Id->getName(); 14870b57cec5SDimitry Andric } 14880b57cec5SDimitry Andric OS << ")"; 14890b57cec5SDimitry Andric } 14900b57cec5SDimitry Andric 14915ffd83dbSDimitry Andric void StmtPrinter::VisitUnaryExprOrTypeTraitExpr( 14925ffd83dbSDimitry Andric UnaryExprOrTypeTraitExpr *Node) { 14935ffd83dbSDimitry Andric const char *Spelling = getTraitSpelling(Node->getKind()); 14945ffd83dbSDimitry Andric if (Node->getKind() == UETT_AlignOf) { 14950b57cec5SDimitry Andric if (Policy.Alignof) 14965ffd83dbSDimitry Andric Spelling = "alignof"; 14970b57cec5SDimitry Andric else if (Policy.UnderscoreAlignof) 14985ffd83dbSDimitry Andric Spelling = "_Alignof"; 14990b57cec5SDimitry Andric else 15005ffd83dbSDimitry Andric Spelling = "__alignof"; 15010b57cec5SDimitry Andric } 15025ffd83dbSDimitry Andric 15035ffd83dbSDimitry Andric OS << Spelling; 15045ffd83dbSDimitry Andric 15050b57cec5SDimitry Andric if (Node->isArgumentType()) { 15060b57cec5SDimitry Andric OS << '('; 15070b57cec5SDimitry Andric Node->getArgumentType().print(OS, Policy); 15080b57cec5SDimitry Andric OS << ')'; 15090b57cec5SDimitry Andric } else { 15100b57cec5SDimitry Andric OS << " "; 15110b57cec5SDimitry Andric PrintExpr(Node->getArgumentExpr()); 15120b57cec5SDimitry Andric } 15130b57cec5SDimitry Andric } 15140b57cec5SDimitry Andric 15150b57cec5SDimitry Andric void StmtPrinter::VisitGenericSelectionExpr(GenericSelectionExpr *Node) { 15160b57cec5SDimitry Andric OS << "_Generic("; 151706c3fb27SDimitry Andric if (Node->isExprPredicate()) 15180b57cec5SDimitry Andric PrintExpr(Node->getControllingExpr()); 151906c3fb27SDimitry Andric else 152006c3fb27SDimitry Andric Node->getControllingType()->getType().print(OS, Policy); 152106c3fb27SDimitry Andric 152206c3fb27SDimitry Andric for (const GenericSelectionExpr::Association &Assoc : Node->associations()) { 15230b57cec5SDimitry Andric OS << ", "; 15240b57cec5SDimitry Andric QualType T = Assoc.getType(); 15250b57cec5SDimitry Andric if (T.isNull()) 15260b57cec5SDimitry Andric OS << "default"; 15270b57cec5SDimitry Andric else 15280b57cec5SDimitry Andric T.print(OS, Policy); 15290b57cec5SDimitry Andric OS << ": "; 15300b57cec5SDimitry Andric PrintExpr(Assoc.getAssociationExpr()); 15310b57cec5SDimitry Andric } 15320b57cec5SDimitry Andric OS << ")"; 15330b57cec5SDimitry Andric } 15340b57cec5SDimitry Andric 15350b57cec5SDimitry Andric void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) { 15360b57cec5SDimitry Andric PrintExpr(Node->getLHS()); 15370b57cec5SDimitry Andric OS << "["; 15380b57cec5SDimitry Andric PrintExpr(Node->getRHS()); 15390b57cec5SDimitry Andric OS << "]"; 15400b57cec5SDimitry Andric } 15410b57cec5SDimitry Andric 15425ffd83dbSDimitry Andric void StmtPrinter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *Node) { 15435ffd83dbSDimitry Andric PrintExpr(Node->getBase()); 15445ffd83dbSDimitry Andric OS << "["; 15455ffd83dbSDimitry Andric PrintExpr(Node->getRowIdx()); 15465ffd83dbSDimitry Andric OS << "]"; 15475ffd83dbSDimitry Andric OS << "["; 15485ffd83dbSDimitry Andric PrintExpr(Node->getColumnIdx()); 15495ffd83dbSDimitry Andric OS << "]"; 15505ffd83dbSDimitry Andric } 15515ffd83dbSDimitry Andric 1552*0fca6ea1SDimitry Andric void StmtPrinter::VisitArraySectionExpr(ArraySectionExpr *Node) { 15530b57cec5SDimitry Andric PrintExpr(Node->getBase()); 15540b57cec5SDimitry Andric OS << "["; 15550b57cec5SDimitry Andric if (Node->getLowerBound()) 15560b57cec5SDimitry Andric PrintExpr(Node->getLowerBound()); 15575ffd83dbSDimitry Andric if (Node->getColonLocFirst().isValid()) { 15580b57cec5SDimitry Andric OS << ":"; 15590b57cec5SDimitry Andric if (Node->getLength()) 15600b57cec5SDimitry Andric PrintExpr(Node->getLength()); 15610b57cec5SDimitry Andric } 1562*0fca6ea1SDimitry Andric if (Node->isOMPArraySection() && Node->getColonLocSecond().isValid()) { 15635ffd83dbSDimitry Andric OS << ":"; 15645ffd83dbSDimitry Andric if (Node->getStride()) 15655ffd83dbSDimitry Andric PrintExpr(Node->getStride()); 15665ffd83dbSDimitry Andric } 15670b57cec5SDimitry Andric OS << "]"; 15680b57cec5SDimitry Andric } 15690b57cec5SDimitry Andric 15705ffd83dbSDimitry Andric void StmtPrinter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *Node) { 15715ffd83dbSDimitry Andric OS << "("; 15725ffd83dbSDimitry Andric for (Expr *E : Node->getDimensions()) { 15735ffd83dbSDimitry Andric OS << "["; 15745ffd83dbSDimitry Andric PrintExpr(E); 15755ffd83dbSDimitry Andric OS << "]"; 15765ffd83dbSDimitry Andric } 15775ffd83dbSDimitry Andric OS << ")"; 15785ffd83dbSDimitry Andric PrintExpr(Node->getBase()); 15795ffd83dbSDimitry Andric } 15805ffd83dbSDimitry Andric 15815ffd83dbSDimitry Andric void StmtPrinter::VisitOMPIteratorExpr(OMPIteratorExpr *Node) { 15825ffd83dbSDimitry Andric OS << "iterator("; 15835ffd83dbSDimitry Andric for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) { 15845ffd83dbSDimitry Andric auto *VD = cast<ValueDecl>(Node->getIteratorDecl(I)); 15855ffd83dbSDimitry Andric VD->getType().print(OS, Policy); 15865ffd83dbSDimitry Andric const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I); 15875ffd83dbSDimitry Andric OS << " " << VD->getName() << " = "; 15885ffd83dbSDimitry Andric PrintExpr(Range.Begin); 15895ffd83dbSDimitry Andric OS << ":"; 15905ffd83dbSDimitry Andric PrintExpr(Range.End); 15915ffd83dbSDimitry Andric if (Range.Step) { 15925ffd83dbSDimitry Andric OS << ":"; 15935ffd83dbSDimitry Andric PrintExpr(Range.Step); 15945ffd83dbSDimitry Andric } 15955ffd83dbSDimitry Andric if (I < E - 1) 15965ffd83dbSDimitry Andric OS << ", "; 15975ffd83dbSDimitry Andric } 15985ffd83dbSDimitry Andric OS << ")"; 15995ffd83dbSDimitry Andric } 16005ffd83dbSDimitry Andric 16010b57cec5SDimitry Andric void StmtPrinter::PrintCallArgs(CallExpr *Call) { 16020b57cec5SDimitry Andric for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) { 16030b57cec5SDimitry Andric if (isa<CXXDefaultArgExpr>(Call->getArg(i))) { 16040b57cec5SDimitry Andric // Don't print any defaulted arguments 16050b57cec5SDimitry Andric break; 16060b57cec5SDimitry Andric } 16070b57cec5SDimitry Andric 16080b57cec5SDimitry Andric if (i) OS << ", "; 16090b57cec5SDimitry Andric PrintExpr(Call->getArg(i)); 16100b57cec5SDimitry Andric } 16110b57cec5SDimitry Andric } 16120b57cec5SDimitry Andric 16130b57cec5SDimitry Andric void StmtPrinter::VisitCallExpr(CallExpr *Call) { 16140b57cec5SDimitry Andric PrintExpr(Call->getCallee()); 16150b57cec5SDimitry Andric OS << "("; 16160b57cec5SDimitry Andric PrintCallArgs(Call); 16170b57cec5SDimitry Andric OS << ")"; 16180b57cec5SDimitry Andric } 16190b57cec5SDimitry Andric 16200b57cec5SDimitry Andric static bool isImplicitThis(const Expr *E) { 16210b57cec5SDimitry Andric if (const auto *TE = dyn_cast<CXXThisExpr>(E)) 16220b57cec5SDimitry Andric return TE->isImplicit(); 16230b57cec5SDimitry Andric return false; 16240b57cec5SDimitry Andric } 16250b57cec5SDimitry Andric 16260b57cec5SDimitry Andric void StmtPrinter::VisitMemberExpr(MemberExpr *Node) { 16270b57cec5SDimitry Andric if (!Policy.SuppressImplicitBase || !isImplicitThis(Node->getBase())) { 16280b57cec5SDimitry Andric PrintExpr(Node->getBase()); 16290b57cec5SDimitry Andric 16300b57cec5SDimitry Andric auto *ParentMember = dyn_cast<MemberExpr>(Node->getBase()); 16310b57cec5SDimitry Andric FieldDecl *ParentDecl = 16320b57cec5SDimitry Andric ParentMember ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl()) 16330b57cec5SDimitry Andric : nullptr; 16340b57cec5SDimitry Andric 16350b57cec5SDimitry Andric if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion()) 16360b57cec5SDimitry Andric OS << (Node->isArrow() ? "->" : "."); 16370b57cec5SDimitry Andric } 16380b57cec5SDimitry Andric 16390b57cec5SDimitry Andric if (auto *FD = dyn_cast<FieldDecl>(Node->getMemberDecl())) 16400b57cec5SDimitry Andric if (FD->isAnonymousStructOrUnion()) 16410b57cec5SDimitry Andric return; 16420b57cec5SDimitry Andric 16430b57cec5SDimitry Andric if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 16440b57cec5SDimitry Andric Qualifier->print(OS, Policy); 16450b57cec5SDimitry Andric if (Node->hasTemplateKeyword()) 16460b57cec5SDimitry Andric OS << "template "; 16470b57cec5SDimitry Andric OS << Node->getMemberNameInfo(); 1648fe6060f1SDimitry Andric const TemplateParameterList *TPL = nullptr; 1649fe6060f1SDimitry Andric if (auto *FD = dyn_cast<FunctionDecl>(Node->getMemberDecl())) { 1650fe6060f1SDimitry Andric if (!Node->hadMultipleCandidates()) 1651fe6060f1SDimitry Andric if (auto *FTD = FD->getPrimaryTemplate()) 1652fe6060f1SDimitry Andric TPL = FTD->getTemplateParameters(); 1653fe6060f1SDimitry Andric } else if (auto *VTSD = 1654fe6060f1SDimitry Andric dyn_cast<VarTemplateSpecializationDecl>(Node->getMemberDecl())) 1655fe6060f1SDimitry Andric TPL = VTSD->getSpecializedTemplate()->getTemplateParameters(); 16560b57cec5SDimitry Andric if (Node->hasExplicitTemplateArgs()) 1657fe6060f1SDimitry Andric printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL); 16580b57cec5SDimitry Andric } 16590b57cec5SDimitry Andric 16600b57cec5SDimitry Andric void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) { 16610b57cec5SDimitry Andric PrintExpr(Node->getBase()); 16620b57cec5SDimitry Andric OS << (Node->isArrow() ? "->isa" : ".isa"); 16630b57cec5SDimitry Andric } 16640b57cec5SDimitry Andric 16650b57cec5SDimitry Andric void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) { 16660b57cec5SDimitry Andric PrintExpr(Node->getBase()); 16670b57cec5SDimitry Andric OS << "."; 16680b57cec5SDimitry Andric OS << Node->getAccessor().getName(); 16690b57cec5SDimitry Andric } 16700b57cec5SDimitry Andric 16710b57cec5SDimitry Andric void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) { 16720b57cec5SDimitry Andric OS << '('; 16730b57cec5SDimitry Andric Node->getTypeAsWritten().print(OS, Policy); 16740b57cec5SDimitry Andric OS << ')'; 16750b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 16760b57cec5SDimitry Andric } 16770b57cec5SDimitry Andric 16780b57cec5SDimitry Andric void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) { 16790b57cec5SDimitry Andric OS << '('; 16800b57cec5SDimitry Andric Node->getType().print(OS, Policy); 16810b57cec5SDimitry Andric OS << ')'; 16820b57cec5SDimitry Andric PrintExpr(Node->getInitializer()); 16830b57cec5SDimitry Andric } 16840b57cec5SDimitry Andric 16850b57cec5SDimitry Andric void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) { 16860b57cec5SDimitry Andric // No need to print anything, simply forward to the subexpression. 16870b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 16880b57cec5SDimitry Andric } 16890b57cec5SDimitry Andric 16900b57cec5SDimitry Andric void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) { 16910b57cec5SDimitry Andric PrintExpr(Node->getLHS()); 16920b57cec5SDimitry Andric OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 16930b57cec5SDimitry Andric PrintExpr(Node->getRHS()); 16940b57cec5SDimitry Andric } 16950b57cec5SDimitry Andric 16960b57cec5SDimitry Andric void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) { 16970b57cec5SDimitry Andric PrintExpr(Node->getLHS()); 16980b57cec5SDimitry Andric OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 16990b57cec5SDimitry Andric PrintExpr(Node->getRHS()); 17000b57cec5SDimitry Andric } 17010b57cec5SDimitry Andric 17020b57cec5SDimitry Andric void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) { 17030b57cec5SDimitry Andric PrintExpr(Node->getCond()); 17040b57cec5SDimitry Andric OS << " ? "; 17050b57cec5SDimitry Andric PrintExpr(Node->getLHS()); 17060b57cec5SDimitry Andric OS << " : "; 17070b57cec5SDimitry Andric PrintExpr(Node->getRHS()); 17080b57cec5SDimitry Andric } 17090b57cec5SDimitry Andric 17100b57cec5SDimitry Andric // GNU extensions. 17110b57cec5SDimitry Andric 17120b57cec5SDimitry Andric void 17130b57cec5SDimitry Andric StmtPrinter::VisitBinaryConditionalOperator(BinaryConditionalOperator *Node) { 17140b57cec5SDimitry Andric PrintExpr(Node->getCommon()); 17150b57cec5SDimitry Andric OS << " ?: "; 17160b57cec5SDimitry Andric PrintExpr(Node->getFalseExpr()); 17170b57cec5SDimitry Andric } 17180b57cec5SDimitry Andric 17190b57cec5SDimitry Andric void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) { 17200b57cec5SDimitry Andric OS << "&&" << Node->getLabel()->getName(); 17210b57cec5SDimitry Andric } 17220b57cec5SDimitry Andric 17230b57cec5SDimitry Andric void StmtPrinter::VisitStmtExpr(StmtExpr *E) { 17240b57cec5SDimitry Andric OS << "("; 17250b57cec5SDimitry Andric PrintRawCompoundStmt(E->getSubStmt()); 17260b57cec5SDimitry Andric OS << ")"; 17270b57cec5SDimitry Andric } 17280b57cec5SDimitry Andric 17290b57cec5SDimitry Andric void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) { 17300b57cec5SDimitry Andric OS << "__builtin_choose_expr("; 17310b57cec5SDimitry Andric PrintExpr(Node->getCond()); 17320b57cec5SDimitry Andric OS << ", "; 17330b57cec5SDimitry Andric PrintExpr(Node->getLHS()); 17340b57cec5SDimitry Andric OS << ", "; 17350b57cec5SDimitry Andric PrintExpr(Node->getRHS()); 17360b57cec5SDimitry Andric OS << ")"; 17370b57cec5SDimitry Andric } 17380b57cec5SDimitry Andric 17390b57cec5SDimitry Andric void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) { 17400b57cec5SDimitry Andric OS << "__null"; 17410b57cec5SDimitry Andric } 17420b57cec5SDimitry Andric 17430b57cec5SDimitry Andric void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) { 17440b57cec5SDimitry Andric OS << "__builtin_shufflevector("; 17450b57cec5SDimitry Andric for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) { 17460b57cec5SDimitry Andric if (i) OS << ", "; 17470b57cec5SDimitry Andric PrintExpr(Node->getExpr(i)); 17480b57cec5SDimitry Andric } 17490b57cec5SDimitry Andric OS << ")"; 17500b57cec5SDimitry Andric } 17510b57cec5SDimitry Andric 17520b57cec5SDimitry Andric void StmtPrinter::VisitConvertVectorExpr(ConvertVectorExpr *Node) { 17530b57cec5SDimitry Andric OS << "__builtin_convertvector("; 17540b57cec5SDimitry Andric PrintExpr(Node->getSrcExpr()); 17550b57cec5SDimitry Andric OS << ", "; 17560b57cec5SDimitry Andric Node->getType().print(OS, Policy); 17570b57cec5SDimitry Andric OS << ")"; 17580b57cec5SDimitry Andric } 17590b57cec5SDimitry Andric 17600b57cec5SDimitry Andric void StmtPrinter::VisitInitListExpr(InitListExpr* Node) { 17610b57cec5SDimitry Andric if (Node->getSyntacticForm()) { 17620b57cec5SDimitry Andric Visit(Node->getSyntacticForm()); 17630b57cec5SDimitry Andric return; 17640b57cec5SDimitry Andric } 17650b57cec5SDimitry Andric 17660b57cec5SDimitry Andric OS << "{"; 17670b57cec5SDimitry Andric for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) { 17680b57cec5SDimitry Andric if (i) OS << ", "; 17690b57cec5SDimitry Andric if (Node->getInit(i)) 17700b57cec5SDimitry Andric PrintExpr(Node->getInit(i)); 17710b57cec5SDimitry Andric else 17720b57cec5SDimitry Andric OS << "{}"; 17730b57cec5SDimitry Andric } 17740b57cec5SDimitry Andric OS << "}"; 17750b57cec5SDimitry Andric } 17760b57cec5SDimitry Andric 17770b57cec5SDimitry Andric void StmtPrinter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *Node) { 17780b57cec5SDimitry Andric // There's no way to express this expression in any of our supported 17790b57cec5SDimitry Andric // languages, so just emit something terse and (hopefully) clear. 17800b57cec5SDimitry Andric OS << "{"; 17810b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 17820b57cec5SDimitry Andric OS << "}"; 17830b57cec5SDimitry Andric } 17840b57cec5SDimitry Andric 17850b57cec5SDimitry Andric void StmtPrinter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *Node) { 17860b57cec5SDimitry Andric OS << "*"; 17870b57cec5SDimitry Andric } 17880b57cec5SDimitry Andric 17890b57cec5SDimitry Andric void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) { 17900b57cec5SDimitry Andric OS << "("; 17910b57cec5SDimitry Andric for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) { 17920b57cec5SDimitry Andric if (i) OS << ", "; 17930b57cec5SDimitry Andric PrintExpr(Node->getExpr(i)); 17940b57cec5SDimitry Andric } 17950b57cec5SDimitry Andric OS << ")"; 17960b57cec5SDimitry Andric } 17970b57cec5SDimitry Andric 17980b57cec5SDimitry Andric void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) { 17990b57cec5SDimitry Andric bool NeedsEquals = true; 18000b57cec5SDimitry Andric for (const DesignatedInitExpr::Designator &D : Node->designators()) { 18010b57cec5SDimitry Andric if (D.isFieldDesignator()) { 18020b57cec5SDimitry Andric if (D.getDotLoc().isInvalid()) { 180306c3fb27SDimitry Andric if (const IdentifierInfo *II = D.getFieldName()) { 18040b57cec5SDimitry Andric OS << II->getName() << ":"; 18050b57cec5SDimitry Andric NeedsEquals = false; 18060b57cec5SDimitry Andric } 18070b57cec5SDimitry Andric } else { 18080b57cec5SDimitry Andric OS << "." << D.getFieldName()->getName(); 18090b57cec5SDimitry Andric } 18100b57cec5SDimitry Andric } else { 18110b57cec5SDimitry Andric OS << "["; 18120b57cec5SDimitry Andric if (D.isArrayDesignator()) { 18130b57cec5SDimitry Andric PrintExpr(Node->getArrayIndex(D)); 18140b57cec5SDimitry Andric } else { 18150b57cec5SDimitry Andric PrintExpr(Node->getArrayRangeStart(D)); 18160b57cec5SDimitry Andric OS << " ... "; 18170b57cec5SDimitry Andric PrintExpr(Node->getArrayRangeEnd(D)); 18180b57cec5SDimitry Andric } 18190b57cec5SDimitry Andric OS << "]"; 18200b57cec5SDimitry Andric } 18210b57cec5SDimitry Andric } 18220b57cec5SDimitry Andric 18230b57cec5SDimitry Andric if (NeedsEquals) 18240b57cec5SDimitry Andric OS << " = "; 18250b57cec5SDimitry Andric else 18260b57cec5SDimitry Andric OS << " "; 18270b57cec5SDimitry Andric PrintExpr(Node->getInit()); 18280b57cec5SDimitry Andric } 18290b57cec5SDimitry Andric 18300b57cec5SDimitry Andric void StmtPrinter::VisitDesignatedInitUpdateExpr( 18310b57cec5SDimitry Andric DesignatedInitUpdateExpr *Node) { 18320b57cec5SDimitry Andric OS << "{"; 18330b57cec5SDimitry Andric OS << "/*base*/"; 18340b57cec5SDimitry Andric PrintExpr(Node->getBase()); 18350b57cec5SDimitry Andric OS << ", "; 18360b57cec5SDimitry Andric 18370b57cec5SDimitry Andric OS << "/*updater*/"; 18380b57cec5SDimitry Andric PrintExpr(Node->getUpdater()); 18390b57cec5SDimitry Andric OS << "}"; 18400b57cec5SDimitry Andric } 18410b57cec5SDimitry Andric 18420b57cec5SDimitry Andric void StmtPrinter::VisitNoInitExpr(NoInitExpr *Node) { 18430b57cec5SDimitry Andric OS << "/*no init*/"; 18440b57cec5SDimitry Andric } 18450b57cec5SDimitry Andric 18460b57cec5SDimitry Andric void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) { 18470b57cec5SDimitry Andric if (Node->getType()->getAsCXXRecordDecl()) { 18480b57cec5SDimitry Andric OS << "/*implicit*/"; 18490b57cec5SDimitry Andric Node->getType().print(OS, Policy); 18500b57cec5SDimitry Andric OS << "()"; 18510b57cec5SDimitry Andric } else { 18520b57cec5SDimitry Andric OS << "/*implicit*/("; 18530b57cec5SDimitry Andric Node->getType().print(OS, Policy); 18540b57cec5SDimitry Andric OS << ')'; 18550b57cec5SDimitry Andric if (Node->getType()->isRecordType()) 18560b57cec5SDimitry Andric OS << "{}"; 18570b57cec5SDimitry Andric else 18580b57cec5SDimitry Andric OS << 0; 18590b57cec5SDimitry Andric } 18600b57cec5SDimitry Andric } 18610b57cec5SDimitry Andric 18620b57cec5SDimitry Andric void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) { 18630b57cec5SDimitry Andric OS << "__builtin_va_arg("; 18640b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 18650b57cec5SDimitry Andric OS << ", "; 18660b57cec5SDimitry Andric Node->getType().print(OS, Policy); 18670b57cec5SDimitry Andric OS << ")"; 18680b57cec5SDimitry Andric } 18690b57cec5SDimitry Andric 18700b57cec5SDimitry Andric void StmtPrinter::VisitPseudoObjectExpr(PseudoObjectExpr *Node) { 18710b57cec5SDimitry Andric PrintExpr(Node->getSyntacticForm()); 18720b57cec5SDimitry Andric } 18730b57cec5SDimitry Andric 18740b57cec5SDimitry Andric void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) { 18750b57cec5SDimitry Andric const char *Name = nullptr; 18760b57cec5SDimitry Andric switch (Node->getOp()) { 18770b57cec5SDimitry Andric #define BUILTIN(ID, TYPE, ATTRS) 18780b57cec5SDimitry Andric #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \ 18790b57cec5SDimitry Andric case AtomicExpr::AO ## ID: \ 18800b57cec5SDimitry Andric Name = #ID "("; \ 18810b57cec5SDimitry Andric break; 1882*0fca6ea1SDimitry Andric #include "clang/Basic/Builtins.inc" 18830b57cec5SDimitry Andric } 18840b57cec5SDimitry Andric OS << Name; 18850b57cec5SDimitry Andric 18860b57cec5SDimitry Andric // AtomicExpr stores its subexpressions in a permuted order. 18870b57cec5SDimitry Andric PrintExpr(Node->getPtr()); 18880b57cec5SDimitry Andric if (Node->getOp() != AtomicExpr::AO__c11_atomic_load && 18890b57cec5SDimitry Andric Node->getOp() != AtomicExpr::AO__atomic_load_n && 18905f757f3fSDimitry Andric Node->getOp() != AtomicExpr::AO__scoped_atomic_load_n && 18914824e7fdSDimitry Andric Node->getOp() != AtomicExpr::AO__opencl_atomic_load && 18924824e7fdSDimitry Andric Node->getOp() != AtomicExpr::AO__hip_atomic_load) { 18930b57cec5SDimitry Andric OS << ", "; 18940b57cec5SDimitry Andric PrintExpr(Node->getVal1()); 18950b57cec5SDimitry Andric } 18960b57cec5SDimitry Andric if (Node->getOp() == AtomicExpr::AO__atomic_exchange || 18970b57cec5SDimitry Andric Node->isCmpXChg()) { 18980b57cec5SDimitry Andric OS << ", "; 18990b57cec5SDimitry Andric PrintExpr(Node->getVal2()); 19000b57cec5SDimitry Andric } 19010b57cec5SDimitry Andric if (Node->getOp() == AtomicExpr::AO__atomic_compare_exchange || 19020b57cec5SDimitry Andric Node->getOp() == AtomicExpr::AO__atomic_compare_exchange_n) { 19030b57cec5SDimitry Andric OS << ", "; 19040b57cec5SDimitry Andric PrintExpr(Node->getWeak()); 19050b57cec5SDimitry Andric } 19060b57cec5SDimitry Andric if (Node->getOp() != AtomicExpr::AO__c11_atomic_init && 19070b57cec5SDimitry Andric Node->getOp() != AtomicExpr::AO__opencl_atomic_init) { 19080b57cec5SDimitry Andric OS << ", "; 19090b57cec5SDimitry Andric PrintExpr(Node->getOrder()); 19100b57cec5SDimitry Andric } 19110b57cec5SDimitry Andric if (Node->isCmpXChg()) { 19120b57cec5SDimitry Andric OS << ", "; 19130b57cec5SDimitry Andric PrintExpr(Node->getOrderFail()); 19140b57cec5SDimitry Andric } 19150b57cec5SDimitry Andric OS << ")"; 19160b57cec5SDimitry Andric } 19170b57cec5SDimitry Andric 19180b57cec5SDimitry Andric // C++ 19190b57cec5SDimitry Andric void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) { 19200b57cec5SDimitry Andric OverloadedOperatorKind Kind = Node->getOperator(); 19210b57cec5SDimitry Andric if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) { 19220b57cec5SDimitry Andric if (Node->getNumArgs() == 1) { 19230b57cec5SDimitry Andric OS << getOperatorSpelling(Kind) << ' '; 19240b57cec5SDimitry Andric PrintExpr(Node->getArg(0)); 19250b57cec5SDimitry Andric } else { 19260b57cec5SDimitry Andric PrintExpr(Node->getArg(0)); 19270b57cec5SDimitry Andric OS << ' ' << getOperatorSpelling(Kind); 19280b57cec5SDimitry Andric } 19290b57cec5SDimitry Andric } else if (Kind == OO_Arrow) { 19300b57cec5SDimitry Andric PrintExpr(Node->getArg(0)); 193181ad6265SDimitry Andric } else if (Kind == OO_Call || Kind == OO_Subscript) { 19320b57cec5SDimitry Andric PrintExpr(Node->getArg(0)); 193381ad6265SDimitry Andric OS << (Kind == OO_Call ? '(' : '['); 19340b57cec5SDimitry Andric for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) { 19350b57cec5SDimitry Andric if (ArgIdx > 1) 19360b57cec5SDimitry Andric OS << ", "; 19370b57cec5SDimitry Andric if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx))) 19380b57cec5SDimitry Andric PrintExpr(Node->getArg(ArgIdx)); 19390b57cec5SDimitry Andric } 194081ad6265SDimitry Andric OS << (Kind == OO_Call ? ')' : ']'); 19410b57cec5SDimitry Andric } else if (Node->getNumArgs() == 1) { 19420b57cec5SDimitry Andric OS << getOperatorSpelling(Kind) << ' '; 19430b57cec5SDimitry Andric PrintExpr(Node->getArg(0)); 19440b57cec5SDimitry Andric } else if (Node->getNumArgs() == 2) { 19450b57cec5SDimitry Andric PrintExpr(Node->getArg(0)); 19460b57cec5SDimitry Andric OS << ' ' << getOperatorSpelling(Kind) << ' '; 19470b57cec5SDimitry Andric PrintExpr(Node->getArg(1)); 19480b57cec5SDimitry Andric } else { 19490b57cec5SDimitry Andric llvm_unreachable("unknown overloaded operator"); 19500b57cec5SDimitry Andric } 19510b57cec5SDimitry Andric } 19520b57cec5SDimitry Andric 19530b57cec5SDimitry Andric void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) { 19540b57cec5SDimitry Andric // If we have a conversion operator call only print the argument. 19550b57cec5SDimitry Andric CXXMethodDecl *MD = Node->getMethodDecl(); 1956*0fca6ea1SDimitry Andric if (isa_and_nonnull<CXXConversionDecl>(MD)) { 19570b57cec5SDimitry Andric PrintExpr(Node->getImplicitObjectArgument()); 19580b57cec5SDimitry Andric return; 19590b57cec5SDimitry Andric } 19600b57cec5SDimitry Andric VisitCallExpr(cast<CallExpr>(Node)); 19610b57cec5SDimitry Andric } 19620b57cec5SDimitry Andric 19630b57cec5SDimitry Andric void StmtPrinter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *Node) { 19640b57cec5SDimitry Andric PrintExpr(Node->getCallee()); 19650b57cec5SDimitry Andric OS << "<<<"; 19660b57cec5SDimitry Andric PrintCallArgs(Node->getConfig()); 19670b57cec5SDimitry Andric OS << ">>>("; 19680b57cec5SDimitry Andric PrintCallArgs(Node); 19690b57cec5SDimitry Andric OS << ")"; 19700b57cec5SDimitry Andric } 19710b57cec5SDimitry Andric 1972a7dea167SDimitry Andric void StmtPrinter::VisitCXXRewrittenBinaryOperator( 1973a7dea167SDimitry Andric CXXRewrittenBinaryOperator *Node) { 1974a7dea167SDimitry Andric CXXRewrittenBinaryOperator::DecomposedForm Decomposed = 1975a7dea167SDimitry Andric Node->getDecomposedForm(); 1976a7dea167SDimitry Andric PrintExpr(const_cast<Expr*>(Decomposed.LHS)); 1977a7dea167SDimitry Andric OS << ' ' << BinaryOperator::getOpcodeStr(Decomposed.Opcode) << ' '; 1978a7dea167SDimitry Andric PrintExpr(const_cast<Expr*>(Decomposed.RHS)); 1979a7dea167SDimitry Andric } 1980a7dea167SDimitry Andric 19810b57cec5SDimitry Andric void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) { 19820b57cec5SDimitry Andric OS << Node->getCastName() << '<'; 19830b57cec5SDimitry Andric Node->getTypeAsWritten().print(OS, Policy); 19840b57cec5SDimitry Andric OS << ">("; 19850b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 19860b57cec5SDimitry Andric OS << ")"; 19870b57cec5SDimitry Andric } 19880b57cec5SDimitry Andric 19890b57cec5SDimitry Andric void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) { 19900b57cec5SDimitry Andric VisitCXXNamedCastExpr(Node); 19910b57cec5SDimitry Andric } 19920b57cec5SDimitry Andric 19930b57cec5SDimitry Andric void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) { 19940b57cec5SDimitry Andric VisitCXXNamedCastExpr(Node); 19950b57cec5SDimitry Andric } 19960b57cec5SDimitry Andric 19970b57cec5SDimitry Andric void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) { 19980b57cec5SDimitry Andric VisitCXXNamedCastExpr(Node); 19990b57cec5SDimitry Andric } 20000b57cec5SDimitry Andric 20010b57cec5SDimitry Andric void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) { 20020b57cec5SDimitry Andric VisitCXXNamedCastExpr(Node); 20030b57cec5SDimitry Andric } 20040b57cec5SDimitry Andric 20050b57cec5SDimitry Andric void StmtPrinter::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *Node) { 20060b57cec5SDimitry Andric OS << "__builtin_bit_cast("; 20070b57cec5SDimitry Andric Node->getTypeInfoAsWritten()->getType().print(OS, Policy); 20080b57cec5SDimitry Andric OS << ", "; 20090b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 20100b57cec5SDimitry Andric OS << ")"; 20110b57cec5SDimitry Andric } 20120b57cec5SDimitry Andric 20135ffd83dbSDimitry Andric void StmtPrinter::VisitCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *Node) { 20145ffd83dbSDimitry Andric VisitCXXNamedCastExpr(Node); 20155ffd83dbSDimitry Andric } 20165ffd83dbSDimitry Andric 20170b57cec5SDimitry Andric void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) { 20180b57cec5SDimitry Andric OS << "typeid("; 20190b57cec5SDimitry Andric if (Node->isTypeOperand()) { 20200b57cec5SDimitry Andric Node->getTypeOperandSourceInfo()->getType().print(OS, Policy); 20210b57cec5SDimitry Andric } else { 20220b57cec5SDimitry Andric PrintExpr(Node->getExprOperand()); 20230b57cec5SDimitry Andric } 20240b57cec5SDimitry Andric OS << ")"; 20250b57cec5SDimitry Andric } 20260b57cec5SDimitry Andric 20270b57cec5SDimitry Andric void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) { 20280b57cec5SDimitry Andric OS << "__uuidof("; 20290b57cec5SDimitry Andric if (Node->isTypeOperand()) { 20300b57cec5SDimitry Andric Node->getTypeOperandSourceInfo()->getType().print(OS, Policy); 20310b57cec5SDimitry Andric } else { 20320b57cec5SDimitry Andric PrintExpr(Node->getExprOperand()); 20330b57cec5SDimitry Andric } 20340b57cec5SDimitry Andric OS << ")"; 20350b57cec5SDimitry Andric } 20360b57cec5SDimitry Andric 20370b57cec5SDimitry Andric void StmtPrinter::VisitMSPropertyRefExpr(MSPropertyRefExpr *Node) { 20380b57cec5SDimitry Andric PrintExpr(Node->getBaseExpr()); 20390b57cec5SDimitry Andric if (Node->isArrow()) 20400b57cec5SDimitry Andric OS << "->"; 20410b57cec5SDimitry Andric else 20420b57cec5SDimitry Andric OS << "."; 20430b57cec5SDimitry Andric if (NestedNameSpecifier *Qualifier = 20440b57cec5SDimitry Andric Node->getQualifierLoc().getNestedNameSpecifier()) 20450b57cec5SDimitry Andric Qualifier->print(OS, Policy); 20460b57cec5SDimitry Andric OS << Node->getPropertyDecl()->getDeclName(); 20470b57cec5SDimitry Andric } 20480b57cec5SDimitry Andric 20490b57cec5SDimitry Andric void StmtPrinter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *Node) { 20500b57cec5SDimitry Andric PrintExpr(Node->getBase()); 20510b57cec5SDimitry Andric OS << "["; 20520b57cec5SDimitry Andric PrintExpr(Node->getIdx()); 20530b57cec5SDimitry Andric OS << "]"; 20540b57cec5SDimitry Andric } 20550b57cec5SDimitry Andric 20560b57cec5SDimitry Andric void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) { 20570b57cec5SDimitry Andric switch (Node->getLiteralOperatorKind()) { 20580b57cec5SDimitry Andric case UserDefinedLiteral::LOK_Raw: 20590b57cec5SDimitry Andric OS << cast<StringLiteral>(Node->getArg(0)->IgnoreImpCasts())->getString(); 20600b57cec5SDimitry Andric break; 20610b57cec5SDimitry Andric case UserDefinedLiteral::LOK_Template: { 20620b57cec5SDimitry Andric const auto *DRE = cast<DeclRefExpr>(Node->getCallee()->IgnoreImpCasts()); 20630b57cec5SDimitry Andric const TemplateArgumentList *Args = 20640b57cec5SDimitry Andric cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs(); 20650b57cec5SDimitry Andric assert(Args); 20660b57cec5SDimitry Andric 20676246ae0bSDimitry Andric if (Args->size() != 1 || Args->get(0).getKind() != TemplateArgument::Pack) { 2068fe6060f1SDimitry Andric const TemplateParameterList *TPL = nullptr; 2069fe6060f1SDimitry Andric if (!DRE->hadMultipleCandidates()) 2070fe6060f1SDimitry Andric if (const auto *TD = dyn_cast<TemplateDecl>(DRE->getDecl())) 2071fe6060f1SDimitry Andric TPL = TD->getTemplateParameters(); 20720b57cec5SDimitry Andric OS << "operator\"\"" << Node->getUDSuffix()->getName(); 2073fe6060f1SDimitry Andric printTemplateArgumentList(OS, Args->asArray(), Policy, TPL); 20740b57cec5SDimitry Andric OS << "()"; 20750b57cec5SDimitry Andric return; 20760b57cec5SDimitry Andric } 20770b57cec5SDimitry Andric 20780b57cec5SDimitry Andric const TemplateArgument &Pack = Args->get(0); 20790b57cec5SDimitry Andric for (const auto &P : Pack.pack_elements()) { 20800b57cec5SDimitry Andric char C = (char)P.getAsIntegral().getZExtValue(); 20810b57cec5SDimitry Andric OS << C; 20820b57cec5SDimitry Andric } 20830b57cec5SDimitry Andric break; 20840b57cec5SDimitry Andric } 20850b57cec5SDimitry Andric case UserDefinedLiteral::LOK_Integer: { 20860b57cec5SDimitry Andric // Print integer literal without suffix. 20870b57cec5SDimitry Andric const auto *Int = cast<IntegerLiteral>(Node->getCookedLiteral()); 2088fe6060f1SDimitry Andric OS << toString(Int->getValue(), 10, /*isSigned*/false); 20890b57cec5SDimitry Andric break; 20900b57cec5SDimitry Andric } 20910b57cec5SDimitry Andric case UserDefinedLiteral::LOK_Floating: { 20920b57cec5SDimitry Andric // Print floating literal without suffix. 20930b57cec5SDimitry Andric auto *Float = cast<FloatingLiteral>(Node->getCookedLiteral()); 20940b57cec5SDimitry Andric PrintFloatingLiteral(OS, Float, /*PrintSuffix=*/false); 20950b57cec5SDimitry Andric break; 20960b57cec5SDimitry Andric } 20970b57cec5SDimitry Andric case UserDefinedLiteral::LOK_String: 20980b57cec5SDimitry Andric case UserDefinedLiteral::LOK_Character: 20990b57cec5SDimitry Andric PrintExpr(Node->getCookedLiteral()); 21000b57cec5SDimitry Andric break; 21010b57cec5SDimitry Andric } 21020b57cec5SDimitry Andric OS << Node->getUDSuffix()->getName(); 21030b57cec5SDimitry Andric } 21040b57cec5SDimitry Andric 21050b57cec5SDimitry Andric void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) { 21060b57cec5SDimitry Andric OS << (Node->getValue() ? "true" : "false"); 21070b57cec5SDimitry Andric } 21080b57cec5SDimitry Andric 21090b57cec5SDimitry Andric void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) { 21100b57cec5SDimitry Andric OS << "nullptr"; 21110b57cec5SDimitry Andric } 21120b57cec5SDimitry Andric 21130b57cec5SDimitry Andric void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) { 21140b57cec5SDimitry Andric OS << "this"; 21150b57cec5SDimitry Andric } 21160b57cec5SDimitry Andric 21170b57cec5SDimitry Andric void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) { 21180b57cec5SDimitry Andric if (!Node->getSubExpr()) 21190b57cec5SDimitry Andric OS << "throw"; 21200b57cec5SDimitry Andric else { 21210b57cec5SDimitry Andric OS << "throw "; 21220b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 21230b57cec5SDimitry Andric } 21240b57cec5SDimitry Andric } 21250b57cec5SDimitry Andric 21260b57cec5SDimitry Andric void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) { 21270b57cec5SDimitry Andric // Nothing to print: we picked up the default argument. 21280b57cec5SDimitry Andric } 21290b57cec5SDimitry Andric 21300b57cec5SDimitry Andric void StmtPrinter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Node) { 21310b57cec5SDimitry Andric // Nothing to print: we picked up the default initializer. 21320b57cec5SDimitry Andric } 21330b57cec5SDimitry Andric 21340b57cec5SDimitry Andric void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) { 213581ad6265SDimitry Andric auto TargetType = Node->getType(); 213681ad6265SDimitry Andric auto *Auto = TargetType->getContainedDeducedType(); 213781ad6265SDimitry Andric bool Bare = Auto && Auto->isDeduced(); 213881ad6265SDimitry Andric 213981ad6265SDimitry Andric // Parenthesize deduced casts. 214081ad6265SDimitry Andric if (Bare) 214181ad6265SDimitry Andric OS << '('; 214281ad6265SDimitry Andric TargetType.print(OS, Policy); 214381ad6265SDimitry Andric if (Bare) 214481ad6265SDimitry Andric OS << ')'; 214581ad6265SDimitry Andric 214681ad6265SDimitry Andric // No extra braces surrounding the inner construct. 214781ad6265SDimitry Andric if (!Node->isListInitialization()) 214881ad6265SDimitry Andric OS << '('; 21490b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 215081ad6265SDimitry Andric if (!Node->isListInitialization()) 215181ad6265SDimitry Andric OS << ')'; 21520b57cec5SDimitry Andric } 21530b57cec5SDimitry Andric 21540b57cec5SDimitry Andric void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) { 21550b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 21560b57cec5SDimitry Andric } 21570b57cec5SDimitry Andric 21580b57cec5SDimitry Andric void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) { 21590b57cec5SDimitry Andric Node->getType().print(OS, Policy); 21600b57cec5SDimitry Andric if (Node->isStdInitListInitialization()) 21610b57cec5SDimitry Andric /* Nothing to do; braces are part of creating the std::initializer_list. */; 21620b57cec5SDimitry Andric else if (Node->isListInitialization()) 21630b57cec5SDimitry Andric OS << "{"; 21640b57cec5SDimitry Andric else 21650b57cec5SDimitry Andric OS << "("; 21660b57cec5SDimitry Andric for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(), 21670b57cec5SDimitry Andric ArgEnd = Node->arg_end(); 21680b57cec5SDimitry Andric Arg != ArgEnd; ++Arg) { 21690b57cec5SDimitry Andric if ((*Arg)->isDefaultArgument()) 21700b57cec5SDimitry Andric break; 21710b57cec5SDimitry Andric if (Arg != Node->arg_begin()) 21720b57cec5SDimitry Andric OS << ", "; 21730b57cec5SDimitry Andric PrintExpr(*Arg); 21740b57cec5SDimitry Andric } 21750b57cec5SDimitry Andric if (Node->isStdInitListInitialization()) 21760b57cec5SDimitry Andric /* See above. */; 21770b57cec5SDimitry Andric else if (Node->isListInitialization()) 21780b57cec5SDimitry Andric OS << "}"; 21790b57cec5SDimitry Andric else 21800b57cec5SDimitry Andric OS << ")"; 21810b57cec5SDimitry Andric } 21820b57cec5SDimitry Andric 21830b57cec5SDimitry Andric void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) { 21840b57cec5SDimitry Andric OS << '['; 21850b57cec5SDimitry Andric bool NeedComma = false; 21860b57cec5SDimitry Andric switch (Node->getCaptureDefault()) { 21870b57cec5SDimitry Andric case LCD_None: 21880b57cec5SDimitry Andric break; 21890b57cec5SDimitry Andric 21900b57cec5SDimitry Andric case LCD_ByCopy: 21910b57cec5SDimitry Andric OS << '='; 21920b57cec5SDimitry Andric NeedComma = true; 21930b57cec5SDimitry Andric break; 21940b57cec5SDimitry Andric 21950b57cec5SDimitry Andric case LCD_ByRef: 21960b57cec5SDimitry Andric OS << '&'; 21970b57cec5SDimitry Andric NeedComma = true; 21980b57cec5SDimitry Andric break; 21990b57cec5SDimitry Andric } 22000b57cec5SDimitry Andric for (LambdaExpr::capture_iterator C = Node->explicit_capture_begin(), 22010b57cec5SDimitry Andric CEnd = Node->explicit_capture_end(); 22020b57cec5SDimitry Andric C != CEnd; 22030b57cec5SDimitry Andric ++C) { 22040b57cec5SDimitry Andric if (C->capturesVLAType()) 22050b57cec5SDimitry Andric continue; 22060b57cec5SDimitry Andric 22070b57cec5SDimitry Andric if (NeedComma) 22080b57cec5SDimitry Andric OS << ", "; 22090b57cec5SDimitry Andric NeedComma = true; 22100b57cec5SDimitry Andric 22110b57cec5SDimitry Andric switch (C->getCaptureKind()) { 22120b57cec5SDimitry Andric case LCK_This: 22130b57cec5SDimitry Andric OS << "this"; 22140b57cec5SDimitry Andric break; 22150b57cec5SDimitry Andric 22160b57cec5SDimitry Andric case LCK_StarThis: 22170b57cec5SDimitry Andric OS << "*this"; 22180b57cec5SDimitry Andric break; 22190b57cec5SDimitry Andric 22200b57cec5SDimitry Andric case LCK_ByRef: 22210b57cec5SDimitry Andric if (Node->getCaptureDefault() != LCD_ByRef || Node->isInitCapture(C)) 22220b57cec5SDimitry Andric OS << '&'; 22230b57cec5SDimitry Andric OS << C->getCapturedVar()->getName(); 22240b57cec5SDimitry Andric break; 22250b57cec5SDimitry Andric 22260b57cec5SDimitry Andric case LCK_ByCopy: 22270b57cec5SDimitry Andric OS << C->getCapturedVar()->getName(); 22280b57cec5SDimitry Andric break; 22290b57cec5SDimitry Andric 22300b57cec5SDimitry Andric case LCK_VLAType: 22310b57cec5SDimitry Andric llvm_unreachable("VLA type in explicit captures."); 22320b57cec5SDimitry Andric } 22330b57cec5SDimitry Andric 22340b57cec5SDimitry Andric if (C->isPackExpansion()) 22350b57cec5SDimitry Andric OS << "..."; 22360b57cec5SDimitry Andric 2237e8d8bef9SDimitry Andric if (Node->isInitCapture(C)) { 2238bdd1243dSDimitry Andric // Init captures are always VarDecl. 2239bdd1243dSDimitry Andric auto *D = cast<VarDecl>(C->getCapturedVar()); 2240e8d8bef9SDimitry Andric 2241e8d8bef9SDimitry Andric llvm::StringRef Pre; 2242e8d8bef9SDimitry Andric llvm::StringRef Post; 2243e8d8bef9SDimitry Andric if (D->getInitStyle() == VarDecl::CallInit && 2244e8d8bef9SDimitry Andric !isa<ParenListExpr>(D->getInit())) { 2245e8d8bef9SDimitry Andric Pre = "("; 2246e8d8bef9SDimitry Andric Post = ")"; 2247e8d8bef9SDimitry Andric } else if (D->getInitStyle() == VarDecl::CInit) { 2248e8d8bef9SDimitry Andric Pre = " = "; 2249e8d8bef9SDimitry Andric } 2250e8d8bef9SDimitry Andric 2251e8d8bef9SDimitry Andric OS << Pre; 2252e8d8bef9SDimitry Andric PrintExpr(D->getInit()); 2253e8d8bef9SDimitry Andric OS << Post; 2254e8d8bef9SDimitry Andric } 22550b57cec5SDimitry Andric } 22560b57cec5SDimitry Andric OS << ']'; 22570b57cec5SDimitry Andric 22580b57cec5SDimitry Andric if (!Node->getExplicitTemplateParameters().empty()) { 22590b57cec5SDimitry Andric Node->getTemplateParameterList()->print( 22600b57cec5SDimitry Andric OS, Node->getLambdaClass()->getASTContext(), 22610b57cec5SDimitry Andric /*OmitTemplateKW*/true); 22620b57cec5SDimitry Andric } 22630b57cec5SDimitry Andric 22640b57cec5SDimitry Andric if (Node->hasExplicitParameters()) { 22650b57cec5SDimitry Andric OS << '('; 22660b57cec5SDimitry Andric CXXMethodDecl *Method = Node->getCallOperator(); 22670b57cec5SDimitry Andric NeedComma = false; 22680b57cec5SDimitry Andric for (const auto *P : Method->parameters()) { 22690b57cec5SDimitry Andric if (NeedComma) { 22700b57cec5SDimitry Andric OS << ", "; 22710b57cec5SDimitry Andric } else { 22720b57cec5SDimitry Andric NeedComma = true; 22730b57cec5SDimitry Andric } 227404eeddc0SDimitry Andric std::string ParamStr = 227504eeddc0SDimitry Andric (Policy.CleanUglifiedParameters && P->getIdentifier()) 227604eeddc0SDimitry Andric ? P->getIdentifier()->deuglifiedName().str() 227704eeddc0SDimitry Andric : P->getNameAsString(); 22780b57cec5SDimitry Andric P->getOriginalType().print(OS, Policy, ParamStr); 22790b57cec5SDimitry Andric } 22800b57cec5SDimitry Andric if (Method->isVariadic()) { 22810b57cec5SDimitry Andric if (NeedComma) 22820b57cec5SDimitry Andric OS << ", "; 22830b57cec5SDimitry Andric OS << "..."; 22840b57cec5SDimitry Andric } 22850b57cec5SDimitry Andric OS << ')'; 22860b57cec5SDimitry Andric 22870b57cec5SDimitry Andric if (Node->isMutable()) 22880b57cec5SDimitry Andric OS << " mutable"; 22890b57cec5SDimitry Andric 2290a7dea167SDimitry Andric auto *Proto = Method->getType()->castAs<FunctionProtoType>(); 22910b57cec5SDimitry Andric Proto->printExceptionSpecification(OS, Policy); 22920b57cec5SDimitry Andric 22930b57cec5SDimitry Andric // FIXME: Attributes 22940b57cec5SDimitry Andric 22950b57cec5SDimitry Andric // Print the trailing return type if it was specified in the source. 22960b57cec5SDimitry Andric if (Node->hasExplicitResultType()) { 22970b57cec5SDimitry Andric OS << " -> "; 22980b57cec5SDimitry Andric Proto->getReturnType().print(OS, Policy); 22990b57cec5SDimitry Andric } 23000b57cec5SDimitry Andric } 23010b57cec5SDimitry Andric 23020b57cec5SDimitry Andric // Print the body. 23030b57cec5SDimitry Andric OS << ' '; 23040b57cec5SDimitry Andric if (Policy.TerseOutput) 23050b57cec5SDimitry Andric OS << "{}"; 23060b57cec5SDimitry Andric else 23075ffd83dbSDimitry Andric PrintRawCompoundStmt(Node->getCompoundStmtBody()); 23080b57cec5SDimitry Andric } 23090b57cec5SDimitry Andric 23100b57cec5SDimitry Andric void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) { 23110b57cec5SDimitry Andric if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo()) 23120b57cec5SDimitry Andric TSInfo->getType().print(OS, Policy); 23130b57cec5SDimitry Andric else 23140b57cec5SDimitry Andric Node->getType().print(OS, Policy); 23150b57cec5SDimitry Andric OS << "()"; 23160b57cec5SDimitry Andric } 23170b57cec5SDimitry Andric 23180b57cec5SDimitry Andric void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) { 23190b57cec5SDimitry Andric if (E->isGlobalNew()) 23200b57cec5SDimitry Andric OS << "::"; 23210b57cec5SDimitry Andric OS << "new "; 23220b57cec5SDimitry Andric unsigned NumPlace = E->getNumPlacementArgs(); 23230b57cec5SDimitry Andric if (NumPlace > 0 && !isa<CXXDefaultArgExpr>(E->getPlacementArg(0))) { 23240b57cec5SDimitry Andric OS << "("; 23250b57cec5SDimitry Andric PrintExpr(E->getPlacementArg(0)); 23260b57cec5SDimitry Andric for (unsigned i = 1; i < NumPlace; ++i) { 23270b57cec5SDimitry Andric if (isa<CXXDefaultArgExpr>(E->getPlacementArg(i))) 23280b57cec5SDimitry Andric break; 23290b57cec5SDimitry Andric OS << ", "; 23300b57cec5SDimitry Andric PrintExpr(E->getPlacementArg(i)); 23310b57cec5SDimitry Andric } 23320b57cec5SDimitry Andric OS << ") "; 23330b57cec5SDimitry Andric } 23340b57cec5SDimitry Andric if (E->isParenTypeId()) 23350b57cec5SDimitry Andric OS << "("; 23360b57cec5SDimitry Andric std::string TypeS; 233781ad6265SDimitry Andric if (E->isArray()) { 23380b57cec5SDimitry Andric llvm::raw_string_ostream s(TypeS); 23390b57cec5SDimitry Andric s << '['; 2340bdd1243dSDimitry Andric if (std::optional<Expr *> Size = E->getArraySize()) 23410b57cec5SDimitry Andric (*Size)->printPretty(s, Helper, Policy); 23420b57cec5SDimitry Andric s << ']'; 23430b57cec5SDimitry Andric } 23440b57cec5SDimitry Andric E->getAllocatedType().print(OS, Policy, TypeS); 23450b57cec5SDimitry Andric if (E->isParenTypeId()) 23460b57cec5SDimitry Andric OS << ")"; 23470b57cec5SDimitry Andric 23485f757f3fSDimitry Andric CXXNewInitializationStyle InitStyle = E->getInitializationStyle(); 23497a6dacacSDimitry Andric if (InitStyle != CXXNewInitializationStyle::None) { 23507a6dacacSDimitry Andric bool Bare = InitStyle == CXXNewInitializationStyle::Parens && 235181ad6265SDimitry Andric !isa<ParenListExpr>(E->getInitializer()); 235281ad6265SDimitry Andric if (Bare) 23530b57cec5SDimitry Andric OS << "("; 23540b57cec5SDimitry Andric PrintExpr(E->getInitializer()); 235581ad6265SDimitry Andric if (Bare) 23560b57cec5SDimitry Andric OS << ")"; 23570b57cec5SDimitry Andric } 23580b57cec5SDimitry Andric } 23590b57cec5SDimitry Andric 23600b57cec5SDimitry Andric void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) { 23610b57cec5SDimitry Andric if (E->isGlobalDelete()) 23620b57cec5SDimitry Andric OS << "::"; 23630b57cec5SDimitry Andric OS << "delete "; 23640b57cec5SDimitry Andric if (E->isArrayForm()) 23650b57cec5SDimitry Andric OS << "[] "; 23660b57cec5SDimitry Andric PrintExpr(E->getArgument()); 23670b57cec5SDimitry Andric } 23680b57cec5SDimitry Andric 23690b57cec5SDimitry Andric void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) { 23700b57cec5SDimitry Andric PrintExpr(E->getBase()); 23710b57cec5SDimitry Andric if (E->isArrow()) 23720b57cec5SDimitry Andric OS << "->"; 23730b57cec5SDimitry Andric else 23740b57cec5SDimitry Andric OS << '.'; 23750b57cec5SDimitry Andric if (E->getQualifier()) 23760b57cec5SDimitry Andric E->getQualifier()->print(OS, Policy); 23770b57cec5SDimitry Andric OS << "~"; 23780b57cec5SDimitry Andric 2379*0fca6ea1SDimitry Andric if (const IdentifierInfo *II = E->getDestroyedTypeIdentifier()) 23800b57cec5SDimitry Andric OS << II->getName(); 23810b57cec5SDimitry Andric else 23820b57cec5SDimitry Andric E->getDestroyedType().print(OS, Policy); 23830b57cec5SDimitry Andric } 23840b57cec5SDimitry Andric 23850b57cec5SDimitry Andric void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) { 23860b57cec5SDimitry Andric if (E->isListInitialization() && !E->isStdInitListInitialization()) 23870b57cec5SDimitry Andric OS << "{"; 23880b57cec5SDimitry Andric 23890b57cec5SDimitry Andric for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { 23900b57cec5SDimitry Andric if (isa<CXXDefaultArgExpr>(E->getArg(i))) { 23910b57cec5SDimitry Andric // Don't print any defaulted arguments 23920b57cec5SDimitry Andric break; 23930b57cec5SDimitry Andric } 23940b57cec5SDimitry Andric 23950b57cec5SDimitry Andric if (i) OS << ", "; 23960b57cec5SDimitry Andric PrintExpr(E->getArg(i)); 23970b57cec5SDimitry Andric } 23980b57cec5SDimitry Andric 23990b57cec5SDimitry Andric if (E->isListInitialization() && !E->isStdInitListInitialization()) 24000b57cec5SDimitry Andric OS << "}"; 24010b57cec5SDimitry Andric } 24020b57cec5SDimitry Andric 24030b57cec5SDimitry Andric void StmtPrinter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) { 24040b57cec5SDimitry Andric // Parens are printed by the surrounding context. 24050b57cec5SDimitry Andric OS << "<forwarded>"; 24060b57cec5SDimitry Andric } 24070b57cec5SDimitry Andric 24080b57cec5SDimitry Andric void StmtPrinter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) { 24090b57cec5SDimitry Andric PrintExpr(E->getSubExpr()); 24100b57cec5SDimitry Andric } 24110b57cec5SDimitry Andric 24120b57cec5SDimitry Andric void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) { 24130b57cec5SDimitry Andric // Just forward to the subexpression. 24140b57cec5SDimitry Andric PrintExpr(E->getSubExpr()); 24150b57cec5SDimitry Andric } 24160b57cec5SDimitry Andric 241781ad6265SDimitry Andric void StmtPrinter::VisitCXXUnresolvedConstructExpr( 24180b57cec5SDimitry Andric CXXUnresolvedConstructExpr *Node) { 24190b57cec5SDimitry Andric Node->getTypeAsWritten().print(OS, Policy); 242081ad6265SDimitry Andric if (!Node->isListInitialization()) 242181ad6265SDimitry Andric OS << '('; 242281ad6265SDimitry Andric for (auto Arg = Node->arg_begin(), ArgEnd = Node->arg_end(); Arg != ArgEnd; 242381ad6265SDimitry Andric ++Arg) { 24240b57cec5SDimitry Andric if (Arg != Node->arg_begin()) 24250b57cec5SDimitry Andric OS << ", "; 24260b57cec5SDimitry Andric PrintExpr(*Arg); 24270b57cec5SDimitry Andric } 242881ad6265SDimitry Andric if (!Node->isListInitialization()) 242981ad6265SDimitry Andric OS << ')'; 24300b57cec5SDimitry Andric } 24310b57cec5SDimitry Andric 24320b57cec5SDimitry Andric void StmtPrinter::VisitCXXDependentScopeMemberExpr( 24330b57cec5SDimitry Andric CXXDependentScopeMemberExpr *Node) { 24340b57cec5SDimitry Andric if (!Node->isImplicitAccess()) { 24350b57cec5SDimitry Andric PrintExpr(Node->getBase()); 24360b57cec5SDimitry Andric OS << (Node->isArrow() ? "->" : "."); 24370b57cec5SDimitry Andric } 24380b57cec5SDimitry Andric if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 24390b57cec5SDimitry Andric Qualifier->print(OS, Policy); 24400b57cec5SDimitry Andric if (Node->hasTemplateKeyword()) 24410b57cec5SDimitry Andric OS << "template "; 24420b57cec5SDimitry Andric OS << Node->getMemberNameInfo(); 24430b57cec5SDimitry Andric if (Node->hasExplicitTemplateArgs()) 24440b57cec5SDimitry Andric printTemplateArgumentList(OS, Node->template_arguments(), Policy); 24450b57cec5SDimitry Andric } 24460b57cec5SDimitry Andric 24470b57cec5SDimitry Andric void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) { 24480b57cec5SDimitry Andric if (!Node->isImplicitAccess()) { 24490b57cec5SDimitry Andric PrintExpr(Node->getBase()); 24500b57cec5SDimitry Andric OS << (Node->isArrow() ? "->" : "."); 24510b57cec5SDimitry Andric } 24520b57cec5SDimitry Andric if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 24530b57cec5SDimitry Andric Qualifier->print(OS, Policy); 24540b57cec5SDimitry Andric if (Node->hasTemplateKeyword()) 24550b57cec5SDimitry Andric OS << "template "; 24560b57cec5SDimitry Andric OS << Node->getMemberNameInfo(); 24570b57cec5SDimitry Andric if (Node->hasExplicitTemplateArgs()) 24580b57cec5SDimitry Andric printTemplateArgumentList(OS, Node->template_arguments(), Policy); 24590b57cec5SDimitry Andric } 24600b57cec5SDimitry Andric 24610b57cec5SDimitry Andric void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) { 24625ffd83dbSDimitry Andric OS << getTraitSpelling(E->getTrait()) << "("; 24630b57cec5SDimitry Andric for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) { 24640b57cec5SDimitry Andric if (I > 0) 24650b57cec5SDimitry Andric OS << ", "; 24660b57cec5SDimitry Andric E->getArg(I)->getType().print(OS, Policy); 24670b57cec5SDimitry Andric } 24680b57cec5SDimitry Andric OS << ")"; 24690b57cec5SDimitry Andric } 24700b57cec5SDimitry Andric 24710b57cec5SDimitry Andric void StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) { 24725ffd83dbSDimitry Andric OS << getTraitSpelling(E->getTrait()) << '('; 24730b57cec5SDimitry Andric E->getQueriedType().print(OS, Policy); 24740b57cec5SDimitry Andric OS << ')'; 24750b57cec5SDimitry Andric } 24760b57cec5SDimitry Andric 24770b57cec5SDimitry Andric void StmtPrinter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) { 24785ffd83dbSDimitry Andric OS << getTraitSpelling(E->getTrait()) << '('; 24790b57cec5SDimitry Andric PrintExpr(E->getQueriedExpression()); 24800b57cec5SDimitry Andric OS << ')'; 24810b57cec5SDimitry Andric } 24820b57cec5SDimitry Andric 24830b57cec5SDimitry Andric void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { 24840b57cec5SDimitry Andric OS << "noexcept("; 24850b57cec5SDimitry Andric PrintExpr(E->getOperand()); 24860b57cec5SDimitry Andric OS << ")"; 24870b57cec5SDimitry Andric } 24880b57cec5SDimitry Andric 24890b57cec5SDimitry Andric void StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) { 24900b57cec5SDimitry Andric PrintExpr(E->getPattern()); 24910b57cec5SDimitry Andric OS << "..."; 24920b57cec5SDimitry Andric } 24930b57cec5SDimitry Andric 24940b57cec5SDimitry Andric void StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) { 24950b57cec5SDimitry Andric OS << "sizeof...(" << *E->getPack() << ")"; 24960b57cec5SDimitry Andric } 24970b57cec5SDimitry Andric 2498*0fca6ea1SDimitry Andric void StmtPrinter::VisitPackIndexingExpr(PackIndexingExpr *E) { 2499*0fca6ea1SDimitry Andric OS << E->getPackIdExpression() << "...[" << E->getIndexExpr() << "]"; 2500*0fca6ea1SDimitry Andric } 2501*0fca6ea1SDimitry Andric 25020b57cec5SDimitry Andric void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr( 25030b57cec5SDimitry Andric SubstNonTypeTemplateParmPackExpr *Node) { 25040b57cec5SDimitry Andric OS << *Node->getParameterPack(); 25050b57cec5SDimitry Andric } 25060b57cec5SDimitry Andric 25070b57cec5SDimitry Andric void StmtPrinter::VisitSubstNonTypeTemplateParmExpr( 25080b57cec5SDimitry Andric SubstNonTypeTemplateParmExpr *Node) { 25090b57cec5SDimitry Andric Visit(Node->getReplacement()); 25100b57cec5SDimitry Andric } 25110b57cec5SDimitry Andric 25120b57cec5SDimitry Andric void StmtPrinter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) { 25130b57cec5SDimitry Andric OS << *E->getParameterPack(); 25140b57cec5SDimitry Andric } 25150b57cec5SDimitry Andric 25160b57cec5SDimitry Andric void StmtPrinter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *Node){ 2517480093f4SDimitry Andric PrintExpr(Node->getSubExpr()); 25180b57cec5SDimitry Andric } 25190b57cec5SDimitry Andric 25200b57cec5SDimitry Andric void StmtPrinter::VisitCXXFoldExpr(CXXFoldExpr *E) { 25210b57cec5SDimitry Andric OS << "("; 25220b57cec5SDimitry Andric if (E->getLHS()) { 25230b57cec5SDimitry Andric PrintExpr(E->getLHS()); 25240b57cec5SDimitry Andric OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " "; 25250b57cec5SDimitry Andric } 25260b57cec5SDimitry Andric OS << "..."; 25270b57cec5SDimitry Andric if (E->getRHS()) { 25280b57cec5SDimitry Andric OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " "; 25290b57cec5SDimitry Andric PrintExpr(E->getRHS()); 25300b57cec5SDimitry Andric } 25310b57cec5SDimitry Andric OS << ")"; 25320b57cec5SDimitry Andric } 25330b57cec5SDimitry Andric 2534bdd1243dSDimitry Andric void StmtPrinter::VisitCXXParenListInitExpr(CXXParenListInitExpr *Node) { 2535bdd1243dSDimitry Andric OS << "("; 2536bdd1243dSDimitry Andric llvm::interleaveComma(Node->getInitExprs(), OS, 2537bdd1243dSDimitry Andric [&](Expr *E) { PrintExpr(E); }); 2538bdd1243dSDimitry Andric OS << ")"; 2539bdd1243dSDimitry Andric } 2540bdd1243dSDimitry Andric 2541a7dea167SDimitry Andric void StmtPrinter::VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) { 2542a7dea167SDimitry Andric NestedNameSpecifierLoc NNS = E->getNestedNameSpecifierLoc(); 2543a7dea167SDimitry Andric if (NNS) 2544a7dea167SDimitry Andric NNS.getNestedNameSpecifier()->print(OS, Policy); 2545a7dea167SDimitry Andric if (E->getTemplateKWLoc().isValid()) 2546a7dea167SDimitry Andric OS << "template "; 2547a7dea167SDimitry Andric OS << E->getFoundDecl()->getName(); 2548a7dea167SDimitry Andric printTemplateArgumentList(OS, E->getTemplateArgsAsWritten()->arguments(), 2549fe6060f1SDimitry Andric Policy, 2550fe6060f1SDimitry Andric E->getNamedConcept()->getTemplateParameters()); 2551a7dea167SDimitry Andric } 2552a7dea167SDimitry Andric 255355e4f9d5SDimitry Andric void StmtPrinter::VisitRequiresExpr(RequiresExpr *E) { 255455e4f9d5SDimitry Andric OS << "requires "; 255555e4f9d5SDimitry Andric auto LocalParameters = E->getLocalParameters(); 255655e4f9d5SDimitry Andric if (!LocalParameters.empty()) { 255755e4f9d5SDimitry Andric OS << "("; 255855e4f9d5SDimitry Andric for (ParmVarDecl *LocalParam : LocalParameters) { 255955e4f9d5SDimitry Andric PrintRawDecl(LocalParam); 256055e4f9d5SDimitry Andric if (LocalParam != LocalParameters.back()) 256155e4f9d5SDimitry Andric OS << ", "; 256255e4f9d5SDimitry Andric } 256355e4f9d5SDimitry Andric 256455e4f9d5SDimitry Andric OS << ") "; 256555e4f9d5SDimitry Andric } 256655e4f9d5SDimitry Andric OS << "{ "; 256755e4f9d5SDimitry Andric auto Requirements = E->getRequirements(); 256855e4f9d5SDimitry Andric for (concepts::Requirement *Req : Requirements) { 256955e4f9d5SDimitry Andric if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) { 257055e4f9d5SDimitry Andric if (TypeReq->isSubstitutionFailure()) 257155e4f9d5SDimitry Andric OS << "<<error-type>>"; 257255e4f9d5SDimitry Andric else 257355e4f9d5SDimitry Andric TypeReq->getType()->getType().print(OS, Policy); 257455e4f9d5SDimitry Andric } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) { 257555e4f9d5SDimitry Andric if (ExprReq->isCompound()) 257655e4f9d5SDimitry Andric OS << "{ "; 257755e4f9d5SDimitry Andric if (ExprReq->isExprSubstitutionFailure()) 257855e4f9d5SDimitry Andric OS << "<<error-expression>>"; 257955e4f9d5SDimitry Andric else 258055e4f9d5SDimitry Andric PrintExpr(ExprReq->getExpr()); 258155e4f9d5SDimitry Andric if (ExprReq->isCompound()) { 258255e4f9d5SDimitry Andric OS << " }"; 258355e4f9d5SDimitry Andric if (ExprReq->getNoexceptLoc().isValid()) 258455e4f9d5SDimitry Andric OS << " noexcept"; 258555e4f9d5SDimitry Andric const auto &RetReq = ExprReq->getReturnTypeRequirement(); 258655e4f9d5SDimitry Andric if (!RetReq.isEmpty()) { 258755e4f9d5SDimitry Andric OS << " -> "; 258855e4f9d5SDimitry Andric if (RetReq.isSubstitutionFailure()) 258955e4f9d5SDimitry Andric OS << "<<error-type>>"; 259055e4f9d5SDimitry Andric else if (RetReq.isTypeConstraint()) 259155e4f9d5SDimitry Andric RetReq.getTypeConstraint()->print(OS, Policy); 259255e4f9d5SDimitry Andric } 259355e4f9d5SDimitry Andric } 259455e4f9d5SDimitry Andric } else { 259555e4f9d5SDimitry Andric auto *NestedReq = cast<concepts::NestedRequirement>(Req); 259655e4f9d5SDimitry Andric OS << "requires "; 2597bdd1243dSDimitry Andric if (NestedReq->hasInvalidConstraint()) 259855e4f9d5SDimitry Andric OS << "<<error-expression>>"; 259955e4f9d5SDimitry Andric else 260055e4f9d5SDimitry Andric PrintExpr(NestedReq->getConstraintExpr()); 260155e4f9d5SDimitry Andric } 260255e4f9d5SDimitry Andric OS << "; "; 260355e4f9d5SDimitry Andric } 260455e4f9d5SDimitry Andric OS << "}"; 260555e4f9d5SDimitry Andric } 260655e4f9d5SDimitry Andric 260706c3fb27SDimitry Andric // C++ Coroutines 26080b57cec5SDimitry Andric 26090b57cec5SDimitry Andric void StmtPrinter::VisitCoroutineBodyStmt(CoroutineBodyStmt *S) { 26100b57cec5SDimitry Andric Visit(S->getBody()); 26110b57cec5SDimitry Andric } 26120b57cec5SDimitry Andric 26130b57cec5SDimitry Andric void StmtPrinter::VisitCoreturnStmt(CoreturnStmt *S) { 26140b57cec5SDimitry Andric OS << "co_return"; 26150b57cec5SDimitry Andric if (S->getOperand()) { 26160b57cec5SDimitry Andric OS << " "; 26170b57cec5SDimitry Andric Visit(S->getOperand()); 26180b57cec5SDimitry Andric } 26190b57cec5SDimitry Andric OS << ";"; 26200b57cec5SDimitry Andric } 26210b57cec5SDimitry Andric 26220b57cec5SDimitry Andric void StmtPrinter::VisitCoawaitExpr(CoawaitExpr *S) { 26230b57cec5SDimitry Andric OS << "co_await "; 26240b57cec5SDimitry Andric PrintExpr(S->getOperand()); 26250b57cec5SDimitry Andric } 26260b57cec5SDimitry Andric 26270b57cec5SDimitry Andric void StmtPrinter::VisitDependentCoawaitExpr(DependentCoawaitExpr *S) { 26280b57cec5SDimitry Andric OS << "co_await "; 26290b57cec5SDimitry Andric PrintExpr(S->getOperand()); 26300b57cec5SDimitry Andric } 26310b57cec5SDimitry Andric 26320b57cec5SDimitry Andric void StmtPrinter::VisitCoyieldExpr(CoyieldExpr *S) { 26330b57cec5SDimitry Andric OS << "co_yield "; 26340b57cec5SDimitry Andric PrintExpr(S->getOperand()); 26350b57cec5SDimitry Andric } 26360b57cec5SDimitry Andric 26370b57cec5SDimitry Andric // Obj-C 26380b57cec5SDimitry Andric 26390b57cec5SDimitry Andric void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) { 26400b57cec5SDimitry Andric OS << "@"; 26410b57cec5SDimitry Andric VisitStringLiteral(Node->getString()); 26420b57cec5SDimitry Andric } 26430b57cec5SDimitry Andric 26440b57cec5SDimitry Andric void StmtPrinter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) { 26450b57cec5SDimitry Andric OS << "@"; 26460b57cec5SDimitry Andric Visit(E->getSubExpr()); 26470b57cec5SDimitry Andric } 26480b57cec5SDimitry Andric 26490b57cec5SDimitry Andric void StmtPrinter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) { 26500b57cec5SDimitry Andric OS << "@[ "; 26510b57cec5SDimitry Andric ObjCArrayLiteral::child_range Ch = E->children(); 26520b57cec5SDimitry Andric for (auto I = Ch.begin(), E = Ch.end(); I != E; ++I) { 26530b57cec5SDimitry Andric if (I != Ch.begin()) 26540b57cec5SDimitry Andric OS << ", "; 26550b57cec5SDimitry Andric Visit(*I); 26560b57cec5SDimitry Andric } 26570b57cec5SDimitry Andric OS << " ]"; 26580b57cec5SDimitry Andric } 26590b57cec5SDimitry Andric 26600b57cec5SDimitry Andric void StmtPrinter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) { 26610b57cec5SDimitry Andric OS << "@{ "; 26620b57cec5SDimitry Andric for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) { 26630b57cec5SDimitry Andric if (I > 0) 26640b57cec5SDimitry Andric OS << ", "; 26650b57cec5SDimitry Andric 26660b57cec5SDimitry Andric ObjCDictionaryElement Element = E->getKeyValueElement(I); 26670b57cec5SDimitry Andric Visit(Element.Key); 26680b57cec5SDimitry Andric OS << " : "; 26690b57cec5SDimitry Andric Visit(Element.Value); 26700b57cec5SDimitry Andric if (Element.isPackExpansion()) 26710b57cec5SDimitry Andric OS << "..."; 26720b57cec5SDimitry Andric } 26730b57cec5SDimitry Andric OS << " }"; 26740b57cec5SDimitry Andric } 26750b57cec5SDimitry Andric 26760b57cec5SDimitry Andric void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) { 26770b57cec5SDimitry Andric OS << "@encode("; 26780b57cec5SDimitry Andric Node->getEncodedType().print(OS, Policy); 26790b57cec5SDimitry Andric OS << ')'; 26800b57cec5SDimitry Andric } 26810b57cec5SDimitry Andric 26820b57cec5SDimitry Andric void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) { 26830b57cec5SDimitry Andric OS << "@selector("; 26840b57cec5SDimitry Andric Node->getSelector().print(OS); 26850b57cec5SDimitry Andric OS << ')'; 26860b57cec5SDimitry Andric } 26870b57cec5SDimitry Andric 26880b57cec5SDimitry Andric void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) { 26890b57cec5SDimitry Andric OS << "@protocol(" << *Node->getProtocol() << ')'; 26900b57cec5SDimitry Andric } 26910b57cec5SDimitry Andric 26920b57cec5SDimitry Andric void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) { 26930b57cec5SDimitry Andric OS << "["; 26940b57cec5SDimitry Andric switch (Mess->getReceiverKind()) { 26950b57cec5SDimitry Andric case ObjCMessageExpr::Instance: 26960b57cec5SDimitry Andric PrintExpr(Mess->getInstanceReceiver()); 26970b57cec5SDimitry Andric break; 26980b57cec5SDimitry Andric 26990b57cec5SDimitry Andric case ObjCMessageExpr::Class: 27000b57cec5SDimitry Andric Mess->getClassReceiver().print(OS, Policy); 27010b57cec5SDimitry Andric break; 27020b57cec5SDimitry Andric 27030b57cec5SDimitry Andric case ObjCMessageExpr::SuperInstance: 27040b57cec5SDimitry Andric case ObjCMessageExpr::SuperClass: 27050b57cec5SDimitry Andric OS << "Super"; 27060b57cec5SDimitry Andric break; 27070b57cec5SDimitry Andric } 27080b57cec5SDimitry Andric 27090b57cec5SDimitry Andric OS << ' '; 27100b57cec5SDimitry Andric Selector selector = Mess->getSelector(); 27110b57cec5SDimitry Andric if (selector.isUnarySelector()) { 27120b57cec5SDimitry Andric OS << selector.getNameForSlot(0); 27130b57cec5SDimitry Andric } else { 27140b57cec5SDimitry Andric for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) { 27150b57cec5SDimitry Andric if (i < selector.getNumArgs()) { 27160b57cec5SDimitry Andric if (i > 0) OS << ' '; 27170b57cec5SDimitry Andric if (selector.getIdentifierInfoForSlot(i)) 27180b57cec5SDimitry Andric OS << selector.getIdentifierInfoForSlot(i)->getName() << ':'; 27190b57cec5SDimitry Andric else 27200b57cec5SDimitry Andric OS << ":"; 27210b57cec5SDimitry Andric } 27220b57cec5SDimitry Andric else OS << ", "; // Handle variadic methods. 27230b57cec5SDimitry Andric 27240b57cec5SDimitry Andric PrintExpr(Mess->getArg(i)); 27250b57cec5SDimitry Andric } 27260b57cec5SDimitry Andric } 27270b57cec5SDimitry Andric OS << "]"; 27280b57cec5SDimitry Andric } 27290b57cec5SDimitry Andric 27300b57cec5SDimitry Andric void StmtPrinter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) { 27310b57cec5SDimitry Andric OS << (Node->getValue() ? "__objc_yes" : "__objc_no"); 27320b57cec5SDimitry Andric } 27330b57cec5SDimitry Andric 27340b57cec5SDimitry Andric void 27350b57cec5SDimitry Andric StmtPrinter::VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) { 27360b57cec5SDimitry Andric PrintExpr(E->getSubExpr()); 27370b57cec5SDimitry Andric } 27380b57cec5SDimitry Andric 27390b57cec5SDimitry Andric void 27400b57cec5SDimitry Andric StmtPrinter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) { 27410b57cec5SDimitry Andric OS << '(' << E->getBridgeKindName(); 27420b57cec5SDimitry Andric E->getType().print(OS, Policy); 27430b57cec5SDimitry Andric OS << ')'; 27440b57cec5SDimitry Andric PrintExpr(E->getSubExpr()); 27450b57cec5SDimitry Andric } 27460b57cec5SDimitry Andric 27470b57cec5SDimitry Andric void StmtPrinter::VisitBlockExpr(BlockExpr *Node) { 27480b57cec5SDimitry Andric BlockDecl *BD = Node->getBlockDecl(); 27490b57cec5SDimitry Andric OS << "^"; 27500b57cec5SDimitry Andric 27510b57cec5SDimitry Andric const FunctionType *AFT = Node->getFunctionType(); 27520b57cec5SDimitry Andric 27530b57cec5SDimitry Andric if (isa<FunctionNoProtoType>(AFT)) { 27540b57cec5SDimitry Andric OS << "()"; 27550b57cec5SDimitry Andric } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) { 27560b57cec5SDimitry Andric OS << '('; 27570b57cec5SDimitry Andric for (BlockDecl::param_iterator AI = BD->param_begin(), 27580b57cec5SDimitry Andric E = BD->param_end(); AI != E; ++AI) { 27590b57cec5SDimitry Andric if (AI != BD->param_begin()) OS << ", "; 27600b57cec5SDimitry Andric std::string ParamStr = (*AI)->getNameAsString(); 27610b57cec5SDimitry Andric (*AI)->getType().print(OS, Policy, ParamStr); 27620b57cec5SDimitry Andric } 27630b57cec5SDimitry Andric 27640b57cec5SDimitry Andric const auto *FT = cast<FunctionProtoType>(AFT); 27650b57cec5SDimitry Andric if (FT->isVariadic()) { 27660b57cec5SDimitry Andric if (!BD->param_empty()) OS << ", "; 27670b57cec5SDimitry Andric OS << "..."; 27680b57cec5SDimitry Andric } 27690b57cec5SDimitry Andric OS << ')'; 27700b57cec5SDimitry Andric } 27710b57cec5SDimitry Andric OS << "{ }"; 27720b57cec5SDimitry Andric } 27730b57cec5SDimitry Andric 27740b57cec5SDimitry Andric void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) { 27750b57cec5SDimitry Andric PrintExpr(Node->getSourceExpr()); 27760b57cec5SDimitry Andric } 27770b57cec5SDimitry Andric 27780b57cec5SDimitry Andric void StmtPrinter::VisitTypoExpr(TypoExpr *Node) { 27790b57cec5SDimitry Andric // TODO: Print something reasonable for a TypoExpr, if necessary. 27800b57cec5SDimitry Andric llvm_unreachable("Cannot print TypoExpr nodes"); 27810b57cec5SDimitry Andric } 27820b57cec5SDimitry Andric 27835ffd83dbSDimitry Andric void StmtPrinter::VisitRecoveryExpr(RecoveryExpr *Node) { 27845ffd83dbSDimitry Andric OS << "<recovery-expr>("; 27855ffd83dbSDimitry Andric const char *Sep = ""; 27865ffd83dbSDimitry Andric for (Expr *E : Node->subExpressions()) { 27875ffd83dbSDimitry Andric OS << Sep; 27885ffd83dbSDimitry Andric PrintExpr(E); 27895ffd83dbSDimitry Andric Sep = ", "; 27905ffd83dbSDimitry Andric } 27915ffd83dbSDimitry Andric OS << ')'; 27925ffd83dbSDimitry Andric } 27935ffd83dbSDimitry Andric 27940b57cec5SDimitry Andric void StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) { 27950b57cec5SDimitry Andric OS << "__builtin_astype("; 27960b57cec5SDimitry Andric PrintExpr(Node->getSrcExpr()); 27970b57cec5SDimitry Andric OS << ", "; 27980b57cec5SDimitry Andric Node->getType().print(OS, Policy); 27990b57cec5SDimitry Andric OS << ")"; 28000b57cec5SDimitry Andric } 28010b57cec5SDimitry Andric 28020b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 28030b57cec5SDimitry Andric // Stmt method implementations 28040b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 28050b57cec5SDimitry Andric 28060b57cec5SDimitry Andric void Stmt::dumpPretty(const ASTContext &Context) const { 28070b57cec5SDimitry Andric printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts())); 28080b57cec5SDimitry Andric } 28090b57cec5SDimitry Andric 28100b57cec5SDimitry Andric void Stmt::printPretty(raw_ostream &Out, PrinterHelper *Helper, 28110b57cec5SDimitry Andric const PrintingPolicy &Policy, unsigned Indentation, 28120b57cec5SDimitry Andric StringRef NL, const ASTContext *Context) const { 28130b57cec5SDimitry Andric StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context); 28140b57cec5SDimitry Andric P.Visit(const_cast<Stmt *>(this)); 28150b57cec5SDimitry Andric } 28160b57cec5SDimitry Andric 2817349cc55cSDimitry Andric void Stmt::printPrettyControlled(raw_ostream &Out, PrinterHelper *Helper, 2818349cc55cSDimitry Andric const PrintingPolicy &Policy, 2819349cc55cSDimitry Andric unsigned Indentation, StringRef NL, 2820349cc55cSDimitry Andric const ASTContext *Context) const { 2821349cc55cSDimitry Andric StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context); 2822349cc55cSDimitry Andric P.PrintControlledStmt(const_cast<Stmt *>(this)); 2823349cc55cSDimitry Andric } 2824349cc55cSDimitry Andric 28250b57cec5SDimitry Andric void Stmt::printJson(raw_ostream &Out, PrinterHelper *Helper, 28260b57cec5SDimitry Andric const PrintingPolicy &Policy, bool AddQuotes) const { 28270b57cec5SDimitry Andric std::string Buf; 28280b57cec5SDimitry Andric llvm::raw_string_ostream TempOut(Buf); 28290b57cec5SDimitry Andric 28300b57cec5SDimitry Andric printPretty(TempOut, Helper, Policy); 28310b57cec5SDimitry Andric 28320b57cec5SDimitry Andric Out << JsonFormat(TempOut.str(), AddQuotes); 28330b57cec5SDimitry Andric } 28340b57cec5SDimitry Andric 28350b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 28360b57cec5SDimitry Andric // PrinterHelper 28370b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 28380b57cec5SDimitry Andric 28390b57cec5SDimitry Andric // Implement virtual destructor. 28400b57cec5SDimitry Andric PrinterHelper::~PrinterHelper() = default; 2841