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" 500b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 510b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 520b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 530b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 540b57cec5SDimitry Andric #include "llvm/Support/Format.h" 550b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 560b57cec5SDimitry Andric #include <cassert> 570b57cec5SDimitry Andric #include <string> 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric using namespace clang; 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 620b57cec5SDimitry Andric // StmtPrinter Visitor 630b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric namespace { 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric class StmtPrinter : public StmtVisitor<StmtPrinter> { 680b57cec5SDimitry Andric raw_ostream &OS; 690b57cec5SDimitry Andric unsigned IndentLevel; 700b57cec5SDimitry Andric PrinterHelper* Helper; 710b57cec5SDimitry Andric PrintingPolicy Policy; 720b57cec5SDimitry Andric std::string NL; 730b57cec5SDimitry Andric const ASTContext *Context; 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric public: 760b57cec5SDimitry Andric StmtPrinter(raw_ostream &os, PrinterHelper *helper, 770b57cec5SDimitry Andric const PrintingPolicy &Policy, unsigned Indentation = 0, 780b57cec5SDimitry Andric StringRef NL = "\n", 790b57cec5SDimitry Andric const ASTContext *Context = nullptr) 800b57cec5SDimitry Andric : OS(os), IndentLevel(Indentation), Helper(helper), Policy(Policy), 810b57cec5SDimitry Andric NL(NL), Context(Context) {} 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric void PrintStmt(Stmt *S) { 840b57cec5SDimitry Andric PrintStmt(S, Policy.Indentation); 850b57cec5SDimitry Andric } 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric void PrintStmt(Stmt *S, int SubIndent) { 880b57cec5SDimitry Andric IndentLevel += SubIndent; 890b57cec5SDimitry Andric if (S && isa<Expr>(S)) { 900b57cec5SDimitry Andric // If this is an expr used in a stmt context, indent and newline it. 910b57cec5SDimitry Andric Indent(); 920b57cec5SDimitry Andric Visit(S); 930b57cec5SDimitry Andric OS << ";" << NL; 940b57cec5SDimitry Andric } else if (S) { 950b57cec5SDimitry Andric Visit(S); 960b57cec5SDimitry Andric } else { 970b57cec5SDimitry Andric Indent() << "<<<NULL STATEMENT>>>" << NL; 980b57cec5SDimitry Andric } 990b57cec5SDimitry Andric IndentLevel -= SubIndent; 1000b57cec5SDimitry Andric } 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric void PrintInitStmt(Stmt *S, unsigned PrefixWidth) { 1030b57cec5SDimitry Andric // FIXME: Cope better with odd prefix widths. 1040b57cec5SDimitry Andric IndentLevel += (PrefixWidth + 1) / 2; 1050b57cec5SDimitry Andric if (auto *DS = dyn_cast<DeclStmt>(S)) 1060b57cec5SDimitry Andric PrintRawDeclStmt(DS); 1070b57cec5SDimitry Andric else 1080b57cec5SDimitry Andric PrintExpr(cast<Expr>(S)); 1090b57cec5SDimitry Andric OS << "; "; 1100b57cec5SDimitry Andric IndentLevel -= (PrefixWidth + 1) / 2; 1110b57cec5SDimitry Andric } 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric void PrintControlledStmt(Stmt *S) { 1140b57cec5SDimitry Andric if (auto *CS = dyn_cast<CompoundStmt>(S)) { 1150b57cec5SDimitry Andric OS << " "; 1160b57cec5SDimitry Andric PrintRawCompoundStmt(CS); 1170b57cec5SDimitry Andric OS << NL; 1180b57cec5SDimitry Andric } else { 1190b57cec5SDimitry Andric OS << NL; 1200b57cec5SDimitry Andric PrintStmt(S); 1210b57cec5SDimitry Andric } 1220b57cec5SDimitry Andric } 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric void PrintRawCompoundStmt(CompoundStmt *S); 1250b57cec5SDimitry Andric void PrintRawDecl(Decl *D); 1260b57cec5SDimitry Andric void PrintRawDeclStmt(const DeclStmt *S); 1270b57cec5SDimitry Andric void PrintRawIfStmt(IfStmt *If); 1280b57cec5SDimitry Andric void PrintRawCXXCatchStmt(CXXCatchStmt *Catch); 1290b57cec5SDimitry Andric void PrintCallArgs(CallExpr *E); 1300b57cec5SDimitry Andric void PrintRawSEHExceptHandler(SEHExceptStmt *S); 1310b57cec5SDimitry Andric void PrintRawSEHFinallyStmt(SEHFinallyStmt *S); 1320b57cec5SDimitry Andric void PrintOMPExecutableDirective(OMPExecutableDirective *S, 1330b57cec5SDimitry Andric bool ForceNoStmt = false); 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric void PrintExpr(Expr *E) { 1360b57cec5SDimitry Andric if (E) 1370b57cec5SDimitry Andric Visit(E); 1380b57cec5SDimitry Andric else 1390b57cec5SDimitry Andric OS << "<null expr>"; 1400b57cec5SDimitry Andric } 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric raw_ostream &Indent(int Delta = 0) { 1430b57cec5SDimitry Andric for (int i = 0, e = IndentLevel+Delta; i < e; ++i) 1440b57cec5SDimitry Andric OS << " "; 1450b57cec5SDimitry Andric return OS; 1460b57cec5SDimitry Andric } 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andric void Visit(Stmt* S) { 1490b57cec5SDimitry Andric if (Helper && Helper->handledStmt(S,OS)) 1500b57cec5SDimitry Andric return; 1510b57cec5SDimitry Andric else StmtVisitor<StmtPrinter>::Visit(S); 1520b57cec5SDimitry Andric } 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric void VisitStmt(Stmt *Node) LLVM_ATTRIBUTE_UNUSED { 1550b57cec5SDimitry Andric Indent() << "<<unknown stmt type>>" << NL; 1560b57cec5SDimitry Andric } 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric void VisitExpr(Expr *Node) LLVM_ATTRIBUTE_UNUSED { 1590b57cec5SDimitry Andric OS << "<<unknown expr type>>"; 1600b57cec5SDimitry Andric } 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node); 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andric #define ABSTRACT_STMT(CLASS) 1650b57cec5SDimitry Andric #define STMT(CLASS, PARENT) \ 1660b57cec5SDimitry Andric void Visit##CLASS(CLASS *Node); 1670b57cec5SDimitry Andric #include "clang/AST/StmtNodes.inc" 1680b57cec5SDimitry Andric }; 1690b57cec5SDimitry Andric 1700b57cec5SDimitry Andric } // namespace 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1730b57cec5SDimitry Andric // Stmt printing methods. 1740b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric /// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and 1770b57cec5SDimitry Andric /// with no newline after the }. 1780b57cec5SDimitry Andric void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) { 1790b57cec5SDimitry Andric OS << "{" << NL; 1800b57cec5SDimitry Andric for (auto *I : Node->body()) 1810b57cec5SDimitry Andric PrintStmt(I); 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric Indent() << "}"; 1840b57cec5SDimitry Andric } 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric void StmtPrinter::PrintRawDecl(Decl *D) { 1870b57cec5SDimitry Andric D->print(OS, Policy, IndentLevel); 1880b57cec5SDimitry Andric } 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric void StmtPrinter::PrintRawDeclStmt(const DeclStmt *S) { 1910b57cec5SDimitry Andric SmallVector<Decl *, 2> Decls(S->decls()); 1920b57cec5SDimitry Andric Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel); 1930b57cec5SDimitry Andric } 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric void StmtPrinter::VisitNullStmt(NullStmt *Node) { 1960b57cec5SDimitry Andric Indent() << ";" << NL; 1970b57cec5SDimitry Andric } 1980b57cec5SDimitry Andric 1990b57cec5SDimitry Andric void StmtPrinter::VisitDeclStmt(DeclStmt *Node) { 2000b57cec5SDimitry Andric Indent(); 2010b57cec5SDimitry Andric PrintRawDeclStmt(Node); 2020b57cec5SDimitry Andric OS << ";" << NL; 2030b57cec5SDimitry Andric } 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andric void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) { 2060b57cec5SDimitry Andric Indent(); 2070b57cec5SDimitry Andric PrintRawCompoundStmt(Node); 2080b57cec5SDimitry Andric OS << "" << NL; 2090b57cec5SDimitry Andric } 2100b57cec5SDimitry Andric 2110b57cec5SDimitry Andric void StmtPrinter::VisitCaseStmt(CaseStmt *Node) { 2120b57cec5SDimitry Andric Indent(-1) << "case "; 2130b57cec5SDimitry Andric PrintExpr(Node->getLHS()); 2140b57cec5SDimitry Andric if (Node->getRHS()) { 2150b57cec5SDimitry Andric OS << " ... "; 2160b57cec5SDimitry Andric PrintExpr(Node->getRHS()); 2170b57cec5SDimitry Andric } 2180b57cec5SDimitry Andric OS << ":" << NL; 2190b57cec5SDimitry Andric 2200b57cec5SDimitry Andric PrintStmt(Node->getSubStmt(), 0); 2210b57cec5SDimitry Andric } 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) { 2240b57cec5SDimitry Andric Indent(-1) << "default:" << NL; 2250b57cec5SDimitry Andric PrintStmt(Node->getSubStmt(), 0); 2260b57cec5SDimitry Andric } 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric void StmtPrinter::VisitLabelStmt(LabelStmt *Node) { 2290b57cec5SDimitry Andric Indent(-1) << Node->getName() << ":" << NL; 2300b57cec5SDimitry Andric PrintStmt(Node->getSubStmt(), 0); 2310b57cec5SDimitry Andric } 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) { 2340b57cec5SDimitry Andric for (const auto *Attr : Node->getAttrs()) { 2350b57cec5SDimitry Andric Attr->printPretty(OS, Policy); 2360b57cec5SDimitry Andric } 2370b57cec5SDimitry Andric 2380b57cec5SDimitry Andric PrintStmt(Node->getSubStmt(), 0); 2390b57cec5SDimitry Andric } 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andric void StmtPrinter::PrintRawIfStmt(IfStmt *If) { 2420b57cec5SDimitry Andric OS << "if ("; 2430b57cec5SDimitry Andric if (If->getInit()) 2440b57cec5SDimitry Andric PrintInitStmt(If->getInit(), 4); 2450b57cec5SDimitry Andric if (const DeclStmt *DS = If->getConditionVariableDeclStmt()) 2460b57cec5SDimitry Andric PrintRawDeclStmt(DS); 2470b57cec5SDimitry Andric else 2480b57cec5SDimitry Andric PrintExpr(If->getCond()); 2490b57cec5SDimitry Andric OS << ')'; 2500b57cec5SDimitry Andric 2510b57cec5SDimitry Andric if (auto *CS = dyn_cast<CompoundStmt>(If->getThen())) { 2520b57cec5SDimitry Andric OS << ' '; 2530b57cec5SDimitry Andric PrintRawCompoundStmt(CS); 2540b57cec5SDimitry Andric OS << (If->getElse() ? " " : NL); 2550b57cec5SDimitry Andric } else { 2560b57cec5SDimitry Andric OS << NL; 2570b57cec5SDimitry Andric PrintStmt(If->getThen()); 2580b57cec5SDimitry Andric if (If->getElse()) Indent(); 2590b57cec5SDimitry Andric } 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andric if (Stmt *Else = If->getElse()) { 2620b57cec5SDimitry Andric OS << "else"; 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric if (auto *CS = dyn_cast<CompoundStmt>(Else)) { 2650b57cec5SDimitry Andric OS << ' '; 2660b57cec5SDimitry Andric PrintRawCompoundStmt(CS); 2670b57cec5SDimitry Andric OS << NL; 2680b57cec5SDimitry Andric } else if (auto *ElseIf = dyn_cast<IfStmt>(Else)) { 2690b57cec5SDimitry Andric OS << ' '; 2700b57cec5SDimitry Andric PrintRawIfStmt(ElseIf); 2710b57cec5SDimitry Andric } else { 2720b57cec5SDimitry Andric OS << NL; 2730b57cec5SDimitry Andric PrintStmt(If->getElse()); 2740b57cec5SDimitry Andric } 2750b57cec5SDimitry Andric } 2760b57cec5SDimitry Andric } 2770b57cec5SDimitry Andric 2780b57cec5SDimitry Andric void StmtPrinter::VisitIfStmt(IfStmt *If) { 2790b57cec5SDimitry Andric Indent(); 2800b57cec5SDimitry Andric PrintRawIfStmt(If); 2810b57cec5SDimitry Andric } 2820b57cec5SDimitry Andric 2830b57cec5SDimitry Andric void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) { 2840b57cec5SDimitry Andric Indent() << "switch ("; 2850b57cec5SDimitry Andric if (Node->getInit()) 2860b57cec5SDimitry Andric PrintInitStmt(Node->getInit(), 8); 2870b57cec5SDimitry Andric if (const DeclStmt *DS = Node->getConditionVariableDeclStmt()) 2880b57cec5SDimitry Andric PrintRawDeclStmt(DS); 2890b57cec5SDimitry Andric else 2900b57cec5SDimitry Andric PrintExpr(Node->getCond()); 2910b57cec5SDimitry Andric OS << ")"; 2920b57cec5SDimitry Andric PrintControlledStmt(Node->getBody()); 2930b57cec5SDimitry Andric } 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric void StmtPrinter::VisitWhileStmt(WhileStmt *Node) { 2960b57cec5SDimitry Andric Indent() << "while ("; 2970b57cec5SDimitry Andric if (const DeclStmt *DS = Node->getConditionVariableDeclStmt()) 2980b57cec5SDimitry Andric PrintRawDeclStmt(DS); 2990b57cec5SDimitry Andric else 3000b57cec5SDimitry Andric PrintExpr(Node->getCond()); 3010b57cec5SDimitry Andric OS << ")" << NL; 3020b57cec5SDimitry Andric PrintStmt(Node->getBody()); 3030b57cec5SDimitry Andric } 3040b57cec5SDimitry Andric 3050b57cec5SDimitry Andric void StmtPrinter::VisitDoStmt(DoStmt *Node) { 3060b57cec5SDimitry Andric Indent() << "do "; 3070b57cec5SDimitry Andric if (auto *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 3080b57cec5SDimitry Andric PrintRawCompoundStmt(CS); 3090b57cec5SDimitry Andric OS << " "; 3100b57cec5SDimitry Andric } else { 3110b57cec5SDimitry Andric OS << NL; 3120b57cec5SDimitry Andric PrintStmt(Node->getBody()); 3130b57cec5SDimitry Andric Indent(); 3140b57cec5SDimitry Andric } 3150b57cec5SDimitry Andric 3160b57cec5SDimitry Andric OS << "while ("; 3170b57cec5SDimitry Andric PrintExpr(Node->getCond()); 3180b57cec5SDimitry Andric OS << ");" << NL; 3190b57cec5SDimitry Andric } 3200b57cec5SDimitry Andric 3210b57cec5SDimitry Andric void StmtPrinter::VisitForStmt(ForStmt *Node) { 3220b57cec5SDimitry Andric Indent() << "for ("; 3230b57cec5SDimitry Andric if (Node->getInit()) 3240b57cec5SDimitry Andric PrintInitStmt(Node->getInit(), 5); 3250b57cec5SDimitry Andric else 3260b57cec5SDimitry Andric OS << (Node->getCond() ? "; " : ";"); 3270b57cec5SDimitry Andric if (Node->getCond()) 3280b57cec5SDimitry Andric PrintExpr(Node->getCond()); 3290b57cec5SDimitry Andric OS << ";"; 3300b57cec5SDimitry Andric if (Node->getInc()) { 3310b57cec5SDimitry Andric OS << " "; 3320b57cec5SDimitry Andric PrintExpr(Node->getInc()); 3330b57cec5SDimitry Andric } 3340b57cec5SDimitry Andric OS << ")"; 3350b57cec5SDimitry Andric PrintControlledStmt(Node->getBody()); 3360b57cec5SDimitry Andric } 3370b57cec5SDimitry Andric 3380b57cec5SDimitry Andric void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) { 3390b57cec5SDimitry Andric Indent() << "for ("; 3400b57cec5SDimitry Andric if (auto *DS = dyn_cast<DeclStmt>(Node->getElement())) 3410b57cec5SDimitry Andric PrintRawDeclStmt(DS); 3420b57cec5SDimitry Andric else 3430b57cec5SDimitry Andric PrintExpr(cast<Expr>(Node->getElement())); 3440b57cec5SDimitry Andric OS << " in "; 3450b57cec5SDimitry Andric PrintExpr(Node->getCollection()); 3460b57cec5SDimitry Andric OS << ")"; 3470b57cec5SDimitry Andric PrintControlledStmt(Node->getBody()); 3480b57cec5SDimitry Andric } 3490b57cec5SDimitry Andric 3500b57cec5SDimitry Andric void StmtPrinter::VisitCXXForRangeStmt(CXXForRangeStmt *Node) { 3510b57cec5SDimitry Andric Indent() << "for ("; 3520b57cec5SDimitry Andric if (Node->getInit()) 3530b57cec5SDimitry Andric PrintInitStmt(Node->getInit(), 5); 3540b57cec5SDimitry Andric PrintingPolicy SubPolicy(Policy); 3550b57cec5SDimitry Andric SubPolicy.SuppressInitializers = true; 3560b57cec5SDimitry Andric Node->getLoopVariable()->print(OS, SubPolicy, IndentLevel); 3570b57cec5SDimitry Andric OS << " : "; 3580b57cec5SDimitry Andric PrintExpr(Node->getRangeInit()); 3590b57cec5SDimitry Andric OS << ")"; 3600b57cec5SDimitry Andric PrintControlledStmt(Node->getBody()); 3610b57cec5SDimitry Andric } 3620b57cec5SDimitry Andric 3630b57cec5SDimitry Andric void StmtPrinter::VisitMSDependentExistsStmt(MSDependentExistsStmt *Node) { 3640b57cec5SDimitry Andric Indent(); 3650b57cec5SDimitry Andric if (Node->isIfExists()) 3660b57cec5SDimitry Andric OS << "__if_exists ("; 3670b57cec5SDimitry Andric else 3680b57cec5SDimitry Andric OS << "__if_not_exists ("; 3690b57cec5SDimitry Andric 3700b57cec5SDimitry Andric if (NestedNameSpecifier *Qualifier 3710b57cec5SDimitry Andric = Node->getQualifierLoc().getNestedNameSpecifier()) 3720b57cec5SDimitry Andric Qualifier->print(OS, Policy); 3730b57cec5SDimitry Andric 3740b57cec5SDimitry Andric OS << Node->getNameInfo() << ") "; 3750b57cec5SDimitry Andric 3760b57cec5SDimitry Andric PrintRawCompoundStmt(Node->getSubStmt()); 3770b57cec5SDimitry Andric } 3780b57cec5SDimitry Andric 3790b57cec5SDimitry Andric void StmtPrinter::VisitGotoStmt(GotoStmt *Node) { 3800b57cec5SDimitry Andric Indent() << "goto " << Node->getLabel()->getName() << ";"; 3810b57cec5SDimitry Andric if (Policy.IncludeNewlines) OS << NL; 3820b57cec5SDimitry Andric } 3830b57cec5SDimitry Andric 3840b57cec5SDimitry Andric void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) { 3850b57cec5SDimitry Andric Indent() << "goto *"; 3860b57cec5SDimitry Andric PrintExpr(Node->getTarget()); 3870b57cec5SDimitry Andric OS << ";"; 3880b57cec5SDimitry Andric if (Policy.IncludeNewlines) OS << NL; 3890b57cec5SDimitry Andric } 3900b57cec5SDimitry Andric 3910b57cec5SDimitry Andric void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) { 3920b57cec5SDimitry Andric Indent() << "continue;"; 3930b57cec5SDimitry Andric if (Policy.IncludeNewlines) OS << NL; 3940b57cec5SDimitry Andric } 3950b57cec5SDimitry Andric 3960b57cec5SDimitry Andric void StmtPrinter::VisitBreakStmt(BreakStmt *Node) { 3970b57cec5SDimitry Andric Indent() << "break;"; 3980b57cec5SDimitry Andric if (Policy.IncludeNewlines) OS << NL; 3990b57cec5SDimitry Andric } 4000b57cec5SDimitry Andric 4010b57cec5SDimitry Andric void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) { 4020b57cec5SDimitry Andric Indent() << "return"; 4030b57cec5SDimitry Andric if (Node->getRetValue()) { 4040b57cec5SDimitry Andric OS << " "; 4050b57cec5SDimitry Andric PrintExpr(Node->getRetValue()); 4060b57cec5SDimitry Andric } 4070b57cec5SDimitry Andric OS << ";"; 4080b57cec5SDimitry Andric if (Policy.IncludeNewlines) OS << NL; 4090b57cec5SDimitry Andric } 4100b57cec5SDimitry Andric 4110b57cec5SDimitry Andric void StmtPrinter::VisitGCCAsmStmt(GCCAsmStmt *Node) { 4120b57cec5SDimitry Andric Indent() << "asm "; 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andric if (Node->isVolatile()) 4150b57cec5SDimitry Andric OS << "volatile "; 4160b57cec5SDimitry Andric 4170b57cec5SDimitry Andric if (Node->isAsmGoto()) 4180b57cec5SDimitry Andric OS << "goto "; 4190b57cec5SDimitry Andric 4200b57cec5SDimitry Andric OS << "("; 4210b57cec5SDimitry Andric VisitStringLiteral(Node->getAsmString()); 4220b57cec5SDimitry Andric 4230b57cec5SDimitry Andric // Outputs 4240b57cec5SDimitry Andric if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 || 4250b57cec5SDimitry Andric Node->getNumClobbers() != 0 || Node->getNumLabels() != 0) 4260b57cec5SDimitry Andric OS << " : "; 4270b57cec5SDimitry Andric 4280b57cec5SDimitry Andric for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) { 4290b57cec5SDimitry Andric if (i != 0) 4300b57cec5SDimitry Andric OS << ", "; 4310b57cec5SDimitry Andric 4320b57cec5SDimitry Andric if (!Node->getOutputName(i).empty()) { 4330b57cec5SDimitry Andric OS << '['; 4340b57cec5SDimitry Andric OS << Node->getOutputName(i); 4350b57cec5SDimitry Andric OS << "] "; 4360b57cec5SDimitry Andric } 4370b57cec5SDimitry Andric 4380b57cec5SDimitry Andric VisitStringLiteral(Node->getOutputConstraintLiteral(i)); 4390b57cec5SDimitry Andric OS << " ("; 4400b57cec5SDimitry Andric Visit(Node->getOutputExpr(i)); 4410b57cec5SDimitry Andric OS << ")"; 4420b57cec5SDimitry Andric } 4430b57cec5SDimitry Andric 4440b57cec5SDimitry Andric // Inputs 4450b57cec5SDimitry Andric if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0 || 4460b57cec5SDimitry Andric Node->getNumLabels() != 0) 4470b57cec5SDimitry Andric OS << " : "; 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andric for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) { 4500b57cec5SDimitry Andric if (i != 0) 4510b57cec5SDimitry Andric OS << ", "; 4520b57cec5SDimitry Andric 4530b57cec5SDimitry Andric if (!Node->getInputName(i).empty()) { 4540b57cec5SDimitry Andric OS << '['; 4550b57cec5SDimitry Andric OS << Node->getInputName(i); 4560b57cec5SDimitry Andric OS << "] "; 4570b57cec5SDimitry Andric } 4580b57cec5SDimitry Andric 4590b57cec5SDimitry Andric VisitStringLiteral(Node->getInputConstraintLiteral(i)); 4600b57cec5SDimitry Andric OS << " ("; 4610b57cec5SDimitry Andric Visit(Node->getInputExpr(i)); 4620b57cec5SDimitry Andric OS << ")"; 4630b57cec5SDimitry Andric } 4640b57cec5SDimitry Andric 4650b57cec5SDimitry Andric // Clobbers 4660b57cec5SDimitry Andric if (Node->getNumClobbers() != 0 || Node->getNumLabels()) 4670b57cec5SDimitry Andric OS << " : "; 4680b57cec5SDimitry Andric 4690b57cec5SDimitry Andric for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) { 4700b57cec5SDimitry Andric if (i != 0) 4710b57cec5SDimitry Andric OS << ", "; 4720b57cec5SDimitry Andric 4730b57cec5SDimitry Andric VisitStringLiteral(Node->getClobberStringLiteral(i)); 4740b57cec5SDimitry Andric } 4750b57cec5SDimitry Andric 4760b57cec5SDimitry Andric // Labels 4770b57cec5SDimitry Andric if (Node->getNumLabels() != 0) 4780b57cec5SDimitry Andric OS << " : "; 4790b57cec5SDimitry Andric 4800b57cec5SDimitry Andric for (unsigned i = 0, e = Node->getNumLabels(); i != e; ++i) { 4810b57cec5SDimitry Andric if (i != 0) 4820b57cec5SDimitry Andric OS << ", "; 4830b57cec5SDimitry Andric OS << Node->getLabelName(i); 4840b57cec5SDimitry Andric } 4850b57cec5SDimitry Andric 4860b57cec5SDimitry Andric OS << ");"; 4870b57cec5SDimitry Andric if (Policy.IncludeNewlines) OS << NL; 4880b57cec5SDimitry Andric } 4890b57cec5SDimitry Andric 4900b57cec5SDimitry Andric void StmtPrinter::VisitMSAsmStmt(MSAsmStmt *Node) { 4910b57cec5SDimitry Andric // FIXME: Implement MS style inline asm statement printer. 4920b57cec5SDimitry Andric Indent() << "__asm "; 4930b57cec5SDimitry Andric if (Node->hasBraces()) 4940b57cec5SDimitry Andric OS << "{" << NL; 4950b57cec5SDimitry Andric OS << Node->getAsmString() << NL; 4960b57cec5SDimitry Andric if (Node->hasBraces()) 4970b57cec5SDimitry Andric Indent() << "}" << NL; 4980b57cec5SDimitry Andric } 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andric void StmtPrinter::VisitCapturedStmt(CapturedStmt *Node) { 5010b57cec5SDimitry Andric PrintStmt(Node->getCapturedDecl()->getBody()); 5020b57cec5SDimitry Andric } 5030b57cec5SDimitry Andric 5040b57cec5SDimitry Andric void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) { 5050b57cec5SDimitry Andric Indent() << "@try"; 5060b57cec5SDimitry Andric if (auto *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) { 5070b57cec5SDimitry Andric PrintRawCompoundStmt(TS); 5080b57cec5SDimitry Andric OS << NL; 5090b57cec5SDimitry Andric } 5100b57cec5SDimitry Andric 5110b57cec5SDimitry Andric for (unsigned I = 0, N = Node->getNumCatchStmts(); I != N; ++I) { 5120b57cec5SDimitry Andric ObjCAtCatchStmt *catchStmt = Node->getCatchStmt(I); 5130b57cec5SDimitry Andric Indent() << "@catch("; 5140b57cec5SDimitry Andric if (catchStmt->getCatchParamDecl()) { 5150b57cec5SDimitry Andric if (Decl *DS = catchStmt->getCatchParamDecl()) 5160b57cec5SDimitry Andric PrintRawDecl(DS); 5170b57cec5SDimitry Andric } 5180b57cec5SDimitry Andric OS << ")"; 5190b57cec5SDimitry Andric if (auto *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) { 5200b57cec5SDimitry Andric PrintRawCompoundStmt(CS); 5210b57cec5SDimitry Andric OS << NL; 5220b57cec5SDimitry Andric } 5230b57cec5SDimitry Andric } 5240b57cec5SDimitry Andric 5250b57cec5SDimitry Andric if (auto *FS = static_cast<ObjCAtFinallyStmt *>(Node->getFinallyStmt())) { 5260b57cec5SDimitry Andric Indent() << "@finally"; 5270b57cec5SDimitry Andric PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody())); 5280b57cec5SDimitry Andric OS << NL; 5290b57cec5SDimitry Andric } 5300b57cec5SDimitry Andric } 5310b57cec5SDimitry Andric 5320b57cec5SDimitry Andric void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) { 5330b57cec5SDimitry Andric } 5340b57cec5SDimitry Andric 5350b57cec5SDimitry Andric void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) { 5360b57cec5SDimitry Andric Indent() << "@catch (...) { /* todo */ } " << NL; 5370b57cec5SDimitry Andric } 5380b57cec5SDimitry Andric 5390b57cec5SDimitry Andric void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) { 5400b57cec5SDimitry Andric Indent() << "@throw"; 5410b57cec5SDimitry Andric if (Node->getThrowExpr()) { 5420b57cec5SDimitry Andric OS << " "; 5430b57cec5SDimitry Andric PrintExpr(Node->getThrowExpr()); 5440b57cec5SDimitry Andric } 5450b57cec5SDimitry Andric OS << ";" << NL; 5460b57cec5SDimitry Andric } 5470b57cec5SDimitry Andric 5480b57cec5SDimitry Andric void StmtPrinter::VisitObjCAvailabilityCheckExpr( 5490b57cec5SDimitry Andric ObjCAvailabilityCheckExpr *Node) { 5500b57cec5SDimitry Andric OS << "@available(...)"; 5510b57cec5SDimitry Andric } 5520b57cec5SDimitry Andric 5530b57cec5SDimitry Andric void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) { 5540b57cec5SDimitry Andric Indent() << "@synchronized ("; 5550b57cec5SDimitry Andric PrintExpr(Node->getSynchExpr()); 5560b57cec5SDimitry Andric OS << ")"; 5570b57cec5SDimitry Andric PrintRawCompoundStmt(Node->getSynchBody()); 5580b57cec5SDimitry Andric OS << NL; 5590b57cec5SDimitry Andric } 5600b57cec5SDimitry Andric 5610b57cec5SDimitry Andric void StmtPrinter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *Node) { 5620b57cec5SDimitry Andric Indent() << "@autoreleasepool"; 5630b57cec5SDimitry Andric PrintRawCompoundStmt(dyn_cast<CompoundStmt>(Node->getSubStmt())); 5640b57cec5SDimitry Andric OS << NL; 5650b57cec5SDimitry Andric } 5660b57cec5SDimitry Andric 5670b57cec5SDimitry Andric void StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) { 5680b57cec5SDimitry Andric OS << "catch ("; 5690b57cec5SDimitry Andric if (Decl *ExDecl = Node->getExceptionDecl()) 5700b57cec5SDimitry Andric PrintRawDecl(ExDecl); 5710b57cec5SDimitry Andric else 5720b57cec5SDimitry Andric OS << "..."; 5730b57cec5SDimitry Andric OS << ") "; 5740b57cec5SDimitry Andric PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock())); 5750b57cec5SDimitry Andric } 5760b57cec5SDimitry Andric 5770b57cec5SDimitry Andric void StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) { 5780b57cec5SDimitry Andric Indent(); 5790b57cec5SDimitry Andric PrintRawCXXCatchStmt(Node); 5800b57cec5SDimitry Andric OS << NL; 5810b57cec5SDimitry Andric } 5820b57cec5SDimitry Andric 5830b57cec5SDimitry Andric void StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) { 5840b57cec5SDimitry Andric Indent() << "try "; 5850b57cec5SDimitry Andric PrintRawCompoundStmt(Node->getTryBlock()); 5860b57cec5SDimitry Andric for (unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) { 5870b57cec5SDimitry Andric OS << " "; 5880b57cec5SDimitry Andric PrintRawCXXCatchStmt(Node->getHandler(i)); 5890b57cec5SDimitry Andric } 5900b57cec5SDimitry Andric OS << NL; 5910b57cec5SDimitry Andric } 5920b57cec5SDimitry Andric 5930b57cec5SDimitry Andric void StmtPrinter::VisitSEHTryStmt(SEHTryStmt *Node) { 5940b57cec5SDimitry Andric Indent() << (Node->getIsCXXTry() ? "try " : "__try "); 5950b57cec5SDimitry Andric PrintRawCompoundStmt(Node->getTryBlock()); 5960b57cec5SDimitry Andric SEHExceptStmt *E = Node->getExceptHandler(); 5970b57cec5SDimitry Andric SEHFinallyStmt *F = Node->getFinallyHandler(); 5980b57cec5SDimitry Andric if(E) 5990b57cec5SDimitry Andric PrintRawSEHExceptHandler(E); 6000b57cec5SDimitry Andric else { 6010b57cec5SDimitry Andric assert(F && "Must have a finally block..."); 6020b57cec5SDimitry Andric PrintRawSEHFinallyStmt(F); 6030b57cec5SDimitry Andric } 6040b57cec5SDimitry Andric OS << NL; 6050b57cec5SDimitry Andric } 6060b57cec5SDimitry Andric 6070b57cec5SDimitry Andric void StmtPrinter::PrintRawSEHFinallyStmt(SEHFinallyStmt *Node) { 6080b57cec5SDimitry Andric OS << "__finally "; 6090b57cec5SDimitry Andric PrintRawCompoundStmt(Node->getBlock()); 6100b57cec5SDimitry Andric OS << NL; 6110b57cec5SDimitry Andric } 6120b57cec5SDimitry Andric 6130b57cec5SDimitry Andric void StmtPrinter::PrintRawSEHExceptHandler(SEHExceptStmt *Node) { 6140b57cec5SDimitry Andric OS << "__except ("; 6150b57cec5SDimitry Andric VisitExpr(Node->getFilterExpr()); 6160b57cec5SDimitry Andric OS << ")" << NL; 6170b57cec5SDimitry Andric PrintRawCompoundStmt(Node->getBlock()); 6180b57cec5SDimitry Andric OS << NL; 6190b57cec5SDimitry Andric } 6200b57cec5SDimitry Andric 6210b57cec5SDimitry Andric void StmtPrinter::VisitSEHExceptStmt(SEHExceptStmt *Node) { 6220b57cec5SDimitry Andric Indent(); 6230b57cec5SDimitry Andric PrintRawSEHExceptHandler(Node); 6240b57cec5SDimitry Andric OS << NL; 6250b57cec5SDimitry Andric } 6260b57cec5SDimitry Andric 6270b57cec5SDimitry Andric void StmtPrinter::VisitSEHFinallyStmt(SEHFinallyStmt *Node) { 6280b57cec5SDimitry Andric Indent(); 6290b57cec5SDimitry Andric PrintRawSEHFinallyStmt(Node); 6300b57cec5SDimitry Andric OS << NL; 6310b57cec5SDimitry Andric } 6320b57cec5SDimitry Andric 6330b57cec5SDimitry Andric void StmtPrinter::VisitSEHLeaveStmt(SEHLeaveStmt *Node) { 6340b57cec5SDimitry Andric Indent() << "__leave;"; 6350b57cec5SDimitry Andric if (Policy.IncludeNewlines) OS << NL; 6360b57cec5SDimitry Andric } 6370b57cec5SDimitry Andric 6380b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 6390b57cec5SDimitry Andric // OpenMP directives printing methods 6400b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 6410b57cec5SDimitry Andric 6420b57cec5SDimitry Andric void StmtPrinter::PrintOMPExecutableDirective(OMPExecutableDirective *S, 6430b57cec5SDimitry Andric bool ForceNoStmt) { 6440b57cec5SDimitry Andric OMPClausePrinter Printer(OS, Policy); 6450b57cec5SDimitry Andric ArrayRef<OMPClause *> Clauses = S->clauses(); 6460b57cec5SDimitry Andric for (auto *Clause : Clauses) 6470b57cec5SDimitry Andric if (Clause && !Clause->isImplicit()) { 6480b57cec5SDimitry Andric OS << ' '; 6490b57cec5SDimitry Andric Printer.Visit(Clause); 6500b57cec5SDimitry Andric } 6510b57cec5SDimitry Andric OS << NL; 6520b57cec5SDimitry Andric if (!ForceNoStmt && S->hasAssociatedStmt()) 6530b57cec5SDimitry Andric PrintStmt(S->getInnermostCapturedStmt()->getCapturedStmt()); 6540b57cec5SDimitry Andric } 6550b57cec5SDimitry Andric 6560b57cec5SDimitry Andric void StmtPrinter::VisitOMPParallelDirective(OMPParallelDirective *Node) { 6570b57cec5SDimitry Andric Indent() << "#pragma omp parallel"; 6580b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 6590b57cec5SDimitry Andric } 6600b57cec5SDimitry Andric 6610b57cec5SDimitry Andric void StmtPrinter::VisitOMPSimdDirective(OMPSimdDirective *Node) { 6620b57cec5SDimitry Andric Indent() << "#pragma omp simd"; 6630b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 6640b57cec5SDimitry Andric } 6650b57cec5SDimitry Andric 6660b57cec5SDimitry Andric void StmtPrinter::VisitOMPForDirective(OMPForDirective *Node) { 6670b57cec5SDimitry Andric Indent() << "#pragma omp for"; 6680b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 6690b57cec5SDimitry Andric } 6700b57cec5SDimitry Andric 6710b57cec5SDimitry Andric void StmtPrinter::VisitOMPForSimdDirective(OMPForSimdDirective *Node) { 6720b57cec5SDimitry Andric Indent() << "#pragma omp for simd"; 6730b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 6740b57cec5SDimitry Andric } 6750b57cec5SDimitry Andric 6760b57cec5SDimitry Andric void StmtPrinter::VisitOMPSectionsDirective(OMPSectionsDirective *Node) { 6770b57cec5SDimitry Andric Indent() << "#pragma omp sections"; 6780b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 6790b57cec5SDimitry Andric } 6800b57cec5SDimitry Andric 6810b57cec5SDimitry Andric void StmtPrinter::VisitOMPSectionDirective(OMPSectionDirective *Node) { 6820b57cec5SDimitry Andric Indent() << "#pragma omp section"; 6830b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 6840b57cec5SDimitry Andric } 6850b57cec5SDimitry Andric 6860b57cec5SDimitry Andric void StmtPrinter::VisitOMPSingleDirective(OMPSingleDirective *Node) { 6870b57cec5SDimitry Andric Indent() << "#pragma omp single"; 6880b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 6890b57cec5SDimitry Andric } 6900b57cec5SDimitry Andric 6910b57cec5SDimitry Andric void StmtPrinter::VisitOMPMasterDirective(OMPMasterDirective *Node) { 6920b57cec5SDimitry Andric Indent() << "#pragma omp master"; 6930b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 6940b57cec5SDimitry Andric } 6950b57cec5SDimitry Andric 6960b57cec5SDimitry Andric void StmtPrinter::VisitOMPCriticalDirective(OMPCriticalDirective *Node) { 6970b57cec5SDimitry Andric Indent() << "#pragma omp critical"; 6980b57cec5SDimitry Andric if (Node->getDirectiveName().getName()) { 6990b57cec5SDimitry Andric OS << " ("; 700480093f4SDimitry Andric Node->getDirectiveName().printName(OS, Policy); 7010b57cec5SDimitry Andric OS << ")"; 7020b57cec5SDimitry Andric } 7030b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 7040b57cec5SDimitry Andric } 7050b57cec5SDimitry Andric 7060b57cec5SDimitry Andric void StmtPrinter::VisitOMPParallelForDirective(OMPParallelForDirective *Node) { 7070b57cec5SDimitry Andric Indent() << "#pragma omp parallel for"; 7080b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 7090b57cec5SDimitry Andric } 7100b57cec5SDimitry Andric 7110b57cec5SDimitry Andric void StmtPrinter::VisitOMPParallelForSimdDirective( 7120b57cec5SDimitry Andric OMPParallelForSimdDirective *Node) { 7130b57cec5SDimitry Andric Indent() << "#pragma omp parallel for simd"; 7140b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 7150b57cec5SDimitry Andric } 7160b57cec5SDimitry Andric 717480093f4SDimitry Andric void StmtPrinter::VisitOMPParallelMasterDirective( 718480093f4SDimitry Andric OMPParallelMasterDirective *Node) { 719480093f4SDimitry Andric Indent() << "#pragma omp parallel master"; 720480093f4SDimitry Andric PrintOMPExecutableDirective(Node); 721480093f4SDimitry Andric } 722480093f4SDimitry Andric 7230b57cec5SDimitry Andric void StmtPrinter::VisitOMPParallelSectionsDirective( 7240b57cec5SDimitry Andric OMPParallelSectionsDirective *Node) { 7250b57cec5SDimitry Andric Indent() << "#pragma omp parallel sections"; 7260b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 7270b57cec5SDimitry Andric } 7280b57cec5SDimitry Andric 7290b57cec5SDimitry Andric void StmtPrinter::VisitOMPTaskDirective(OMPTaskDirective *Node) { 7300b57cec5SDimitry Andric Indent() << "#pragma omp task"; 7310b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 7320b57cec5SDimitry Andric } 7330b57cec5SDimitry Andric 7340b57cec5SDimitry Andric void StmtPrinter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *Node) { 7350b57cec5SDimitry Andric Indent() << "#pragma omp taskyield"; 7360b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 7370b57cec5SDimitry Andric } 7380b57cec5SDimitry Andric 7390b57cec5SDimitry Andric void StmtPrinter::VisitOMPBarrierDirective(OMPBarrierDirective *Node) { 7400b57cec5SDimitry Andric Indent() << "#pragma omp barrier"; 7410b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 7420b57cec5SDimitry Andric } 7430b57cec5SDimitry Andric 7440b57cec5SDimitry Andric void StmtPrinter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *Node) { 7450b57cec5SDimitry Andric Indent() << "#pragma omp taskwait"; 7460b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 7470b57cec5SDimitry Andric } 7480b57cec5SDimitry Andric 7490b57cec5SDimitry Andric void StmtPrinter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *Node) { 7500b57cec5SDimitry Andric Indent() << "#pragma omp taskgroup"; 7510b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 7520b57cec5SDimitry Andric } 7530b57cec5SDimitry Andric 7540b57cec5SDimitry Andric void StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) { 7550b57cec5SDimitry Andric Indent() << "#pragma omp flush"; 7560b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 7570b57cec5SDimitry Andric } 7580b57cec5SDimitry Andric 7590b57cec5SDimitry Andric void StmtPrinter::VisitOMPOrderedDirective(OMPOrderedDirective *Node) { 7600b57cec5SDimitry Andric Indent() << "#pragma omp ordered"; 7610b57cec5SDimitry Andric PrintOMPExecutableDirective(Node, Node->hasClausesOfKind<OMPDependClause>()); 7620b57cec5SDimitry Andric } 7630b57cec5SDimitry Andric 7640b57cec5SDimitry Andric void StmtPrinter::VisitOMPAtomicDirective(OMPAtomicDirective *Node) { 7650b57cec5SDimitry Andric Indent() << "#pragma omp atomic"; 7660b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 7670b57cec5SDimitry Andric } 7680b57cec5SDimitry Andric 7690b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetDirective(OMPTargetDirective *Node) { 7700b57cec5SDimitry Andric Indent() << "#pragma omp target"; 7710b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 7720b57cec5SDimitry Andric } 7730b57cec5SDimitry Andric 7740b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetDataDirective(OMPTargetDataDirective *Node) { 7750b57cec5SDimitry Andric Indent() << "#pragma omp target data"; 7760b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 7770b57cec5SDimitry Andric } 7780b57cec5SDimitry Andric 7790b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetEnterDataDirective( 7800b57cec5SDimitry Andric OMPTargetEnterDataDirective *Node) { 7810b57cec5SDimitry Andric Indent() << "#pragma omp target enter data"; 7820b57cec5SDimitry Andric PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true); 7830b57cec5SDimitry Andric } 7840b57cec5SDimitry Andric 7850b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetExitDataDirective( 7860b57cec5SDimitry Andric OMPTargetExitDataDirective *Node) { 7870b57cec5SDimitry Andric Indent() << "#pragma omp target exit data"; 7880b57cec5SDimitry Andric PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true); 7890b57cec5SDimitry Andric } 7900b57cec5SDimitry Andric 7910b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetParallelDirective( 7920b57cec5SDimitry Andric OMPTargetParallelDirective *Node) { 7930b57cec5SDimitry Andric Indent() << "#pragma omp target parallel"; 7940b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 7950b57cec5SDimitry Andric } 7960b57cec5SDimitry Andric 7970b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetParallelForDirective( 7980b57cec5SDimitry Andric OMPTargetParallelForDirective *Node) { 7990b57cec5SDimitry Andric Indent() << "#pragma omp target parallel for"; 8000b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 8010b57cec5SDimitry Andric } 8020b57cec5SDimitry Andric 8030b57cec5SDimitry Andric void StmtPrinter::VisitOMPTeamsDirective(OMPTeamsDirective *Node) { 8040b57cec5SDimitry Andric Indent() << "#pragma omp teams"; 8050b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 8060b57cec5SDimitry Andric } 8070b57cec5SDimitry Andric 8080b57cec5SDimitry Andric void StmtPrinter::VisitOMPCancellationPointDirective( 8090b57cec5SDimitry Andric OMPCancellationPointDirective *Node) { 8100b57cec5SDimitry Andric Indent() << "#pragma omp cancellation point " 8110b57cec5SDimitry Andric << getOpenMPDirectiveName(Node->getCancelRegion()); 8120b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 8130b57cec5SDimitry Andric } 8140b57cec5SDimitry Andric 8150b57cec5SDimitry Andric void StmtPrinter::VisitOMPCancelDirective(OMPCancelDirective *Node) { 8160b57cec5SDimitry Andric Indent() << "#pragma omp cancel " 8170b57cec5SDimitry Andric << getOpenMPDirectiveName(Node->getCancelRegion()); 8180b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 8190b57cec5SDimitry Andric } 8200b57cec5SDimitry Andric 8210b57cec5SDimitry Andric void StmtPrinter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *Node) { 8220b57cec5SDimitry Andric Indent() << "#pragma omp taskloop"; 8230b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 8240b57cec5SDimitry Andric } 8250b57cec5SDimitry Andric 8260b57cec5SDimitry Andric void StmtPrinter::VisitOMPTaskLoopSimdDirective( 8270b57cec5SDimitry Andric OMPTaskLoopSimdDirective *Node) { 8280b57cec5SDimitry Andric Indent() << "#pragma omp taskloop simd"; 8290b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 8300b57cec5SDimitry Andric } 8310b57cec5SDimitry Andric 832a7dea167SDimitry Andric void StmtPrinter::VisitOMPMasterTaskLoopDirective( 833a7dea167SDimitry Andric OMPMasterTaskLoopDirective *Node) { 834a7dea167SDimitry Andric Indent() << "#pragma omp master taskloop"; 835a7dea167SDimitry Andric PrintOMPExecutableDirective(Node); 836a7dea167SDimitry Andric } 837a7dea167SDimitry Andric 838a7dea167SDimitry Andric void StmtPrinter::VisitOMPMasterTaskLoopSimdDirective( 839a7dea167SDimitry Andric OMPMasterTaskLoopSimdDirective *Node) { 840a7dea167SDimitry Andric Indent() << "#pragma omp master taskloop simd"; 841a7dea167SDimitry Andric PrintOMPExecutableDirective(Node); 842a7dea167SDimitry Andric } 843a7dea167SDimitry Andric 844a7dea167SDimitry Andric void StmtPrinter::VisitOMPParallelMasterTaskLoopDirective( 845a7dea167SDimitry Andric OMPParallelMasterTaskLoopDirective *Node) { 846a7dea167SDimitry Andric Indent() << "#pragma omp parallel master taskloop"; 847a7dea167SDimitry Andric PrintOMPExecutableDirective(Node); 848a7dea167SDimitry Andric } 849a7dea167SDimitry Andric 850480093f4SDimitry Andric void StmtPrinter::VisitOMPParallelMasterTaskLoopSimdDirective( 851480093f4SDimitry Andric OMPParallelMasterTaskLoopSimdDirective *Node) { 852480093f4SDimitry Andric Indent() << "#pragma omp parallel master taskloop simd"; 853480093f4SDimitry Andric PrintOMPExecutableDirective(Node); 854480093f4SDimitry Andric } 855480093f4SDimitry Andric 8560b57cec5SDimitry Andric void StmtPrinter::VisitOMPDistributeDirective(OMPDistributeDirective *Node) { 8570b57cec5SDimitry Andric Indent() << "#pragma omp distribute"; 8580b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 8590b57cec5SDimitry Andric } 8600b57cec5SDimitry Andric 8610b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetUpdateDirective( 8620b57cec5SDimitry Andric OMPTargetUpdateDirective *Node) { 8630b57cec5SDimitry Andric Indent() << "#pragma omp target update"; 8640b57cec5SDimitry Andric PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true); 8650b57cec5SDimitry Andric } 8660b57cec5SDimitry Andric 8670b57cec5SDimitry Andric void StmtPrinter::VisitOMPDistributeParallelForDirective( 8680b57cec5SDimitry Andric OMPDistributeParallelForDirective *Node) { 8690b57cec5SDimitry Andric Indent() << "#pragma omp distribute parallel for"; 8700b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 8710b57cec5SDimitry Andric } 8720b57cec5SDimitry Andric 8730b57cec5SDimitry Andric void StmtPrinter::VisitOMPDistributeParallelForSimdDirective( 8740b57cec5SDimitry Andric OMPDistributeParallelForSimdDirective *Node) { 8750b57cec5SDimitry Andric Indent() << "#pragma omp distribute parallel for simd"; 8760b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 8770b57cec5SDimitry Andric } 8780b57cec5SDimitry Andric 8790b57cec5SDimitry Andric void StmtPrinter::VisitOMPDistributeSimdDirective( 8800b57cec5SDimitry Andric OMPDistributeSimdDirective *Node) { 8810b57cec5SDimitry Andric Indent() << "#pragma omp distribute simd"; 8820b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 8830b57cec5SDimitry Andric } 8840b57cec5SDimitry Andric 8850b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetParallelForSimdDirective( 8860b57cec5SDimitry Andric OMPTargetParallelForSimdDirective *Node) { 8870b57cec5SDimitry Andric Indent() << "#pragma omp target parallel for simd"; 8880b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 8890b57cec5SDimitry Andric } 8900b57cec5SDimitry Andric 8910b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *Node) { 8920b57cec5SDimitry Andric Indent() << "#pragma omp target simd"; 8930b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 8940b57cec5SDimitry Andric } 8950b57cec5SDimitry Andric 8960b57cec5SDimitry Andric void StmtPrinter::VisitOMPTeamsDistributeDirective( 8970b57cec5SDimitry Andric OMPTeamsDistributeDirective *Node) { 8980b57cec5SDimitry Andric Indent() << "#pragma omp teams distribute"; 8990b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 9000b57cec5SDimitry Andric } 9010b57cec5SDimitry Andric 9020b57cec5SDimitry Andric void StmtPrinter::VisitOMPTeamsDistributeSimdDirective( 9030b57cec5SDimitry Andric OMPTeamsDistributeSimdDirective *Node) { 9040b57cec5SDimitry Andric Indent() << "#pragma omp teams distribute simd"; 9050b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 9060b57cec5SDimitry Andric } 9070b57cec5SDimitry Andric 9080b57cec5SDimitry Andric void StmtPrinter::VisitOMPTeamsDistributeParallelForSimdDirective( 9090b57cec5SDimitry Andric OMPTeamsDistributeParallelForSimdDirective *Node) { 9100b57cec5SDimitry Andric Indent() << "#pragma omp teams distribute parallel for simd"; 9110b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 9120b57cec5SDimitry Andric } 9130b57cec5SDimitry Andric 9140b57cec5SDimitry Andric void StmtPrinter::VisitOMPTeamsDistributeParallelForDirective( 9150b57cec5SDimitry Andric OMPTeamsDistributeParallelForDirective *Node) { 9160b57cec5SDimitry Andric Indent() << "#pragma omp teams distribute parallel for"; 9170b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 9180b57cec5SDimitry Andric } 9190b57cec5SDimitry Andric 9200b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *Node) { 9210b57cec5SDimitry Andric Indent() << "#pragma omp target teams"; 9220b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 9230b57cec5SDimitry Andric } 9240b57cec5SDimitry Andric 9250b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetTeamsDistributeDirective( 9260b57cec5SDimitry Andric OMPTargetTeamsDistributeDirective *Node) { 9270b57cec5SDimitry Andric Indent() << "#pragma omp target teams distribute"; 9280b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 9290b57cec5SDimitry Andric } 9300b57cec5SDimitry Andric 9310b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForDirective( 9320b57cec5SDimitry Andric OMPTargetTeamsDistributeParallelForDirective *Node) { 9330b57cec5SDimitry Andric Indent() << "#pragma omp target teams distribute parallel for"; 9340b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 9350b57cec5SDimitry Andric } 9360b57cec5SDimitry Andric 9370b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForSimdDirective( 9380b57cec5SDimitry Andric OMPTargetTeamsDistributeParallelForSimdDirective *Node) { 9390b57cec5SDimitry Andric Indent() << "#pragma omp target teams distribute parallel for simd"; 9400b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 9410b57cec5SDimitry Andric } 9420b57cec5SDimitry Andric 9430b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetTeamsDistributeSimdDirective( 9440b57cec5SDimitry Andric OMPTargetTeamsDistributeSimdDirective *Node) { 9450b57cec5SDimitry Andric Indent() << "#pragma omp target teams distribute simd"; 9460b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 9470b57cec5SDimitry Andric } 9480b57cec5SDimitry Andric 9490b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 9500b57cec5SDimitry Andric // Expr printing methods. 9510b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 9520b57cec5SDimitry Andric 9530b57cec5SDimitry Andric void StmtPrinter::VisitSourceLocExpr(SourceLocExpr *Node) { 9540b57cec5SDimitry Andric OS << Node->getBuiltinStr() << "()"; 9550b57cec5SDimitry Andric } 9560b57cec5SDimitry Andric 9570b57cec5SDimitry Andric void StmtPrinter::VisitConstantExpr(ConstantExpr *Node) { 9580b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 9590b57cec5SDimitry Andric } 9600b57cec5SDimitry Andric 9610b57cec5SDimitry Andric void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) { 9620b57cec5SDimitry Andric if (const auto *OCED = dyn_cast<OMPCapturedExprDecl>(Node->getDecl())) { 9630b57cec5SDimitry Andric OCED->getInit()->IgnoreImpCasts()->printPretty(OS, nullptr, Policy); 9640b57cec5SDimitry Andric return; 9650b57cec5SDimitry Andric } 9660b57cec5SDimitry Andric if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 9670b57cec5SDimitry Andric Qualifier->print(OS, Policy); 9680b57cec5SDimitry Andric if (Node->hasTemplateKeyword()) 9690b57cec5SDimitry Andric OS << "template "; 9700b57cec5SDimitry Andric OS << Node->getNameInfo(); 9710b57cec5SDimitry Andric if (Node->hasExplicitTemplateArgs()) 9720b57cec5SDimitry Andric printTemplateArgumentList(OS, Node->template_arguments(), Policy); 9730b57cec5SDimitry Andric } 9740b57cec5SDimitry Andric 9750b57cec5SDimitry Andric void StmtPrinter::VisitDependentScopeDeclRefExpr( 9760b57cec5SDimitry Andric DependentScopeDeclRefExpr *Node) { 9770b57cec5SDimitry Andric if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 9780b57cec5SDimitry Andric Qualifier->print(OS, Policy); 9790b57cec5SDimitry Andric if (Node->hasTemplateKeyword()) 9800b57cec5SDimitry Andric OS << "template "; 9810b57cec5SDimitry Andric OS << Node->getNameInfo(); 9820b57cec5SDimitry Andric if (Node->hasExplicitTemplateArgs()) 9830b57cec5SDimitry Andric printTemplateArgumentList(OS, Node->template_arguments(), Policy); 9840b57cec5SDimitry Andric } 9850b57cec5SDimitry Andric 9860b57cec5SDimitry Andric void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) { 9870b57cec5SDimitry Andric if (Node->getQualifier()) 9880b57cec5SDimitry Andric Node->getQualifier()->print(OS, Policy); 9890b57cec5SDimitry Andric if (Node->hasTemplateKeyword()) 9900b57cec5SDimitry Andric OS << "template "; 9910b57cec5SDimitry Andric OS << Node->getNameInfo(); 9920b57cec5SDimitry Andric if (Node->hasExplicitTemplateArgs()) 9930b57cec5SDimitry Andric printTemplateArgumentList(OS, Node->template_arguments(), Policy); 9940b57cec5SDimitry Andric } 9950b57cec5SDimitry Andric 9960b57cec5SDimitry Andric static bool isImplicitSelf(const Expr *E) { 9970b57cec5SDimitry Andric if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) { 9980b57cec5SDimitry Andric if (const auto *PD = dyn_cast<ImplicitParamDecl>(DRE->getDecl())) { 9990b57cec5SDimitry Andric if (PD->getParameterKind() == ImplicitParamDecl::ObjCSelf && 10000b57cec5SDimitry Andric DRE->getBeginLoc().isInvalid()) 10010b57cec5SDimitry Andric return true; 10020b57cec5SDimitry Andric } 10030b57cec5SDimitry Andric } 10040b57cec5SDimitry Andric return false; 10050b57cec5SDimitry Andric } 10060b57cec5SDimitry Andric 10070b57cec5SDimitry Andric void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { 10080b57cec5SDimitry Andric if (Node->getBase()) { 10090b57cec5SDimitry Andric if (!Policy.SuppressImplicitBase || 10100b57cec5SDimitry Andric !isImplicitSelf(Node->getBase()->IgnoreImpCasts())) { 10110b57cec5SDimitry Andric PrintExpr(Node->getBase()); 10120b57cec5SDimitry Andric OS << (Node->isArrow() ? "->" : "."); 10130b57cec5SDimitry Andric } 10140b57cec5SDimitry Andric } 10150b57cec5SDimitry Andric OS << *Node->getDecl(); 10160b57cec5SDimitry Andric } 10170b57cec5SDimitry Andric 10180b57cec5SDimitry Andric void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) { 10190b57cec5SDimitry Andric if (Node->isSuperReceiver()) 10200b57cec5SDimitry Andric OS << "super."; 10210b57cec5SDimitry Andric else if (Node->isObjectReceiver() && Node->getBase()) { 10220b57cec5SDimitry Andric PrintExpr(Node->getBase()); 10230b57cec5SDimitry Andric OS << "."; 10240b57cec5SDimitry Andric } else if (Node->isClassReceiver() && Node->getClassReceiver()) { 10250b57cec5SDimitry Andric OS << Node->getClassReceiver()->getName() << "."; 10260b57cec5SDimitry Andric } 10270b57cec5SDimitry Andric 10280b57cec5SDimitry Andric if (Node->isImplicitProperty()) { 10290b57cec5SDimitry Andric if (const auto *Getter = Node->getImplicitPropertyGetter()) 10300b57cec5SDimitry Andric Getter->getSelector().print(OS); 10310b57cec5SDimitry Andric else 10320b57cec5SDimitry Andric OS << SelectorTable::getPropertyNameFromSetterSelector( 10330b57cec5SDimitry Andric Node->getImplicitPropertySetter()->getSelector()); 10340b57cec5SDimitry Andric } else 10350b57cec5SDimitry Andric OS << Node->getExplicitProperty()->getName(); 10360b57cec5SDimitry Andric } 10370b57cec5SDimitry Andric 10380b57cec5SDimitry Andric void StmtPrinter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node) { 10390b57cec5SDimitry Andric PrintExpr(Node->getBaseExpr()); 10400b57cec5SDimitry Andric OS << "["; 10410b57cec5SDimitry Andric PrintExpr(Node->getKeyExpr()); 10420b57cec5SDimitry Andric OS << "]"; 10430b57cec5SDimitry Andric } 10440b57cec5SDimitry Andric 10450b57cec5SDimitry Andric void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) { 10460b57cec5SDimitry Andric OS << PredefinedExpr::getIdentKindName(Node->getIdentKind()); 10470b57cec5SDimitry Andric } 10480b57cec5SDimitry Andric 10490b57cec5SDimitry Andric void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) { 10500b57cec5SDimitry Andric unsigned value = Node->getValue(); 10510b57cec5SDimitry Andric 10520b57cec5SDimitry Andric switch (Node->getKind()) { 10530b57cec5SDimitry Andric case CharacterLiteral::Ascii: break; // no prefix. 10540b57cec5SDimitry Andric case CharacterLiteral::Wide: OS << 'L'; break; 10550b57cec5SDimitry Andric case CharacterLiteral::UTF8: OS << "u8"; break; 10560b57cec5SDimitry Andric case CharacterLiteral::UTF16: OS << 'u'; break; 10570b57cec5SDimitry Andric case CharacterLiteral::UTF32: OS << 'U'; break; 10580b57cec5SDimitry Andric } 10590b57cec5SDimitry Andric 10600b57cec5SDimitry Andric switch (value) { 10610b57cec5SDimitry Andric case '\\': 10620b57cec5SDimitry Andric OS << "'\\\\'"; 10630b57cec5SDimitry Andric break; 10640b57cec5SDimitry Andric case '\'': 10650b57cec5SDimitry Andric OS << "'\\''"; 10660b57cec5SDimitry Andric break; 10670b57cec5SDimitry Andric case '\a': 10680b57cec5SDimitry Andric // TODO: K&R: the meaning of '\\a' is different in traditional C 10690b57cec5SDimitry Andric OS << "'\\a'"; 10700b57cec5SDimitry Andric break; 10710b57cec5SDimitry Andric case '\b': 10720b57cec5SDimitry Andric OS << "'\\b'"; 10730b57cec5SDimitry Andric break; 10740b57cec5SDimitry Andric // Nonstandard escape sequence. 10750b57cec5SDimitry Andric /*case '\e': 10760b57cec5SDimitry Andric OS << "'\\e'"; 10770b57cec5SDimitry Andric break;*/ 10780b57cec5SDimitry Andric case '\f': 10790b57cec5SDimitry Andric OS << "'\\f'"; 10800b57cec5SDimitry Andric break; 10810b57cec5SDimitry Andric case '\n': 10820b57cec5SDimitry Andric OS << "'\\n'"; 10830b57cec5SDimitry Andric break; 10840b57cec5SDimitry Andric case '\r': 10850b57cec5SDimitry Andric OS << "'\\r'"; 10860b57cec5SDimitry Andric break; 10870b57cec5SDimitry Andric case '\t': 10880b57cec5SDimitry Andric OS << "'\\t'"; 10890b57cec5SDimitry Andric break; 10900b57cec5SDimitry Andric case '\v': 10910b57cec5SDimitry Andric OS << "'\\v'"; 10920b57cec5SDimitry Andric break; 10930b57cec5SDimitry Andric default: 10940b57cec5SDimitry Andric // A character literal might be sign-extended, which 10950b57cec5SDimitry Andric // would result in an invalid \U escape sequence. 10960b57cec5SDimitry Andric // FIXME: multicharacter literals such as '\xFF\xFF\xFF\xFF' 10970b57cec5SDimitry Andric // are not correctly handled. 10980b57cec5SDimitry Andric if ((value & ~0xFFu) == ~0xFFu && Node->getKind() == CharacterLiteral::Ascii) 10990b57cec5SDimitry Andric value &= 0xFFu; 11000b57cec5SDimitry Andric if (value < 256 && isPrintable((unsigned char)value)) 11010b57cec5SDimitry Andric OS << "'" << (char)value << "'"; 11020b57cec5SDimitry Andric else if (value < 256) 11030b57cec5SDimitry Andric OS << "'\\x" << llvm::format("%02x", value) << "'"; 11040b57cec5SDimitry Andric else if (value <= 0xFFFF) 11050b57cec5SDimitry Andric OS << "'\\u" << llvm::format("%04x", value) << "'"; 11060b57cec5SDimitry Andric else 11070b57cec5SDimitry Andric OS << "'\\U" << llvm::format("%08x", value) << "'"; 11080b57cec5SDimitry Andric } 11090b57cec5SDimitry Andric } 11100b57cec5SDimitry Andric 11110b57cec5SDimitry Andric /// Prints the given expression using the original source text. Returns true on 11120b57cec5SDimitry Andric /// success, false otherwise. 11130b57cec5SDimitry Andric static bool printExprAsWritten(raw_ostream &OS, Expr *E, 11140b57cec5SDimitry Andric const ASTContext *Context) { 11150b57cec5SDimitry Andric if (!Context) 11160b57cec5SDimitry Andric return false; 11170b57cec5SDimitry Andric bool Invalid = false; 11180b57cec5SDimitry Andric StringRef Source = Lexer::getSourceText( 11190b57cec5SDimitry Andric CharSourceRange::getTokenRange(E->getSourceRange()), 11200b57cec5SDimitry Andric Context->getSourceManager(), Context->getLangOpts(), &Invalid); 11210b57cec5SDimitry Andric if (!Invalid) { 11220b57cec5SDimitry Andric OS << Source; 11230b57cec5SDimitry Andric return true; 11240b57cec5SDimitry Andric } 11250b57cec5SDimitry Andric return false; 11260b57cec5SDimitry Andric } 11270b57cec5SDimitry Andric 11280b57cec5SDimitry Andric void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) { 11290b57cec5SDimitry Andric if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context)) 11300b57cec5SDimitry Andric return; 11310b57cec5SDimitry Andric bool isSigned = Node->getType()->isSignedIntegerType(); 11320b57cec5SDimitry Andric OS << Node->getValue().toString(10, isSigned); 11330b57cec5SDimitry Andric 11340b57cec5SDimitry Andric // Emit suffixes. Integer literals are always a builtin integer type. 1135a7dea167SDimitry Andric switch (Node->getType()->castAs<BuiltinType>()->getKind()) { 11360b57cec5SDimitry Andric default: llvm_unreachable("Unexpected type for integer literal!"); 11370b57cec5SDimitry Andric case BuiltinType::Char_S: 11380b57cec5SDimitry Andric case BuiltinType::Char_U: OS << "i8"; break; 11390b57cec5SDimitry Andric case BuiltinType::UChar: OS << "Ui8"; break; 11400b57cec5SDimitry Andric case BuiltinType::Short: OS << "i16"; break; 11410b57cec5SDimitry Andric case BuiltinType::UShort: OS << "Ui16"; break; 11420b57cec5SDimitry Andric case BuiltinType::Int: break; // no suffix. 11430b57cec5SDimitry Andric case BuiltinType::UInt: OS << 'U'; break; 11440b57cec5SDimitry Andric case BuiltinType::Long: OS << 'L'; break; 11450b57cec5SDimitry Andric case BuiltinType::ULong: OS << "UL"; break; 11460b57cec5SDimitry Andric case BuiltinType::LongLong: OS << "LL"; break; 11470b57cec5SDimitry Andric case BuiltinType::ULongLong: OS << "ULL"; break; 11480b57cec5SDimitry Andric } 11490b57cec5SDimitry Andric } 11500b57cec5SDimitry Andric 11510b57cec5SDimitry Andric void StmtPrinter::VisitFixedPointLiteral(FixedPointLiteral *Node) { 11520b57cec5SDimitry Andric if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context)) 11530b57cec5SDimitry Andric return; 11540b57cec5SDimitry Andric OS << Node->getValueAsString(/*Radix=*/10); 11550b57cec5SDimitry Andric 1156a7dea167SDimitry Andric switch (Node->getType()->castAs<BuiltinType>()->getKind()) { 11570b57cec5SDimitry Andric default: llvm_unreachable("Unexpected type for fixed point literal!"); 11580b57cec5SDimitry Andric case BuiltinType::ShortFract: OS << "hr"; break; 11590b57cec5SDimitry Andric case BuiltinType::ShortAccum: OS << "hk"; break; 11600b57cec5SDimitry Andric case BuiltinType::UShortFract: OS << "uhr"; break; 11610b57cec5SDimitry Andric case BuiltinType::UShortAccum: OS << "uhk"; break; 11620b57cec5SDimitry Andric case BuiltinType::Fract: OS << "r"; break; 11630b57cec5SDimitry Andric case BuiltinType::Accum: OS << "k"; break; 11640b57cec5SDimitry Andric case BuiltinType::UFract: OS << "ur"; break; 11650b57cec5SDimitry Andric case BuiltinType::UAccum: OS << "uk"; break; 11660b57cec5SDimitry Andric case BuiltinType::LongFract: OS << "lr"; break; 11670b57cec5SDimitry Andric case BuiltinType::LongAccum: OS << "lk"; break; 11680b57cec5SDimitry Andric case BuiltinType::ULongFract: OS << "ulr"; break; 11690b57cec5SDimitry Andric case BuiltinType::ULongAccum: OS << "ulk"; break; 11700b57cec5SDimitry Andric } 11710b57cec5SDimitry Andric } 11720b57cec5SDimitry Andric 11730b57cec5SDimitry Andric static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node, 11740b57cec5SDimitry Andric bool PrintSuffix) { 11750b57cec5SDimitry Andric SmallString<16> Str; 11760b57cec5SDimitry Andric Node->getValue().toString(Str); 11770b57cec5SDimitry Andric OS << Str; 11780b57cec5SDimitry Andric if (Str.find_first_not_of("-0123456789") == StringRef::npos) 11790b57cec5SDimitry Andric OS << '.'; // Trailing dot in order to separate from ints. 11800b57cec5SDimitry Andric 11810b57cec5SDimitry Andric if (!PrintSuffix) 11820b57cec5SDimitry Andric return; 11830b57cec5SDimitry Andric 11840b57cec5SDimitry Andric // Emit suffixes. Float literals are always a builtin float type. 1185a7dea167SDimitry Andric switch (Node->getType()->castAs<BuiltinType>()->getKind()) { 11860b57cec5SDimitry Andric default: llvm_unreachable("Unexpected type for float literal!"); 11870b57cec5SDimitry Andric case BuiltinType::Half: break; // FIXME: suffix? 11880b57cec5SDimitry Andric case BuiltinType::Double: break; // no suffix. 11890b57cec5SDimitry Andric case BuiltinType::Float16: OS << "F16"; break; 11900b57cec5SDimitry Andric case BuiltinType::Float: OS << 'F'; break; 11910b57cec5SDimitry Andric case BuiltinType::LongDouble: OS << 'L'; break; 11920b57cec5SDimitry Andric case BuiltinType::Float128: OS << 'Q'; break; 11930b57cec5SDimitry Andric } 11940b57cec5SDimitry Andric } 11950b57cec5SDimitry Andric 11960b57cec5SDimitry Andric void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) { 11970b57cec5SDimitry Andric if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context)) 11980b57cec5SDimitry Andric return; 11990b57cec5SDimitry Andric PrintFloatingLiteral(OS, Node, /*PrintSuffix=*/true); 12000b57cec5SDimitry Andric } 12010b57cec5SDimitry Andric 12020b57cec5SDimitry Andric void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) { 12030b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 12040b57cec5SDimitry Andric OS << "i"; 12050b57cec5SDimitry Andric } 12060b57cec5SDimitry Andric 12070b57cec5SDimitry Andric void StmtPrinter::VisitStringLiteral(StringLiteral *Str) { 12080b57cec5SDimitry Andric Str->outputString(OS); 12090b57cec5SDimitry Andric } 12100b57cec5SDimitry Andric 12110b57cec5SDimitry Andric void StmtPrinter::VisitParenExpr(ParenExpr *Node) { 12120b57cec5SDimitry Andric OS << "("; 12130b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 12140b57cec5SDimitry Andric OS << ")"; 12150b57cec5SDimitry Andric } 12160b57cec5SDimitry Andric 12170b57cec5SDimitry Andric void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) { 12180b57cec5SDimitry Andric if (!Node->isPostfix()) { 12190b57cec5SDimitry Andric OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 12200b57cec5SDimitry Andric 12210b57cec5SDimitry Andric // Print a space if this is an "identifier operator" like __real, or if 12220b57cec5SDimitry Andric // it might be concatenated incorrectly like '+'. 12230b57cec5SDimitry Andric switch (Node->getOpcode()) { 12240b57cec5SDimitry Andric default: break; 12250b57cec5SDimitry Andric case UO_Real: 12260b57cec5SDimitry Andric case UO_Imag: 12270b57cec5SDimitry Andric case UO_Extension: 12280b57cec5SDimitry Andric OS << ' '; 12290b57cec5SDimitry Andric break; 12300b57cec5SDimitry Andric case UO_Plus: 12310b57cec5SDimitry Andric case UO_Minus: 12320b57cec5SDimitry Andric if (isa<UnaryOperator>(Node->getSubExpr())) 12330b57cec5SDimitry Andric OS << ' '; 12340b57cec5SDimitry Andric break; 12350b57cec5SDimitry Andric } 12360b57cec5SDimitry Andric } 12370b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 12380b57cec5SDimitry Andric 12390b57cec5SDimitry Andric if (Node->isPostfix()) 12400b57cec5SDimitry Andric OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 12410b57cec5SDimitry Andric } 12420b57cec5SDimitry Andric 12430b57cec5SDimitry Andric void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) { 12440b57cec5SDimitry Andric OS << "__builtin_offsetof("; 12450b57cec5SDimitry Andric Node->getTypeSourceInfo()->getType().print(OS, Policy); 12460b57cec5SDimitry Andric OS << ", "; 12470b57cec5SDimitry Andric bool PrintedSomething = false; 12480b57cec5SDimitry Andric for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) { 12490b57cec5SDimitry Andric OffsetOfNode ON = Node->getComponent(i); 12500b57cec5SDimitry Andric if (ON.getKind() == OffsetOfNode::Array) { 12510b57cec5SDimitry Andric // Array node 12520b57cec5SDimitry Andric OS << "["; 12530b57cec5SDimitry Andric PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex())); 12540b57cec5SDimitry Andric OS << "]"; 12550b57cec5SDimitry Andric PrintedSomething = true; 12560b57cec5SDimitry Andric continue; 12570b57cec5SDimitry Andric } 12580b57cec5SDimitry Andric 12590b57cec5SDimitry Andric // Skip implicit base indirections. 12600b57cec5SDimitry Andric if (ON.getKind() == OffsetOfNode::Base) 12610b57cec5SDimitry Andric continue; 12620b57cec5SDimitry Andric 12630b57cec5SDimitry Andric // Field or identifier node. 12640b57cec5SDimitry Andric IdentifierInfo *Id = ON.getFieldName(); 12650b57cec5SDimitry Andric if (!Id) 12660b57cec5SDimitry Andric continue; 12670b57cec5SDimitry Andric 12680b57cec5SDimitry Andric if (PrintedSomething) 12690b57cec5SDimitry Andric OS << "."; 12700b57cec5SDimitry Andric else 12710b57cec5SDimitry Andric PrintedSomething = true; 12720b57cec5SDimitry Andric OS << Id->getName(); 12730b57cec5SDimitry Andric } 12740b57cec5SDimitry Andric OS << ")"; 12750b57cec5SDimitry Andric } 12760b57cec5SDimitry Andric 12770b57cec5SDimitry Andric void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node){ 12780b57cec5SDimitry Andric switch(Node->getKind()) { 12790b57cec5SDimitry Andric case UETT_SizeOf: 12800b57cec5SDimitry Andric OS << "sizeof"; 12810b57cec5SDimitry Andric break; 12820b57cec5SDimitry Andric case UETT_AlignOf: 12830b57cec5SDimitry Andric if (Policy.Alignof) 12840b57cec5SDimitry Andric OS << "alignof"; 12850b57cec5SDimitry Andric else if (Policy.UnderscoreAlignof) 12860b57cec5SDimitry Andric OS << "_Alignof"; 12870b57cec5SDimitry Andric else 12880b57cec5SDimitry Andric OS << "__alignof"; 12890b57cec5SDimitry Andric break; 12900b57cec5SDimitry Andric case UETT_PreferredAlignOf: 12910b57cec5SDimitry Andric OS << "__alignof"; 12920b57cec5SDimitry Andric break; 12930b57cec5SDimitry Andric case UETT_VecStep: 12940b57cec5SDimitry Andric OS << "vec_step"; 12950b57cec5SDimitry Andric break; 12960b57cec5SDimitry Andric case UETT_OpenMPRequiredSimdAlign: 12970b57cec5SDimitry Andric OS << "__builtin_omp_required_simd_align"; 12980b57cec5SDimitry Andric break; 12990b57cec5SDimitry Andric } 13000b57cec5SDimitry Andric if (Node->isArgumentType()) { 13010b57cec5SDimitry Andric OS << '('; 13020b57cec5SDimitry Andric Node->getArgumentType().print(OS, Policy); 13030b57cec5SDimitry Andric OS << ')'; 13040b57cec5SDimitry Andric } else { 13050b57cec5SDimitry Andric OS << " "; 13060b57cec5SDimitry Andric PrintExpr(Node->getArgumentExpr()); 13070b57cec5SDimitry Andric } 13080b57cec5SDimitry Andric } 13090b57cec5SDimitry Andric 13100b57cec5SDimitry Andric void StmtPrinter::VisitGenericSelectionExpr(GenericSelectionExpr *Node) { 13110b57cec5SDimitry Andric OS << "_Generic("; 13120b57cec5SDimitry Andric PrintExpr(Node->getControllingExpr()); 1313480093f4SDimitry Andric for (const GenericSelectionExpr::Association Assoc : Node->associations()) { 13140b57cec5SDimitry Andric OS << ", "; 13150b57cec5SDimitry Andric QualType T = Assoc.getType(); 13160b57cec5SDimitry Andric if (T.isNull()) 13170b57cec5SDimitry Andric OS << "default"; 13180b57cec5SDimitry Andric else 13190b57cec5SDimitry Andric T.print(OS, Policy); 13200b57cec5SDimitry Andric OS << ": "; 13210b57cec5SDimitry Andric PrintExpr(Assoc.getAssociationExpr()); 13220b57cec5SDimitry Andric } 13230b57cec5SDimitry Andric OS << ")"; 13240b57cec5SDimitry Andric } 13250b57cec5SDimitry Andric 13260b57cec5SDimitry Andric void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) { 13270b57cec5SDimitry Andric PrintExpr(Node->getLHS()); 13280b57cec5SDimitry Andric OS << "["; 13290b57cec5SDimitry Andric PrintExpr(Node->getRHS()); 13300b57cec5SDimitry Andric OS << "]"; 13310b57cec5SDimitry Andric } 13320b57cec5SDimitry Andric 13330b57cec5SDimitry Andric void StmtPrinter::VisitOMPArraySectionExpr(OMPArraySectionExpr *Node) { 13340b57cec5SDimitry Andric PrintExpr(Node->getBase()); 13350b57cec5SDimitry Andric OS << "["; 13360b57cec5SDimitry Andric if (Node->getLowerBound()) 13370b57cec5SDimitry Andric PrintExpr(Node->getLowerBound()); 13380b57cec5SDimitry Andric if (Node->getColonLoc().isValid()) { 13390b57cec5SDimitry Andric OS << ":"; 13400b57cec5SDimitry Andric if (Node->getLength()) 13410b57cec5SDimitry Andric PrintExpr(Node->getLength()); 13420b57cec5SDimitry Andric } 13430b57cec5SDimitry Andric OS << "]"; 13440b57cec5SDimitry Andric } 13450b57cec5SDimitry Andric 13460b57cec5SDimitry Andric void StmtPrinter::PrintCallArgs(CallExpr *Call) { 13470b57cec5SDimitry Andric for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) { 13480b57cec5SDimitry Andric if (isa<CXXDefaultArgExpr>(Call->getArg(i))) { 13490b57cec5SDimitry Andric // Don't print any defaulted arguments 13500b57cec5SDimitry Andric break; 13510b57cec5SDimitry Andric } 13520b57cec5SDimitry Andric 13530b57cec5SDimitry Andric if (i) OS << ", "; 13540b57cec5SDimitry Andric PrintExpr(Call->getArg(i)); 13550b57cec5SDimitry Andric } 13560b57cec5SDimitry Andric } 13570b57cec5SDimitry Andric 13580b57cec5SDimitry Andric void StmtPrinter::VisitCallExpr(CallExpr *Call) { 13590b57cec5SDimitry Andric PrintExpr(Call->getCallee()); 13600b57cec5SDimitry Andric OS << "("; 13610b57cec5SDimitry Andric PrintCallArgs(Call); 13620b57cec5SDimitry Andric OS << ")"; 13630b57cec5SDimitry Andric } 13640b57cec5SDimitry Andric 13650b57cec5SDimitry Andric static bool isImplicitThis(const Expr *E) { 13660b57cec5SDimitry Andric if (const auto *TE = dyn_cast<CXXThisExpr>(E)) 13670b57cec5SDimitry Andric return TE->isImplicit(); 13680b57cec5SDimitry Andric return false; 13690b57cec5SDimitry Andric } 13700b57cec5SDimitry Andric 13710b57cec5SDimitry Andric void StmtPrinter::VisitMemberExpr(MemberExpr *Node) { 13720b57cec5SDimitry Andric if (!Policy.SuppressImplicitBase || !isImplicitThis(Node->getBase())) { 13730b57cec5SDimitry Andric PrintExpr(Node->getBase()); 13740b57cec5SDimitry Andric 13750b57cec5SDimitry Andric auto *ParentMember = dyn_cast<MemberExpr>(Node->getBase()); 13760b57cec5SDimitry Andric FieldDecl *ParentDecl = 13770b57cec5SDimitry Andric ParentMember ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl()) 13780b57cec5SDimitry Andric : nullptr; 13790b57cec5SDimitry Andric 13800b57cec5SDimitry Andric if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion()) 13810b57cec5SDimitry Andric OS << (Node->isArrow() ? "->" : "."); 13820b57cec5SDimitry Andric } 13830b57cec5SDimitry Andric 13840b57cec5SDimitry Andric if (auto *FD = dyn_cast<FieldDecl>(Node->getMemberDecl())) 13850b57cec5SDimitry Andric if (FD->isAnonymousStructOrUnion()) 13860b57cec5SDimitry Andric return; 13870b57cec5SDimitry Andric 13880b57cec5SDimitry Andric if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 13890b57cec5SDimitry Andric Qualifier->print(OS, Policy); 13900b57cec5SDimitry Andric if (Node->hasTemplateKeyword()) 13910b57cec5SDimitry Andric OS << "template "; 13920b57cec5SDimitry Andric OS << Node->getMemberNameInfo(); 13930b57cec5SDimitry Andric if (Node->hasExplicitTemplateArgs()) 13940b57cec5SDimitry Andric printTemplateArgumentList(OS, Node->template_arguments(), Policy); 13950b57cec5SDimitry Andric } 13960b57cec5SDimitry Andric 13970b57cec5SDimitry Andric void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) { 13980b57cec5SDimitry Andric PrintExpr(Node->getBase()); 13990b57cec5SDimitry Andric OS << (Node->isArrow() ? "->isa" : ".isa"); 14000b57cec5SDimitry Andric } 14010b57cec5SDimitry Andric 14020b57cec5SDimitry Andric void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) { 14030b57cec5SDimitry Andric PrintExpr(Node->getBase()); 14040b57cec5SDimitry Andric OS << "."; 14050b57cec5SDimitry Andric OS << Node->getAccessor().getName(); 14060b57cec5SDimitry Andric } 14070b57cec5SDimitry Andric 14080b57cec5SDimitry Andric void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) { 14090b57cec5SDimitry Andric OS << '('; 14100b57cec5SDimitry Andric Node->getTypeAsWritten().print(OS, Policy); 14110b57cec5SDimitry Andric OS << ')'; 14120b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 14130b57cec5SDimitry Andric } 14140b57cec5SDimitry Andric 14150b57cec5SDimitry Andric void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) { 14160b57cec5SDimitry Andric OS << '('; 14170b57cec5SDimitry Andric Node->getType().print(OS, Policy); 14180b57cec5SDimitry Andric OS << ')'; 14190b57cec5SDimitry Andric PrintExpr(Node->getInitializer()); 14200b57cec5SDimitry Andric } 14210b57cec5SDimitry Andric 14220b57cec5SDimitry Andric void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) { 14230b57cec5SDimitry Andric // No need to print anything, simply forward to the subexpression. 14240b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 14250b57cec5SDimitry Andric } 14260b57cec5SDimitry Andric 14270b57cec5SDimitry Andric void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) { 14280b57cec5SDimitry Andric PrintExpr(Node->getLHS()); 14290b57cec5SDimitry Andric OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 14300b57cec5SDimitry Andric PrintExpr(Node->getRHS()); 14310b57cec5SDimitry Andric } 14320b57cec5SDimitry Andric 14330b57cec5SDimitry Andric void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) { 14340b57cec5SDimitry Andric PrintExpr(Node->getLHS()); 14350b57cec5SDimitry Andric OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 14360b57cec5SDimitry Andric PrintExpr(Node->getRHS()); 14370b57cec5SDimitry Andric } 14380b57cec5SDimitry Andric 14390b57cec5SDimitry Andric void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) { 14400b57cec5SDimitry Andric PrintExpr(Node->getCond()); 14410b57cec5SDimitry Andric OS << " ? "; 14420b57cec5SDimitry Andric PrintExpr(Node->getLHS()); 14430b57cec5SDimitry Andric OS << " : "; 14440b57cec5SDimitry Andric PrintExpr(Node->getRHS()); 14450b57cec5SDimitry Andric } 14460b57cec5SDimitry Andric 14470b57cec5SDimitry Andric // GNU extensions. 14480b57cec5SDimitry Andric 14490b57cec5SDimitry Andric void 14500b57cec5SDimitry Andric StmtPrinter::VisitBinaryConditionalOperator(BinaryConditionalOperator *Node) { 14510b57cec5SDimitry Andric PrintExpr(Node->getCommon()); 14520b57cec5SDimitry Andric OS << " ?: "; 14530b57cec5SDimitry Andric PrintExpr(Node->getFalseExpr()); 14540b57cec5SDimitry Andric } 14550b57cec5SDimitry Andric 14560b57cec5SDimitry Andric void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) { 14570b57cec5SDimitry Andric OS << "&&" << Node->getLabel()->getName(); 14580b57cec5SDimitry Andric } 14590b57cec5SDimitry Andric 14600b57cec5SDimitry Andric void StmtPrinter::VisitStmtExpr(StmtExpr *E) { 14610b57cec5SDimitry Andric OS << "("; 14620b57cec5SDimitry Andric PrintRawCompoundStmt(E->getSubStmt()); 14630b57cec5SDimitry Andric OS << ")"; 14640b57cec5SDimitry Andric } 14650b57cec5SDimitry Andric 14660b57cec5SDimitry Andric void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) { 14670b57cec5SDimitry Andric OS << "__builtin_choose_expr("; 14680b57cec5SDimitry Andric PrintExpr(Node->getCond()); 14690b57cec5SDimitry Andric OS << ", "; 14700b57cec5SDimitry Andric PrintExpr(Node->getLHS()); 14710b57cec5SDimitry Andric OS << ", "; 14720b57cec5SDimitry Andric PrintExpr(Node->getRHS()); 14730b57cec5SDimitry Andric OS << ")"; 14740b57cec5SDimitry Andric } 14750b57cec5SDimitry Andric 14760b57cec5SDimitry Andric void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) { 14770b57cec5SDimitry Andric OS << "__null"; 14780b57cec5SDimitry Andric } 14790b57cec5SDimitry Andric 14800b57cec5SDimitry Andric void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) { 14810b57cec5SDimitry Andric OS << "__builtin_shufflevector("; 14820b57cec5SDimitry Andric for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) { 14830b57cec5SDimitry Andric if (i) OS << ", "; 14840b57cec5SDimitry Andric PrintExpr(Node->getExpr(i)); 14850b57cec5SDimitry Andric } 14860b57cec5SDimitry Andric OS << ")"; 14870b57cec5SDimitry Andric } 14880b57cec5SDimitry Andric 14890b57cec5SDimitry Andric void StmtPrinter::VisitConvertVectorExpr(ConvertVectorExpr *Node) { 14900b57cec5SDimitry Andric OS << "__builtin_convertvector("; 14910b57cec5SDimitry Andric PrintExpr(Node->getSrcExpr()); 14920b57cec5SDimitry Andric OS << ", "; 14930b57cec5SDimitry Andric Node->getType().print(OS, Policy); 14940b57cec5SDimitry Andric OS << ")"; 14950b57cec5SDimitry Andric } 14960b57cec5SDimitry Andric 14970b57cec5SDimitry Andric void StmtPrinter::VisitInitListExpr(InitListExpr* Node) { 14980b57cec5SDimitry Andric if (Node->getSyntacticForm()) { 14990b57cec5SDimitry Andric Visit(Node->getSyntacticForm()); 15000b57cec5SDimitry Andric return; 15010b57cec5SDimitry Andric } 15020b57cec5SDimitry Andric 15030b57cec5SDimitry Andric OS << "{"; 15040b57cec5SDimitry Andric for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) { 15050b57cec5SDimitry Andric if (i) OS << ", "; 15060b57cec5SDimitry Andric if (Node->getInit(i)) 15070b57cec5SDimitry Andric PrintExpr(Node->getInit(i)); 15080b57cec5SDimitry Andric else 15090b57cec5SDimitry Andric OS << "{}"; 15100b57cec5SDimitry Andric } 15110b57cec5SDimitry Andric OS << "}"; 15120b57cec5SDimitry Andric } 15130b57cec5SDimitry Andric 15140b57cec5SDimitry Andric void StmtPrinter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *Node) { 15150b57cec5SDimitry Andric // There's no way to express this expression in any of our supported 15160b57cec5SDimitry Andric // languages, so just emit something terse and (hopefully) clear. 15170b57cec5SDimitry Andric OS << "{"; 15180b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 15190b57cec5SDimitry Andric OS << "}"; 15200b57cec5SDimitry Andric } 15210b57cec5SDimitry Andric 15220b57cec5SDimitry Andric void StmtPrinter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *Node) { 15230b57cec5SDimitry Andric OS << "*"; 15240b57cec5SDimitry Andric } 15250b57cec5SDimitry Andric 15260b57cec5SDimitry Andric void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) { 15270b57cec5SDimitry Andric OS << "("; 15280b57cec5SDimitry Andric for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) { 15290b57cec5SDimitry Andric if (i) OS << ", "; 15300b57cec5SDimitry Andric PrintExpr(Node->getExpr(i)); 15310b57cec5SDimitry Andric } 15320b57cec5SDimitry Andric OS << ")"; 15330b57cec5SDimitry Andric } 15340b57cec5SDimitry Andric 15350b57cec5SDimitry Andric void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) { 15360b57cec5SDimitry Andric bool NeedsEquals = true; 15370b57cec5SDimitry Andric for (const DesignatedInitExpr::Designator &D : Node->designators()) { 15380b57cec5SDimitry Andric if (D.isFieldDesignator()) { 15390b57cec5SDimitry Andric if (D.getDotLoc().isInvalid()) { 15400b57cec5SDimitry Andric if (IdentifierInfo *II = D.getFieldName()) { 15410b57cec5SDimitry Andric OS << II->getName() << ":"; 15420b57cec5SDimitry Andric NeedsEquals = false; 15430b57cec5SDimitry Andric } 15440b57cec5SDimitry Andric } else { 15450b57cec5SDimitry Andric OS << "." << D.getFieldName()->getName(); 15460b57cec5SDimitry Andric } 15470b57cec5SDimitry Andric } else { 15480b57cec5SDimitry Andric OS << "["; 15490b57cec5SDimitry Andric if (D.isArrayDesignator()) { 15500b57cec5SDimitry Andric PrintExpr(Node->getArrayIndex(D)); 15510b57cec5SDimitry Andric } else { 15520b57cec5SDimitry Andric PrintExpr(Node->getArrayRangeStart(D)); 15530b57cec5SDimitry Andric OS << " ... "; 15540b57cec5SDimitry Andric PrintExpr(Node->getArrayRangeEnd(D)); 15550b57cec5SDimitry Andric } 15560b57cec5SDimitry Andric OS << "]"; 15570b57cec5SDimitry Andric } 15580b57cec5SDimitry Andric } 15590b57cec5SDimitry Andric 15600b57cec5SDimitry Andric if (NeedsEquals) 15610b57cec5SDimitry Andric OS << " = "; 15620b57cec5SDimitry Andric else 15630b57cec5SDimitry Andric OS << " "; 15640b57cec5SDimitry Andric PrintExpr(Node->getInit()); 15650b57cec5SDimitry Andric } 15660b57cec5SDimitry Andric 15670b57cec5SDimitry Andric void StmtPrinter::VisitDesignatedInitUpdateExpr( 15680b57cec5SDimitry Andric DesignatedInitUpdateExpr *Node) { 15690b57cec5SDimitry Andric OS << "{"; 15700b57cec5SDimitry Andric OS << "/*base*/"; 15710b57cec5SDimitry Andric PrintExpr(Node->getBase()); 15720b57cec5SDimitry Andric OS << ", "; 15730b57cec5SDimitry Andric 15740b57cec5SDimitry Andric OS << "/*updater*/"; 15750b57cec5SDimitry Andric PrintExpr(Node->getUpdater()); 15760b57cec5SDimitry Andric OS << "}"; 15770b57cec5SDimitry Andric } 15780b57cec5SDimitry Andric 15790b57cec5SDimitry Andric void StmtPrinter::VisitNoInitExpr(NoInitExpr *Node) { 15800b57cec5SDimitry Andric OS << "/*no init*/"; 15810b57cec5SDimitry Andric } 15820b57cec5SDimitry Andric 15830b57cec5SDimitry Andric void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) { 15840b57cec5SDimitry Andric if (Node->getType()->getAsCXXRecordDecl()) { 15850b57cec5SDimitry Andric OS << "/*implicit*/"; 15860b57cec5SDimitry Andric Node->getType().print(OS, Policy); 15870b57cec5SDimitry Andric OS << "()"; 15880b57cec5SDimitry Andric } else { 15890b57cec5SDimitry Andric OS << "/*implicit*/("; 15900b57cec5SDimitry Andric Node->getType().print(OS, Policy); 15910b57cec5SDimitry Andric OS << ')'; 15920b57cec5SDimitry Andric if (Node->getType()->isRecordType()) 15930b57cec5SDimitry Andric OS << "{}"; 15940b57cec5SDimitry Andric else 15950b57cec5SDimitry Andric OS << 0; 15960b57cec5SDimitry Andric } 15970b57cec5SDimitry Andric } 15980b57cec5SDimitry Andric 15990b57cec5SDimitry Andric void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) { 16000b57cec5SDimitry Andric OS << "__builtin_va_arg("; 16010b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 16020b57cec5SDimitry Andric OS << ", "; 16030b57cec5SDimitry Andric Node->getType().print(OS, Policy); 16040b57cec5SDimitry Andric OS << ")"; 16050b57cec5SDimitry Andric } 16060b57cec5SDimitry Andric 16070b57cec5SDimitry Andric void StmtPrinter::VisitPseudoObjectExpr(PseudoObjectExpr *Node) { 16080b57cec5SDimitry Andric PrintExpr(Node->getSyntacticForm()); 16090b57cec5SDimitry Andric } 16100b57cec5SDimitry Andric 16110b57cec5SDimitry Andric void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) { 16120b57cec5SDimitry Andric const char *Name = nullptr; 16130b57cec5SDimitry Andric switch (Node->getOp()) { 16140b57cec5SDimitry Andric #define BUILTIN(ID, TYPE, ATTRS) 16150b57cec5SDimitry Andric #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \ 16160b57cec5SDimitry Andric case AtomicExpr::AO ## ID: \ 16170b57cec5SDimitry Andric Name = #ID "("; \ 16180b57cec5SDimitry Andric break; 16190b57cec5SDimitry Andric #include "clang/Basic/Builtins.def" 16200b57cec5SDimitry Andric } 16210b57cec5SDimitry Andric OS << Name; 16220b57cec5SDimitry Andric 16230b57cec5SDimitry Andric // AtomicExpr stores its subexpressions in a permuted order. 16240b57cec5SDimitry Andric PrintExpr(Node->getPtr()); 16250b57cec5SDimitry Andric if (Node->getOp() != AtomicExpr::AO__c11_atomic_load && 16260b57cec5SDimitry Andric Node->getOp() != AtomicExpr::AO__atomic_load_n && 16270b57cec5SDimitry Andric Node->getOp() != AtomicExpr::AO__opencl_atomic_load) { 16280b57cec5SDimitry Andric OS << ", "; 16290b57cec5SDimitry Andric PrintExpr(Node->getVal1()); 16300b57cec5SDimitry Andric } 16310b57cec5SDimitry Andric if (Node->getOp() == AtomicExpr::AO__atomic_exchange || 16320b57cec5SDimitry Andric Node->isCmpXChg()) { 16330b57cec5SDimitry Andric OS << ", "; 16340b57cec5SDimitry Andric PrintExpr(Node->getVal2()); 16350b57cec5SDimitry Andric } 16360b57cec5SDimitry Andric if (Node->getOp() == AtomicExpr::AO__atomic_compare_exchange || 16370b57cec5SDimitry Andric Node->getOp() == AtomicExpr::AO__atomic_compare_exchange_n) { 16380b57cec5SDimitry Andric OS << ", "; 16390b57cec5SDimitry Andric PrintExpr(Node->getWeak()); 16400b57cec5SDimitry Andric } 16410b57cec5SDimitry Andric if (Node->getOp() != AtomicExpr::AO__c11_atomic_init && 16420b57cec5SDimitry Andric Node->getOp() != AtomicExpr::AO__opencl_atomic_init) { 16430b57cec5SDimitry Andric OS << ", "; 16440b57cec5SDimitry Andric PrintExpr(Node->getOrder()); 16450b57cec5SDimitry Andric } 16460b57cec5SDimitry Andric if (Node->isCmpXChg()) { 16470b57cec5SDimitry Andric OS << ", "; 16480b57cec5SDimitry Andric PrintExpr(Node->getOrderFail()); 16490b57cec5SDimitry Andric } 16500b57cec5SDimitry Andric OS << ")"; 16510b57cec5SDimitry Andric } 16520b57cec5SDimitry Andric 16530b57cec5SDimitry Andric // C++ 16540b57cec5SDimitry Andric void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) { 16550b57cec5SDimitry Andric OverloadedOperatorKind Kind = Node->getOperator(); 16560b57cec5SDimitry Andric if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) { 16570b57cec5SDimitry Andric if (Node->getNumArgs() == 1) { 16580b57cec5SDimitry Andric OS << getOperatorSpelling(Kind) << ' '; 16590b57cec5SDimitry Andric PrintExpr(Node->getArg(0)); 16600b57cec5SDimitry Andric } else { 16610b57cec5SDimitry Andric PrintExpr(Node->getArg(0)); 16620b57cec5SDimitry Andric OS << ' ' << getOperatorSpelling(Kind); 16630b57cec5SDimitry Andric } 16640b57cec5SDimitry Andric } else if (Kind == OO_Arrow) { 16650b57cec5SDimitry Andric PrintExpr(Node->getArg(0)); 16660b57cec5SDimitry Andric } else if (Kind == OO_Call) { 16670b57cec5SDimitry Andric PrintExpr(Node->getArg(0)); 16680b57cec5SDimitry Andric OS << '('; 16690b57cec5SDimitry Andric for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) { 16700b57cec5SDimitry Andric if (ArgIdx > 1) 16710b57cec5SDimitry Andric OS << ", "; 16720b57cec5SDimitry Andric if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx))) 16730b57cec5SDimitry Andric PrintExpr(Node->getArg(ArgIdx)); 16740b57cec5SDimitry Andric } 16750b57cec5SDimitry Andric OS << ')'; 16760b57cec5SDimitry Andric } else if (Kind == OO_Subscript) { 16770b57cec5SDimitry Andric PrintExpr(Node->getArg(0)); 16780b57cec5SDimitry Andric OS << '['; 16790b57cec5SDimitry Andric PrintExpr(Node->getArg(1)); 16800b57cec5SDimitry Andric OS << ']'; 16810b57cec5SDimitry Andric } else if (Node->getNumArgs() == 1) { 16820b57cec5SDimitry Andric OS << getOperatorSpelling(Kind) << ' '; 16830b57cec5SDimitry Andric PrintExpr(Node->getArg(0)); 16840b57cec5SDimitry Andric } else if (Node->getNumArgs() == 2) { 16850b57cec5SDimitry Andric PrintExpr(Node->getArg(0)); 16860b57cec5SDimitry Andric OS << ' ' << getOperatorSpelling(Kind) << ' '; 16870b57cec5SDimitry Andric PrintExpr(Node->getArg(1)); 16880b57cec5SDimitry Andric } else { 16890b57cec5SDimitry Andric llvm_unreachable("unknown overloaded operator"); 16900b57cec5SDimitry Andric } 16910b57cec5SDimitry Andric } 16920b57cec5SDimitry Andric 16930b57cec5SDimitry Andric void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) { 16940b57cec5SDimitry Andric // If we have a conversion operator call only print the argument. 16950b57cec5SDimitry Andric CXXMethodDecl *MD = Node->getMethodDecl(); 16960b57cec5SDimitry Andric if (MD && isa<CXXConversionDecl>(MD)) { 16970b57cec5SDimitry Andric PrintExpr(Node->getImplicitObjectArgument()); 16980b57cec5SDimitry Andric return; 16990b57cec5SDimitry Andric } 17000b57cec5SDimitry Andric VisitCallExpr(cast<CallExpr>(Node)); 17010b57cec5SDimitry Andric } 17020b57cec5SDimitry Andric 17030b57cec5SDimitry Andric void StmtPrinter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *Node) { 17040b57cec5SDimitry Andric PrintExpr(Node->getCallee()); 17050b57cec5SDimitry Andric OS << "<<<"; 17060b57cec5SDimitry Andric PrintCallArgs(Node->getConfig()); 17070b57cec5SDimitry Andric OS << ">>>("; 17080b57cec5SDimitry Andric PrintCallArgs(Node); 17090b57cec5SDimitry Andric OS << ")"; 17100b57cec5SDimitry Andric } 17110b57cec5SDimitry Andric 1712a7dea167SDimitry Andric void StmtPrinter::VisitCXXRewrittenBinaryOperator( 1713a7dea167SDimitry Andric CXXRewrittenBinaryOperator *Node) { 1714a7dea167SDimitry Andric CXXRewrittenBinaryOperator::DecomposedForm Decomposed = 1715a7dea167SDimitry Andric Node->getDecomposedForm(); 1716a7dea167SDimitry Andric PrintExpr(const_cast<Expr*>(Decomposed.LHS)); 1717a7dea167SDimitry Andric OS << ' ' << BinaryOperator::getOpcodeStr(Decomposed.Opcode) << ' '; 1718a7dea167SDimitry Andric PrintExpr(const_cast<Expr*>(Decomposed.RHS)); 1719a7dea167SDimitry Andric } 1720a7dea167SDimitry Andric 17210b57cec5SDimitry Andric void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) { 17220b57cec5SDimitry Andric OS << Node->getCastName() << '<'; 17230b57cec5SDimitry Andric Node->getTypeAsWritten().print(OS, Policy); 17240b57cec5SDimitry Andric OS << ">("; 17250b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 17260b57cec5SDimitry Andric OS << ")"; 17270b57cec5SDimitry Andric } 17280b57cec5SDimitry Andric 17290b57cec5SDimitry Andric void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) { 17300b57cec5SDimitry Andric VisitCXXNamedCastExpr(Node); 17310b57cec5SDimitry Andric } 17320b57cec5SDimitry Andric 17330b57cec5SDimitry Andric void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) { 17340b57cec5SDimitry Andric VisitCXXNamedCastExpr(Node); 17350b57cec5SDimitry Andric } 17360b57cec5SDimitry Andric 17370b57cec5SDimitry Andric void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) { 17380b57cec5SDimitry Andric VisitCXXNamedCastExpr(Node); 17390b57cec5SDimitry Andric } 17400b57cec5SDimitry Andric 17410b57cec5SDimitry Andric void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) { 17420b57cec5SDimitry Andric VisitCXXNamedCastExpr(Node); 17430b57cec5SDimitry Andric } 17440b57cec5SDimitry Andric 17450b57cec5SDimitry Andric void StmtPrinter::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *Node) { 17460b57cec5SDimitry Andric OS << "__builtin_bit_cast("; 17470b57cec5SDimitry Andric Node->getTypeInfoAsWritten()->getType().print(OS, Policy); 17480b57cec5SDimitry Andric OS << ", "; 17490b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 17500b57cec5SDimitry Andric OS << ")"; 17510b57cec5SDimitry Andric } 17520b57cec5SDimitry Andric 17530b57cec5SDimitry Andric void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) { 17540b57cec5SDimitry Andric OS << "typeid("; 17550b57cec5SDimitry Andric if (Node->isTypeOperand()) { 17560b57cec5SDimitry Andric Node->getTypeOperandSourceInfo()->getType().print(OS, Policy); 17570b57cec5SDimitry Andric } else { 17580b57cec5SDimitry Andric PrintExpr(Node->getExprOperand()); 17590b57cec5SDimitry Andric } 17600b57cec5SDimitry Andric OS << ")"; 17610b57cec5SDimitry Andric } 17620b57cec5SDimitry Andric 17630b57cec5SDimitry Andric void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) { 17640b57cec5SDimitry Andric OS << "__uuidof("; 17650b57cec5SDimitry Andric if (Node->isTypeOperand()) { 17660b57cec5SDimitry Andric Node->getTypeOperandSourceInfo()->getType().print(OS, Policy); 17670b57cec5SDimitry Andric } else { 17680b57cec5SDimitry Andric PrintExpr(Node->getExprOperand()); 17690b57cec5SDimitry Andric } 17700b57cec5SDimitry Andric OS << ")"; 17710b57cec5SDimitry Andric } 17720b57cec5SDimitry Andric 17730b57cec5SDimitry Andric void StmtPrinter::VisitMSPropertyRefExpr(MSPropertyRefExpr *Node) { 17740b57cec5SDimitry Andric PrintExpr(Node->getBaseExpr()); 17750b57cec5SDimitry Andric if (Node->isArrow()) 17760b57cec5SDimitry Andric OS << "->"; 17770b57cec5SDimitry Andric else 17780b57cec5SDimitry Andric OS << "."; 17790b57cec5SDimitry Andric if (NestedNameSpecifier *Qualifier = 17800b57cec5SDimitry Andric Node->getQualifierLoc().getNestedNameSpecifier()) 17810b57cec5SDimitry Andric Qualifier->print(OS, Policy); 17820b57cec5SDimitry Andric OS << Node->getPropertyDecl()->getDeclName(); 17830b57cec5SDimitry Andric } 17840b57cec5SDimitry Andric 17850b57cec5SDimitry Andric void StmtPrinter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *Node) { 17860b57cec5SDimitry Andric PrintExpr(Node->getBase()); 17870b57cec5SDimitry Andric OS << "["; 17880b57cec5SDimitry Andric PrintExpr(Node->getIdx()); 17890b57cec5SDimitry Andric OS << "]"; 17900b57cec5SDimitry Andric } 17910b57cec5SDimitry Andric 17920b57cec5SDimitry Andric void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) { 17930b57cec5SDimitry Andric switch (Node->getLiteralOperatorKind()) { 17940b57cec5SDimitry Andric case UserDefinedLiteral::LOK_Raw: 17950b57cec5SDimitry Andric OS << cast<StringLiteral>(Node->getArg(0)->IgnoreImpCasts())->getString(); 17960b57cec5SDimitry Andric break; 17970b57cec5SDimitry Andric case UserDefinedLiteral::LOK_Template: { 17980b57cec5SDimitry Andric const auto *DRE = cast<DeclRefExpr>(Node->getCallee()->IgnoreImpCasts()); 17990b57cec5SDimitry Andric const TemplateArgumentList *Args = 18000b57cec5SDimitry Andric cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs(); 18010b57cec5SDimitry Andric assert(Args); 18020b57cec5SDimitry Andric 18030b57cec5SDimitry Andric if (Args->size() != 1) { 18040b57cec5SDimitry Andric OS << "operator\"\"" << Node->getUDSuffix()->getName(); 18050b57cec5SDimitry Andric printTemplateArgumentList(OS, Args->asArray(), Policy); 18060b57cec5SDimitry Andric OS << "()"; 18070b57cec5SDimitry Andric return; 18080b57cec5SDimitry Andric } 18090b57cec5SDimitry Andric 18100b57cec5SDimitry Andric const TemplateArgument &Pack = Args->get(0); 18110b57cec5SDimitry Andric for (const auto &P : Pack.pack_elements()) { 18120b57cec5SDimitry Andric char C = (char)P.getAsIntegral().getZExtValue(); 18130b57cec5SDimitry Andric OS << C; 18140b57cec5SDimitry Andric } 18150b57cec5SDimitry Andric break; 18160b57cec5SDimitry Andric } 18170b57cec5SDimitry Andric case UserDefinedLiteral::LOK_Integer: { 18180b57cec5SDimitry Andric // Print integer literal without suffix. 18190b57cec5SDimitry Andric const auto *Int = cast<IntegerLiteral>(Node->getCookedLiteral()); 18200b57cec5SDimitry Andric OS << Int->getValue().toString(10, /*isSigned*/false); 18210b57cec5SDimitry Andric break; 18220b57cec5SDimitry Andric } 18230b57cec5SDimitry Andric case UserDefinedLiteral::LOK_Floating: { 18240b57cec5SDimitry Andric // Print floating literal without suffix. 18250b57cec5SDimitry Andric auto *Float = cast<FloatingLiteral>(Node->getCookedLiteral()); 18260b57cec5SDimitry Andric PrintFloatingLiteral(OS, Float, /*PrintSuffix=*/false); 18270b57cec5SDimitry Andric break; 18280b57cec5SDimitry Andric } 18290b57cec5SDimitry Andric case UserDefinedLiteral::LOK_String: 18300b57cec5SDimitry Andric case UserDefinedLiteral::LOK_Character: 18310b57cec5SDimitry Andric PrintExpr(Node->getCookedLiteral()); 18320b57cec5SDimitry Andric break; 18330b57cec5SDimitry Andric } 18340b57cec5SDimitry Andric OS << Node->getUDSuffix()->getName(); 18350b57cec5SDimitry Andric } 18360b57cec5SDimitry Andric 18370b57cec5SDimitry Andric void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) { 18380b57cec5SDimitry Andric OS << (Node->getValue() ? "true" : "false"); 18390b57cec5SDimitry Andric } 18400b57cec5SDimitry Andric 18410b57cec5SDimitry Andric void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) { 18420b57cec5SDimitry Andric OS << "nullptr"; 18430b57cec5SDimitry Andric } 18440b57cec5SDimitry Andric 18450b57cec5SDimitry Andric void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) { 18460b57cec5SDimitry Andric OS << "this"; 18470b57cec5SDimitry Andric } 18480b57cec5SDimitry Andric 18490b57cec5SDimitry Andric void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) { 18500b57cec5SDimitry Andric if (!Node->getSubExpr()) 18510b57cec5SDimitry Andric OS << "throw"; 18520b57cec5SDimitry Andric else { 18530b57cec5SDimitry Andric OS << "throw "; 18540b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 18550b57cec5SDimitry Andric } 18560b57cec5SDimitry Andric } 18570b57cec5SDimitry Andric 18580b57cec5SDimitry Andric void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) { 18590b57cec5SDimitry Andric // Nothing to print: we picked up the default argument. 18600b57cec5SDimitry Andric } 18610b57cec5SDimitry Andric 18620b57cec5SDimitry Andric void StmtPrinter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Node) { 18630b57cec5SDimitry Andric // Nothing to print: we picked up the default initializer. 18640b57cec5SDimitry Andric } 18650b57cec5SDimitry Andric 18660b57cec5SDimitry Andric void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) { 18670b57cec5SDimitry Andric Node->getType().print(OS, Policy); 18680b57cec5SDimitry Andric // If there are no parens, this is list-initialization, and the braces are 18690b57cec5SDimitry Andric // part of the syntax of the inner construct. 18700b57cec5SDimitry Andric if (Node->getLParenLoc().isValid()) 18710b57cec5SDimitry Andric OS << "("; 18720b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 18730b57cec5SDimitry Andric if (Node->getLParenLoc().isValid()) 18740b57cec5SDimitry Andric OS << ")"; 18750b57cec5SDimitry Andric } 18760b57cec5SDimitry Andric 18770b57cec5SDimitry Andric void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) { 18780b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 18790b57cec5SDimitry Andric } 18800b57cec5SDimitry Andric 18810b57cec5SDimitry Andric void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) { 18820b57cec5SDimitry Andric Node->getType().print(OS, Policy); 18830b57cec5SDimitry Andric if (Node->isStdInitListInitialization()) 18840b57cec5SDimitry Andric /* Nothing to do; braces are part of creating the std::initializer_list. */; 18850b57cec5SDimitry Andric else if (Node->isListInitialization()) 18860b57cec5SDimitry Andric OS << "{"; 18870b57cec5SDimitry Andric else 18880b57cec5SDimitry Andric OS << "("; 18890b57cec5SDimitry Andric for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(), 18900b57cec5SDimitry Andric ArgEnd = Node->arg_end(); 18910b57cec5SDimitry Andric Arg != ArgEnd; ++Arg) { 18920b57cec5SDimitry Andric if ((*Arg)->isDefaultArgument()) 18930b57cec5SDimitry Andric break; 18940b57cec5SDimitry Andric if (Arg != Node->arg_begin()) 18950b57cec5SDimitry Andric OS << ", "; 18960b57cec5SDimitry Andric PrintExpr(*Arg); 18970b57cec5SDimitry Andric } 18980b57cec5SDimitry Andric if (Node->isStdInitListInitialization()) 18990b57cec5SDimitry Andric /* See above. */; 19000b57cec5SDimitry Andric else if (Node->isListInitialization()) 19010b57cec5SDimitry Andric OS << "}"; 19020b57cec5SDimitry Andric else 19030b57cec5SDimitry Andric OS << ")"; 19040b57cec5SDimitry Andric } 19050b57cec5SDimitry Andric 19060b57cec5SDimitry Andric void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) { 19070b57cec5SDimitry Andric OS << '['; 19080b57cec5SDimitry Andric bool NeedComma = false; 19090b57cec5SDimitry Andric switch (Node->getCaptureDefault()) { 19100b57cec5SDimitry Andric case LCD_None: 19110b57cec5SDimitry Andric break; 19120b57cec5SDimitry Andric 19130b57cec5SDimitry Andric case LCD_ByCopy: 19140b57cec5SDimitry Andric OS << '='; 19150b57cec5SDimitry Andric NeedComma = true; 19160b57cec5SDimitry Andric break; 19170b57cec5SDimitry Andric 19180b57cec5SDimitry Andric case LCD_ByRef: 19190b57cec5SDimitry Andric OS << '&'; 19200b57cec5SDimitry Andric NeedComma = true; 19210b57cec5SDimitry Andric break; 19220b57cec5SDimitry Andric } 19230b57cec5SDimitry Andric for (LambdaExpr::capture_iterator C = Node->explicit_capture_begin(), 19240b57cec5SDimitry Andric CEnd = Node->explicit_capture_end(); 19250b57cec5SDimitry Andric C != CEnd; 19260b57cec5SDimitry Andric ++C) { 19270b57cec5SDimitry Andric if (C->capturesVLAType()) 19280b57cec5SDimitry Andric continue; 19290b57cec5SDimitry Andric 19300b57cec5SDimitry Andric if (NeedComma) 19310b57cec5SDimitry Andric OS << ", "; 19320b57cec5SDimitry Andric NeedComma = true; 19330b57cec5SDimitry Andric 19340b57cec5SDimitry Andric switch (C->getCaptureKind()) { 19350b57cec5SDimitry Andric case LCK_This: 19360b57cec5SDimitry Andric OS << "this"; 19370b57cec5SDimitry Andric break; 19380b57cec5SDimitry Andric 19390b57cec5SDimitry Andric case LCK_StarThis: 19400b57cec5SDimitry Andric OS << "*this"; 19410b57cec5SDimitry Andric break; 19420b57cec5SDimitry Andric 19430b57cec5SDimitry Andric case LCK_ByRef: 19440b57cec5SDimitry Andric if (Node->getCaptureDefault() != LCD_ByRef || Node->isInitCapture(C)) 19450b57cec5SDimitry Andric OS << '&'; 19460b57cec5SDimitry Andric OS << C->getCapturedVar()->getName(); 19470b57cec5SDimitry Andric break; 19480b57cec5SDimitry Andric 19490b57cec5SDimitry Andric case LCK_ByCopy: 19500b57cec5SDimitry Andric OS << C->getCapturedVar()->getName(); 19510b57cec5SDimitry Andric break; 19520b57cec5SDimitry Andric 19530b57cec5SDimitry Andric case LCK_VLAType: 19540b57cec5SDimitry Andric llvm_unreachable("VLA type in explicit captures."); 19550b57cec5SDimitry Andric } 19560b57cec5SDimitry Andric 19570b57cec5SDimitry Andric if (C->isPackExpansion()) 19580b57cec5SDimitry Andric OS << "..."; 19590b57cec5SDimitry Andric 19600b57cec5SDimitry Andric if (Node->isInitCapture(C)) 19610b57cec5SDimitry Andric PrintExpr(C->getCapturedVar()->getInit()); 19620b57cec5SDimitry Andric } 19630b57cec5SDimitry Andric OS << ']'; 19640b57cec5SDimitry Andric 19650b57cec5SDimitry Andric if (!Node->getExplicitTemplateParameters().empty()) { 19660b57cec5SDimitry Andric Node->getTemplateParameterList()->print( 19670b57cec5SDimitry Andric OS, Node->getLambdaClass()->getASTContext(), 19680b57cec5SDimitry Andric /*OmitTemplateKW*/true); 19690b57cec5SDimitry Andric } 19700b57cec5SDimitry Andric 19710b57cec5SDimitry Andric if (Node->hasExplicitParameters()) { 19720b57cec5SDimitry Andric OS << '('; 19730b57cec5SDimitry Andric CXXMethodDecl *Method = Node->getCallOperator(); 19740b57cec5SDimitry Andric NeedComma = false; 19750b57cec5SDimitry Andric for (const auto *P : Method->parameters()) { 19760b57cec5SDimitry Andric if (NeedComma) { 19770b57cec5SDimitry Andric OS << ", "; 19780b57cec5SDimitry Andric } else { 19790b57cec5SDimitry Andric NeedComma = true; 19800b57cec5SDimitry Andric } 19810b57cec5SDimitry Andric std::string ParamStr = P->getNameAsString(); 19820b57cec5SDimitry Andric P->getOriginalType().print(OS, Policy, ParamStr); 19830b57cec5SDimitry Andric } 19840b57cec5SDimitry Andric if (Method->isVariadic()) { 19850b57cec5SDimitry Andric if (NeedComma) 19860b57cec5SDimitry Andric OS << ", "; 19870b57cec5SDimitry Andric OS << "..."; 19880b57cec5SDimitry Andric } 19890b57cec5SDimitry Andric OS << ')'; 19900b57cec5SDimitry Andric 19910b57cec5SDimitry Andric if (Node->isMutable()) 19920b57cec5SDimitry Andric OS << " mutable"; 19930b57cec5SDimitry Andric 1994a7dea167SDimitry Andric auto *Proto = Method->getType()->castAs<FunctionProtoType>(); 19950b57cec5SDimitry Andric Proto->printExceptionSpecification(OS, Policy); 19960b57cec5SDimitry Andric 19970b57cec5SDimitry Andric // FIXME: Attributes 19980b57cec5SDimitry Andric 19990b57cec5SDimitry Andric // Print the trailing return type if it was specified in the source. 20000b57cec5SDimitry Andric if (Node->hasExplicitResultType()) { 20010b57cec5SDimitry Andric OS << " -> "; 20020b57cec5SDimitry Andric Proto->getReturnType().print(OS, Policy); 20030b57cec5SDimitry Andric } 20040b57cec5SDimitry Andric } 20050b57cec5SDimitry Andric 20060b57cec5SDimitry Andric // Print the body. 20070b57cec5SDimitry Andric OS << ' '; 20080b57cec5SDimitry Andric if (Policy.TerseOutput) 20090b57cec5SDimitry Andric OS << "{}"; 20100b57cec5SDimitry Andric else 20110b57cec5SDimitry Andric PrintRawCompoundStmt(Node->getBody()); 20120b57cec5SDimitry Andric } 20130b57cec5SDimitry Andric 20140b57cec5SDimitry Andric void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) { 20150b57cec5SDimitry Andric if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo()) 20160b57cec5SDimitry Andric TSInfo->getType().print(OS, Policy); 20170b57cec5SDimitry Andric else 20180b57cec5SDimitry Andric Node->getType().print(OS, Policy); 20190b57cec5SDimitry Andric OS << "()"; 20200b57cec5SDimitry Andric } 20210b57cec5SDimitry Andric 20220b57cec5SDimitry Andric void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) { 20230b57cec5SDimitry Andric if (E->isGlobalNew()) 20240b57cec5SDimitry Andric OS << "::"; 20250b57cec5SDimitry Andric OS << "new "; 20260b57cec5SDimitry Andric unsigned NumPlace = E->getNumPlacementArgs(); 20270b57cec5SDimitry Andric if (NumPlace > 0 && !isa<CXXDefaultArgExpr>(E->getPlacementArg(0))) { 20280b57cec5SDimitry Andric OS << "("; 20290b57cec5SDimitry Andric PrintExpr(E->getPlacementArg(0)); 20300b57cec5SDimitry Andric for (unsigned i = 1; i < NumPlace; ++i) { 20310b57cec5SDimitry Andric if (isa<CXXDefaultArgExpr>(E->getPlacementArg(i))) 20320b57cec5SDimitry Andric break; 20330b57cec5SDimitry Andric OS << ", "; 20340b57cec5SDimitry Andric PrintExpr(E->getPlacementArg(i)); 20350b57cec5SDimitry Andric } 20360b57cec5SDimitry Andric OS << ") "; 20370b57cec5SDimitry Andric } 20380b57cec5SDimitry Andric if (E->isParenTypeId()) 20390b57cec5SDimitry Andric OS << "("; 20400b57cec5SDimitry Andric std::string TypeS; 20410b57cec5SDimitry Andric if (Optional<Expr *> Size = E->getArraySize()) { 20420b57cec5SDimitry Andric llvm::raw_string_ostream s(TypeS); 20430b57cec5SDimitry Andric s << '['; 20440b57cec5SDimitry Andric if (*Size) 20450b57cec5SDimitry Andric (*Size)->printPretty(s, Helper, Policy); 20460b57cec5SDimitry Andric s << ']'; 20470b57cec5SDimitry Andric } 20480b57cec5SDimitry Andric E->getAllocatedType().print(OS, Policy, TypeS); 20490b57cec5SDimitry Andric if (E->isParenTypeId()) 20500b57cec5SDimitry Andric OS << ")"; 20510b57cec5SDimitry Andric 20520b57cec5SDimitry Andric CXXNewExpr::InitializationStyle InitStyle = E->getInitializationStyle(); 20530b57cec5SDimitry Andric if (InitStyle) { 20540b57cec5SDimitry Andric if (InitStyle == CXXNewExpr::CallInit) 20550b57cec5SDimitry Andric OS << "("; 20560b57cec5SDimitry Andric PrintExpr(E->getInitializer()); 20570b57cec5SDimitry Andric if (InitStyle == CXXNewExpr::CallInit) 20580b57cec5SDimitry Andric OS << ")"; 20590b57cec5SDimitry Andric } 20600b57cec5SDimitry Andric } 20610b57cec5SDimitry Andric 20620b57cec5SDimitry Andric void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) { 20630b57cec5SDimitry Andric if (E->isGlobalDelete()) 20640b57cec5SDimitry Andric OS << "::"; 20650b57cec5SDimitry Andric OS << "delete "; 20660b57cec5SDimitry Andric if (E->isArrayForm()) 20670b57cec5SDimitry Andric OS << "[] "; 20680b57cec5SDimitry Andric PrintExpr(E->getArgument()); 20690b57cec5SDimitry Andric } 20700b57cec5SDimitry Andric 20710b57cec5SDimitry Andric void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) { 20720b57cec5SDimitry Andric PrintExpr(E->getBase()); 20730b57cec5SDimitry Andric if (E->isArrow()) 20740b57cec5SDimitry Andric OS << "->"; 20750b57cec5SDimitry Andric else 20760b57cec5SDimitry Andric OS << '.'; 20770b57cec5SDimitry Andric if (E->getQualifier()) 20780b57cec5SDimitry Andric E->getQualifier()->print(OS, Policy); 20790b57cec5SDimitry Andric OS << "~"; 20800b57cec5SDimitry Andric 20810b57cec5SDimitry Andric if (IdentifierInfo *II = E->getDestroyedTypeIdentifier()) 20820b57cec5SDimitry Andric OS << II->getName(); 20830b57cec5SDimitry Andric else 20840b57cec5SDimitry Andric E->getDestroyedType().print(OS, Policy); 20850b57cec5SDimitry Andric } 20860b57cec5SDimitry Andric 20870b57cec5SDimitry Andric void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) { 20880b57cec5SDimitry Andric if (E->isListInitialization() && !E->isStdInitListInitialization()) 20890b57cec5SDimitry Andric OS << "{"; 20900b57cec5SDimitry Andric 20910b57cec5SDimitry Andric for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { 20920b57cec5SDimitry Andric if (isa<CXXDefaultArgExpr>(E->getArg(i))) { 20930b57cec5SDimitry Andric // Don't print any defaulted arguments 20940b57cec5SDimitry Andric break; 20950b57cec5SDimitry Andric } 20960b57cec5SDimitry Andric 20970b57cec5SDimitry Andric if (i) OS << ", "; 20980b57cec5SDimitry Andric PrintExpr(E->getArg(i)); 20990b57cec5SDimitry Andric } 21000b57cec5SDimitry Andric 21010b57cec5SDimitry Andric if (E->isListInitialization() && !E->isStdInitListInitialization()) 21020b57cec5SDimitry Andric OS << "}"; 21030b57cec5SDimitry Andric } 21040b57cec5SDimitry Andric 21050b57cec5SDimitry Andric void StmtPrinter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) { 21060b57cec5SDimitry Andric // Parens are printed by the surrounding context. 21070b57cec5SDimitry Andric OS << "<forwarded>"; 21080b57cec5SDimitry Andric } 21090b57cec5SDimitry Andric 21100b57cec5SDimitry Andric void StmtPrinter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) { 21110b57cec5SDimitry Andric PrintExpr(E->getSubExpr()); 21120b57cec5SDimitry Andric } 21130b57cec5SDimitry Andric 21140b57cec5SDimitry Andric void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) { 21150b57cec5SDimitry Andric // Just forward to the subexpression. 21160b57cec5SDimitry Andric PrintExpr(E->getSubExpr()); 21170b57cec5SDimitry Andric } 21180b57cec5SDimitry Andric 21190b57cec5SDimitry Andric void 21200b57cec5SDimitry Andric StmtPrinter::VisitCXXUnresolvedConstructExpr( 21210b57cec5SDimitry Andric CXXUnresolvedConstructExpr *Node) { 21220b57cec5SDimitry Andric Node->getTypeAsWritten().print(OS, Policy); 21230b57cec5SDimitry Andric OS << "("; 21240b57cec5SDimitry Andric for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(), 21250b57cec5SDimitry Andric ArgEnd = Node->arg_end(); 21260b57cec5SDimitry Andric Arg != ArgEnd; ++Arg) { 21270b57cec5SDimitry Andric if (Arg != Node->arg_begin()) 21280b57cec5SDimitry Andric OS << ", "; 21290b57cec5SDimitry Andric PrintExpr(*Arg); 21300b57cec5SDimitry Andric } 21310b57cec5SDimitry Andric OS << ")"; 21320b57cec5SDimitry Andric } 21330b57cec5SDimitry Andric 21340b57cec5SDimitry Andric void StmtPrinter::VisitCXXDependentScopeMemberExpr( 21350b57cec5SDimitry Andric CXXDependentScopeMemberExpr *Node) { 21360b57cec5SDimitry Andric if (!Node->isImplicitAccess()) { 21370b57cec5SDimitry Andric PrintExpr(Node->getBase()); 21380b57cec5SDimitry Andric OS << (Node->isArrow() ? "->" : "."); 21390b57cec5SDimitry Andric } 21400b57cec5SDimitry Andric if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 21410b57cec5SDimitry Andric Qualifier->print(OS, Policy); 21420b57cec5SDimitry Andric if (Node->hasTemplateKeyword()) 21430b57cec5SDimitry Andric OS << "template "; 21440b57cec5SDimitry Andric OS << Node->getMemberNameInfo(); 21450b57cec5SDimitry Andric if (Node->hasExplicitTemplateArgs()) 21460b57cec5SDimitry Andric printTemplateArgumentList(OS, Node->template_arguments(), Policy); 21470b57cec5SDimitry Andric } 21480b57cec5SDimitry Andric 21490b57cec5SDimitry Andric void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) { 21500b57cec5SDimitry Andric if (!Node->isImplicitAccess()) { 21510b57cec5SDimitry Andric PrintExpr(Node->getBase()); 21520b57cec5SDimitry Andric OS << (Node->isArrow() ? "->" : "."); 21530b57cec5SDimitry Andric } 21540b57cec5SDimitry Andric if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 21550b57cec5SDimitry Andric Qualifier->print(OS, Policy); 21560b57cec5SDimitry Andric if (Node->hasTemplateKeyword()) 21570b57cec5SDimitry Andric OS << "template "; 21580b57cec5SDimitry Andric OS << Node->getMemberNameInfo(); 21590b57cec5SDimitry Andric if (Node->hasExplicitTemplateArgs()) 21600b57cec5SDimitry Andric printTemplateArgumentList(OS, Node->template_arguments(), Policy); 21610b57cec5SDimitry Andric } 21620b57cec5SDimitry Andric 21630b57cec5SDimitry Andric static const char *getTypeTraitName(TypeTrait TT) { 21640b57cec5SDimitry Andric switch (TT) { 21650b57cec5SDimitry Andric #define TYPE_TRAIT_1(Spelling, Name, Key) \ 21660b57cec5SDimitry Andric case clang::UTT_##Name: return #Spelling; 21670b57cec5SDimitry Andric #define TYPE_TRAIT_2(Spelling, Name, Key) \ 21680b57cec5SDimitry Andric case clang::BTT_##Name: return #Spelling; 21690b57cec5SDimitry Andric #define TYPE_TRAIT_N(Spelling, Name, Key) \ 21700b57cec5SDimitry Andric case clang::TT_##Name: return #Spelling; 21710b57cec5SDimitry Andric #include "clang/Basic/TokenKinds.def" 21720b57cec5SDimitry Andric } 21730b57cec5SDimitry Andric llvm_unreachable("Type trait not covered by switch"); 21740b57cec5SDimitry Andric } 21750b57cec5SDimitry Andric 21760b57cec5SDimitry Andric static const char *getTypeTraitName(ArrayTypeTrait ATT) { 21770b57cec5SDimitry Andric switch (ATT) { 21780b57cec5SDimitry Andric case ATT_ArrayRank: return "__array_rank"; 21790b57cec5SDimitry Andric case ATT_ArrayExtent: return "__array_extent"; 21800b57cec5SDimitry Andric } 21810b57cec5SDimitry Andric llvm_unreachable("Array type trait not covered by switch"); 21820b57cec5SDimitry Andric } 21830b57cec5SDimitry Andric 21840b57cec5SDimitry Andric static const char *getExpressionTraitName(ExpressionTrait ET) { 21850b57cec5SDimitry Andric switch (ET) { 21860b57cec5SDimitry Andric case ET_IsLValueExpr: return "__is_lvalue_expr"; 21870b57cec5SDimitry Andric case ET_IsRValueExpr: return "__is_rvalue_expr"; 21880b57cec5SDimitry Andric } 21890b57cec5SDimitry Andric llvm_unreachable("Expression type trait not covered by switch"); 21900b57cec5SDimitry Andric } 21910b57cec5SDimitry Andric 21920b57cec5SDimitry Andric void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) { 21930b57cec5SDimitry Andric OS << getTypeTraitName(E->getTrait()) << "("; 21940b57cec5SDimitry Andric for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) { 21950b57cec5SDimitry Andric if (I > 0) 21960b57cec5SDimitry Andric OS << ", "; 21970b57cec5SDimitry Andric E->getArg(I)->getType().print(OS, Policy); 21980b57cec5SDimitry Andric } 21990b57cec5SDimitry Andric OS << ")"; 22000b57cec5SDimitry Andric } 22010b57cec5SDimitry Andric 22020b57cec5SDimitry Andric void StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) { 22030b57cec5SDimitry Andric OS << getTypeTraitName(E->getTrait()) << '('; 22040b57cec5SDimitry Andric E->getQueriedType().print(OS, Policy); 22050b57cec5SDimitry Andric OS << ')'; 22060b57cec5SDimitry Andric } 22070b57cec5SDimitry Andric 22080b57cec5SDimitry Andric void StmtPrinter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) { 22090b57cec5SDimitry Andric OS << getExpressionTraitName(E->getTrait()) << '('; 22100b57cec5SDimitry Andric PrintExpr(E->getQueriedExpression()); 22110b57cec5SDimitry Andric OS << ')'; 22120b57cec5SDimitry Andric } 22130b57cec5SDimitry Andric 22140b57cec5SDimitry Andric void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { 22150b57cec5SDimitry Andric OS << "noexcept("; 22160b57cec5SDimitry Andric PrintExpr(E->getOperand()); 22170b57cec5SDimitry Andric OS << ")"; 22180b57cec5SDimitry Andric } 22190b57cec5SDimitry Andric 22200b57cec5SDimitry Andric void StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) { 22210b57cec5SDimitry Andric PrintExpr(E->getPattern()); 22220b57cec5SDimitry Andric OS << "..."; 22230b57cec5SDimitry Andric } 22240b57cec5SDimitry Andric 22250b57cec5SDimitry Andric void StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) { 22260b57cec5SDimitry Andric OS << "sizeof...(" << *E->getPack() << ")"; 22270b57cec5SDimitry Andric } 22280b57cec5SDimitry Andric 22290b57cec5SDimitry Andric void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr( 22300b57cec5SDimitry Andric SubstNonTypeTemplateParmPackExpr *Node) { 22310b57cec5SDimitry Andric OS << *Node->getParameterPack(); 22320b57cec5SDimitry Andric } 22330b57cec5SDimitry Andric 22340b57cec5SDimitry Andric void StmtPrinter::VisitSubstNonTypeTemplateParmExpr( 22350b57cec5SDimitry Andric SubstNonTypeTemplateParmExpr *Node) { 22360b57cec5SDimitry Andric Visit(Node->getReplacement()); 22370b57cec5SDimitry Andric } 22380b57cec5SDimitry Andric 22390b57cec5SDimitry Andric void StmtPrinter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) { 22400b57cec5SDimitry Andric OS << *E->getParameterPack(); 22410b57cec5SDimitry Andric } 22420b57cec5SDimitry Andric 22430b57cec5SDimitry Andric void StmtPrinter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *Node){ 2244480093f4SDimitry Andric PrintExpr(Node->getSubExpr()); 22450b57cec5SDimitry Andric } 22460b57cec5SDimitry Andric 22470b57cec5SDimitry Andric void StmtPrinter::VisitCXXFoldExpr(CXXFoldExpr *E) { 22480b57cec5SDimitry Andric OS << "("; 22490b57cec5SDimitry Andric if (E->getLHS()) { 22500b57cec5SDimitry Andric PrintExpr(E->getLHS()); 22510b57cec5SDimitry Andric OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " "; 22520b57cec5SDimitry Andric } 22530b57cec5SDimitry Andric OS << "..."; 22540b57cec5SDimitry Andric if (E->getRHS()) { 22550b57cec5SDimitry Andric OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " "; 22560b57cec5SDimitry Andric PrintExpr(E->getRHS()); 22570b57cec5SDimitry Andric } 22580b57cec5SDimitry Andric OS << ")"; 22590b57cec5SDimitry Andric } 22600b57cec5SDimitry Andric 2261a7dea167SDimitry Andric void StmtPrinter::VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) { 2262a7dea167SDimitry Andric NestedNameSpecifierLoc NNS = E->getNestedNameSpecifierLoc(); 2263a7dea167SDimitry Andric if (NNS) 2264a7dea167SDimitry Andric NNS.getNestedNameSpecifier()->print(OS, Policy); 2265a7dea167SDimitry Andric if (E->getTemplateKWLoc().isValid()) 2266a7dea167SDimitry Andric OS << "template "; 2267a7dea167SDimitry Andric OS << E->getFoundDecl()->getName(); 2268a7dea167SDimitry Andric printTemplateArgumentList(OS, E->getTemplateArgsAsWritten()->arguments(), 2269a7dea167SDimitry Andric Policy); 2270a7dea167SDimitry Andric } 2271a7dea167SDimitry Andric 2272*55e4f9d5SDimitry Andric void StmtPrinter::VisitRequiresExpr(RequiresExpr *E) { 2273*55e4f9d5SDimitry Andric OS << "requires "; 2274*55e4f9d5SDimitry Andric auto LocalParameters = E->getLocalParameters(); 2275*55e4f9d5SDimitry Andric if (!LocalParameters.empty()) { 2276*55e4f9d5SDimitry Andric OS << "("; 2277*55e4f9d5SDimitry Andric for (ParmVarDecl *LocalParam : LocalParameters) { 2278*55e4f9d5SDimitry Andric PrintRawDecl(LocalParam); 2279*55e4f9d5SDimitry Andric if (LocalParam != LocalParameters.back()) 2280*55e4f9d5SDimitry Andric OS << ", "; 2281*55e4f9d5SDimitry Andric } 2282*55e4f9d5SDimitry Andric 2283*55e4f9d5SDimitry Andric OS << ") "; 2284*55e4f9d5SDimitry Andric } 2285*55e4f9d5SDimitry Andric OS << "{ "; 2286*55e4f9d5SDimitry Andric auto Requirements = E->getRequirements(); 2287*55e4f9d5SDimitry Andric for (concepts::Requirement *Req : Requirements) { 2288*55e4f9d5SDimitry Andric if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) { 2289*55e4f9d5SDimitry Andric if (TypeReq->isSubstitutionFailure()) 2290*55e4f9d5SDimitry Andric OS << "<<error-type>>"; 2291*55e4f9d5SDimitry Andric else 2292*55e4f9d5SDimitry Andric TypeReq->getType()->getType().print(OS, Policy); 2293*55e4f9d5SDimitry Andric } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) { 2294*55e4f9d5SDimitry Andric if (ExprReq->isCompound()) 2295*55e4f9d5SDimitry Andric OS << "{ "; 2296*55e4f9d5SDimitry Andric if (ExprReq->isExprSubstitutionFailure()) 2297*55e4f9d5SDimitry Andric OS << "<<error-expression>>"; 2298*55e4f9d5SDimitry Andric else 2299*55e4f9d5SDimitry Andric PrintExpr(ExprReq->getExpr()); 2300*55e4f9d5SDimitry Andric if (ExprReq->isCompound()) { 2301*55e4f9d5SDimitry Andric OS << " }"; 2302*55e4f9d5SDimitry Andric if (ExprReq->getNoexceptLoc().isValid()) 2303*55e4f9d5SDimitry Andric OS << " noexcept"; 2304*55e4f9d5SDimitry Andric const auto &RetReq = ExprReq->getReturnTypeRequirement(); 2305*55e4f9d5SDimitry Andric if (!RetReq.isEmpty()) { 2306*55e4f9d5SDimitry Andric OS << " -> "; 2307*55e4f9d5SDimitry Andric if (RetReq.isSubstitutionFailure()) 2308*55e4f9d5SDimitry Andric OS << "<<error-type>>"; 2309*55e4f9d5SDimitry Andric else if (RetReq.isTypeConstraint()) 2310*55e4f9d5SDimitry Andric RetReq.getTypeConstraint()->print(OS, Policy); 2311*55e4f9d5SDimitry Andric } 2312*55e4f9d5SDimitry Andric } 2313*55e4f9d5SDimitry Andric } else { 2314*55e4f9d5SDimitry Andric auto *NestedReq = cast<concepts::NestedRequirement>(Req); 2315*55e4f9d5SDimitry Andric OS << "requires "; 2316*55e4f9d5SDimitry Andric if (NestedReq->isSubstitutionFailure()) 2317*55e4f9d5SDimitry Andric OS << "<<error-expression>>"; 2318*55e4f9d5SDimitry Andric else 2319*55e4f9d5SDimitry Andric PrintExpr(NestedReq->getConstraintExpr()); 2320*55e4f9d5SDimitry Andric } 2321*55e4f9d5SDimitry Andric OS << "; "; 2322*55e4f9d5SDimitry Andric } 2323*55e4f9d5SDimitry Andric OS << "}"; 2324*55e4f9d5SDimitry Andric } 2325*55e4f9d5SDimitry Andric 23260b57cec5SDimitry Andric // C++ Coroutines TS 23270b57cec5SDimitry Andric 23280b57cec5SDimitry Andric void StmtPrinter::VisitCoroutineBodyStmt(CoroutineBodyStmt *S) { 23290b57cec5SDimitry Andric Visit(S->getBody()); 23300b57cec5SDimitry Andric } 23310b57cec5SDimitry Andric 23320b57cec5SDimitry Andric void StmtPrinter::VisitCoreturnStmt(CoreturnStmt *S) { 23330b57cec5SDimitry Andric OS << "co_return"; 23340b57cec5SDimitry Andric if (S->getOperand()) { 23350b57cec5SDimitry Andric OS << " "; 23360b57cec5SDimitry Andric Visit(S->getOperand()); 23370b57cec5SDimitry Andric } 23380b57cec5SDimitry Andric OS << ";"; 23390b57cec5SDimitry Andric } 23400b57cec5SDimitry Andric 23410b57cec5SDimitry Andric void StmtPrinter::VisitCoawaitExpr(CoawaitExpr *S) { 23420b57cec5SDimitry Andric OS << "co_await "; 23430b57cec5SDimitry Andric PrintExpr(S->getOperand()); 23440b57cec5SDimitry Andric } 23450b57cec5SDimitry Andric 23460b57cec5SDimitry Andric void StmtPrinter::VisitDependentCoawaitExpr(DependentCoawaitExpr *S) { 23470b57cec5SDimitry Andric OS << "co_await "; 23480b57cec5SDimitry Andric PrintExpr(S->getOperand()); 23490b57cec5SDimitry Andric } 23500b57cec5SDimitry Andric 23510b57cec5SDimitry Andric void StmtPrinter::VisitCoyieldExpr(CoyieldExpr *S) { 23520b57cec5SDimitry Andric OS << "co_yield "; 23530b57cec5SDimitry Andric PrintExpr(S->getOperand()); 23540b57cec5SDimitry Andric } 23550b57cec5SDimitry Andric 23560b57cec5SDimitry Andric // Obj-C 23570b57cec5SDimitry Andric 23580b57cec5SDimitry Andric void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) { 23590b57cec5SDimitry Andric OS << "@"; 23600b57cec5SDimitry Andric VisitStringLiteral(Node->getString()); 23610b57cec5SDimitry Andric } 23620b57cec5SDimitry Andric 23630b57cec5SDimitry Andric void StmtPrinter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) { 23640b57cec5SDimitry Andric OS << "@"; 23650b57cec5SDimitry Andric Visit(E->getSubExpr()); 23660b57cec5SDimitry Andric } 23670b57cec5SDimitry Andric 23680b57cec5SDimitry Andric void StmtPrinter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) { 23690b57cec5SDimitry Andric OS << "@[ "; 23700b57cec5SDimitry Andric ObjCArrayLiteral::child_range Ch = E->children(); 23710b57cec5SDimitry Andric for (auto I = Ch.begin(), E = Ch.end(); I != E; ++I) { 23720b57cec5SDimitry Andric if (I != Ch.begin()) 23730b57cec5SDimitry Andric OS << ", "; 23740b57cec5SDimitry Andric Visit(*I); 23750b57cec5SDimitry Andric } 23760b57cec5SDimitry Andric OS << " ]"; 23770b57cec5SDimitry Andric } 23780b57cec5SDimitry Andric 23790b57cec5SDimitry Andric void StmtPrinter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) { 23800b57cec5SDimitry Andric OS << "@{ "; 23810b57cec5SDimitry Andric for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) { 23820b57cec5SDimitry Andric if (I > 0) 23830b57cec5SDimitry Andric OS << ", "; 23840b57cec5SDimitry Andric 23850b57cec5SDimitry Andric ObjCDictionaryElement Element = E->getKeyValueElement(I); 23860b57cec5SDimitry Andric Visit(Element.Key); 23870b57cec5SDimitry Andric OS << " : "; 23880b57cec5SDimitry Andric Visit(Element.Value); 23890b57cec5SDimitry Andric if (Element.isPackExpansion()) 23900b57cec5SDimitry Andric OS << "..."; 23910b57cec5SDimitry Andric } 23920b57cec5SDimitry Andric OS << " }"; 23930b57cec5SDimitry Andric } 23940b57cec5SDimitry Andric 23950b57cec5SDimitry Andric void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) { 23960b57cec5SDimitry Andric OS << "@encode("; 23970b57cec5SDimitry Andric Node->getEncodedType().print(OS, Policy); 23980b57cec5SDimitry Andric OS << ')'; 23990b57cec5SDimitry Andric } 24000b57cec5SDimitry Andric 24010b57cec5SDimitry Andric void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) { 24020b57cec5SDimitry Andric OS << "@selector("; 24030b57cec5SDimitry Andric Node->getSelector().print(OS); 24040b57cec5SDimitry Andric OS << ')'; 24050b57cec5SDimitry Andric } 24060b57cec5SDimitry Andric 24070b57cec5SDimitry Andric void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) { 24080b57cec5SDimitry Andric OS << "@protocol(" << *Node->getProtocol() << ')'; 24090b57cec5SDimitry Andric } 24100b57cec5SDimitry Andric 24110b57cec5SDimitry Andric void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) { 24120b57cec5SDimitry Andric OS << "["; 24130b57cec5SDimitry Andric switch (Mess->getReceiverKind()) { 24140b57cec5SDimitry Andric case ObjCMessageExpr::Instance: 24150b57cec5SDimitry Andric PrintExpr(Mess->getInstanceReceiver()); 24160b57cec5SDimitry Andric break; 24170b57cec5SDimitry Andric 24180b57cec5SDimitry Andric case ObjCMessageExpr::Class: 24190b57cec5SDimitry Andric Mess->getClassReceiver().print(OS, Policy); 24200b57cec5SDimitry Andric break; 24210b57cec5SDimitry Andric 24220b57cec5SDimitry Andric case ObjCMessageExpr::SuperInstance: 24230b57cec5SDimitry Andric case ObjCMessageExpr::SuperClass: 24240b57cec5SDimitry Andric OS << "Super"; 24250b57cec5SDimitry Andric break; 24260b57cec5SDimitry Andric } 24270b57cec5SDimitry Andric 24280b57cec5SDimitry Andric OS << ' '; 24290b57cec5SDimitry Andric Selector selector = Mess->getSelector(); 24300b57cec5SDimitry Andric if (selector.isUnarySelector()) { 24310b57cec5SDimitry Andric OS << selector.getNameForSlot(0); 24320b57cec5SDimitry Andric } else { 24330b57cec5SDimitry Andric for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) { 24340b57cec5SDimitry Andric if (i < selector.getNumArgs()) { 24350b57cec5SDimitry Andric if (i > 0) OS << ' '; 24360b57cec5SDimitry Andric if (selector.getIdentifierInfoForSlot(i)) 24370b57cec5SDimitry Andric OS << selector.getIdentifierInfoForSlot(i)->getName() << ':'; 24380b57cec5SDimitry Andric else 24390b57cec5SDimitry Andric OS << ":"; 24400b57cec5SDimitry Andric } 24410b57cec5SDimitry Andric else OS << ", "; // Handle variadic methods. 24420b57cec5SDimitry Andric 24430b57cec5SDimitry Andric PrintExpr(Mess->getArg(i)); 24440b57cec5SDimitry Andric } 24450b57cec5SDimitry Andric } 24460b57cec5SDimitry Andric OS << "]"; 24470b57cec5SDimitry Andric } 24480b57cec5SDimitry Andric 24490b57cec5SDimitry Andric void StmtPrinter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) { 24500b57cec5SDimitry Andric OS << (Node->getValue() ? "__objc_yes" : "__objc_no"); 24510b57cec5SDimitry Andric } 24520b57cec5SDimitry Andric 24530b57cec5SDimitry Andric void 24540b57cec5SDimitry Andric StmtPrinter::VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) { 24550b57cec5SDimitry Andric PrintExpr(E->getSubExpr()); 24560b57cec5SDimitry Andric } 24570b57cec5SDimitry Andric 24580b57cec5SDimitry Andric void 24590b57cec5SDimitry Andric StmtPrinter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) { 24600b57cec5SDimitry Andric OS << '(' << E->getBridgeKindName(); 24610b57cec5SDimitry Andric E->getType().print(OS, Policy); 24620b57cec5SDimitry Andric OS << ')'; 24630b57cec5SDimitry Andric PrintExpr(E->getSubExpr()); 24640b57cec5SDimitry Andric } 24650b57cec5SDimitry Andric 24660b57cec5SDimitry Andric void StmtPrinter::VisitBlockExpr(BlockExpr *Node) { 24670b57cec5SDimitry Andric BlockDecl *BD = Node->getBlockDecl(); 24680b57cec5SDimitry Andric OS << "^"; 24690b57cec5SDimitry Andric 24700b57cec5SDimitry Andric const FunctionType *AFT = Node->getFunctionType(); 24710b57cec5SDimitry Andric 24720b57cec5SDimitry Andric if (isa<FunctionNoProtoType>(AFT)) { 24730b57cec5SDimitry Andric OS << "()"; 24740b57cec5SDimitry Andric } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) { 24750b57cec5SDimitry Andric OS << '('; 24760b57cec5SDimitry Andric for (BlockDecl::param_iterator AI = BD->param_begin(), 24770b57cec5SDimitry Andric E = BD->param_end(); AI != E; ++AI) { 24780b57cec5SDimitry Andric if (AI != BD->param_begin()) OS << ", "; 24790b57cec5SDimitry Andric std::string ParamStr = (*AI)->getNameAsString(); 24800b57cec5SDimitry Andric (*AI)->getType().print(OS, Policy, ParamStr); 24810b57cec5SDimitry Andric } 24820b57cec5SDimitry Andric 24830b57cec5SDimitry Andric const auto *FT = cast<FunctionProtoType>(AFT); 24840b57cec5SDimitry Andric if (FT->isVariadic()) { 24850b57cec5SDimitry Andric if (!BD->param_empty()) OS << ", "; 24860b57cec5SDimitry Andric OS << "..."; 24870b57cec5SDimitry Andric } 24880b57cec5SDimitry Andric OS << ')'; 24890b57cec5SDimitry Andric } 24900b57cec5SDimitry Andric OS << "{ }"; 24910b57cec5SDimitry Andric } 24920b57cec5SDimitry Andric 24930b57cec5SDimitry Andric void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) { 24940b57cec5SDimitry Andric PrintExpr(Node->getSourceExpr()); 24950b57cec5SDimitry Andric } 24960b57cec5SDimitry Andric 24970b57cec5SDimitry Andric void StmtPrinter::VisitTypoExpr(TypoExpr *Node) { 24980b57cec5SDimitry Andric // TODO: Print something reasonable for a TypoExpr, if necessary. 24990b57cec5SDimitry Andric llvm_unreachable("Cannot print TypoExpr nodes"); 25000b57cec5SDimitry Andric } 25010b57cec5SDimitry Andric 25020b57cec5SDimitry Andric void StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) { 25030b57cec5SDimitry Andric OS << "__builtin_astype("; 25040b57cec5SDimitry Andric PrintExpr(Node->getSrcExpr()); 25050b57cec5SDimitry Andric OS << ", "; 25060b57cec5SDimitry Andric Node->getType().print(OS, Policy); 25070b57cec5SDimitry Andric OS << ")"; 25080b57cec5SDimitry Andric } 25090b57cec5SDimitry Andric 25100b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 25110b57cec5SDimitry Andric // Stmt method implementations 25120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 25130b57cec5SDimitry Andric 25140b57cec5SDimitry Andric void Stmt::dumpPretty(const ASTContext &Context) const { 25150b57cec5SDimitry Andric printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts())); 25160b57cec5SDimitry Andric } 25170b57cec5SDimitry Andric 25180b57cec5SDimitry Andric void Stmt::printPretty(raw_ostream &Out, PrinterHelper *Helper, 25190b57cec5SDimitry Andric const PrintingPolicy &Policy, unsigned Indentation, 25200b57cec5SDimitry Andric StringRef NL, const ASTContext *Context) const { 25210b57cec5SDimitry Andric StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context); 25220b57cec5SDimitry Andric P.Visit(const_cast<Stmt *>(this)); 25230b57cec5SDimitry Andric } 25240b57cec5SDimitry Andric 25250b57cec5SDimitry Andric void Stmt::printJson(raw_ostream &Out, PrinterHelper *Helper, 25260b57cec5SDimitry Andric const PrintingPolicy &Policy, bool AddQuotes) const { 25270b57cec5SDimitry Andric std::string Buf; 25280b57cec5SDimitry Andric llvm::raw_string_ostream TempOut(Buf); 25290b57cec5SDimitry Andric 25300b57cec5SDimitry Andric printPretty(TempOut, Helper, Policy); 25310b57cec5SDimitry Andric 25320b57cec5SDimitry Andric Out << JsonFormat(TempOut.str(), AddQuotes); 25330b57cec5SDimitry Andric } 25340b57cec5SDimitry Andric 25350b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 25360b57cec5SDimitry Andric // PrinterHelper 25370b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 25380b57cec5SDimitry Andric 25390b57cec5SDimitry Andric // Implement virtual destructor. 25400b57cec5SDimitry Andric PrinterHelper::~PrinterHelper() = default; 2541