1*0b57cec5SDimitry Andric //===- StmtPrinter.cpp - Printing implementation for Stmt ASTs ------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file implements the Stmt::dumpPretty/Stmt::printPretty methods, which 10*0b57cec5SDimitry Andric // pretty print the AST back out to C code. 11*0b57cec5SDimitry Andric // 12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric #include "clang/AST/ASTContext.h" 15*0b57cec5SDimitry Andric #include "clang/AST/Attr.h" 16*0b57cec5SDimitry Andric #include "clang/AST/Decl.h" 17*0b57cec5SDimitry Andric #include "clang/AST/DeclBase.h" 18*0b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h" 19*0b57cec5SDimitry Andric #include "clang/AST/DeclObjC.h" 20*0b57cec5SDimitry Andric #include "clang/AST/DeclOpenMP.h" 21*0b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h" 22*0b57cec5SDimitry Andric #include "clang/AST/Expr.h" 23*0b57cec5SDimitry Andric #include "clang/AST/ExprCXX.h" 24*0b57cec5SDimitry Andric #include "clang/AST/ExprObjC.h" 25*0b57cec5SDimitry Andric #include "clang/AST/ExprOpenMP.h" 26*0b57cec5SDimitry Andric #include "clang/AST/NestedNameSpecifier.h" 27*0b57cec5SDimitry Andric #include "clang/AST/OpenMPClause.h" 28*0b57cec5SDimitry Andric #include "clang/AST/PrettyPrinter.h" 29*0b57cec5SDimitry Andric #include "clang/AST/Stmt.h" 30*0b57cec5SDimitry Andric #include "clang/AST/StmtCXX.h" 31*0b57cec5SDimitry Andric #include "clang/AST/StmtObjC.h" 32*0b57cec5SDimitry Andric #include "clang/AST/StmtOpenMP.h" 33*0b57cec5SDimitry Andric #include "clang/AST/StmtVisitor.h" 34*0b57cec5SDimitry Andric #include "clang/AST/TemplateBase.h" 35*0b57cec5SDimitry Andric #include "clang/AST/Type.h" 36*0b57cec5SDimitry Andric #include "clang/Basic/CharInfo.h" 37*0b57cec5SDimitry Andric #include "clang/Basic/ExpressionTraits.h" 38*0b57cec5SDimitry Andric #include "clang/Basic/IdentifierTable.h" 39*0b57cec5SDimitry Andric #include "clang/Basic/JsonSupport.h" 40*0b57cec5SDimitry Andric #include "clang/Basic/LLVM.h" 41*0b57cec5SDimitry Andric #include "clang/Basic/Lambda.h" 42*0b57cec5SDimitry Andric #include "clang/Basic/OpenMPKinds.h" 43*0b57cec5SDimitry Andric #include "clang/Basic/OperatorKinds.h" 44*0b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h" 45*0b57cec5SDimitry Andric #include "clang/Basic/TypeTraits.h" 46*0b57cec5SDimitry Andric #include "clang/Lex/Lexer.h" 47*0b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 48*0b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h" 49*0b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 50*0b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 51*0b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 52*0b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 53*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 54*0b57cec5SDimitry Andric #include "llvm/Support/Format.h" 55*0b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 56*0b57cec5SDimitry Andric #include <cassert> 57*0b57cec5SDimitry Andric #include <string> 58*0b57cec5SDimitry Andric 59*0b57cec5SDimitry Andric using namespace clang; 60*0b57cec5SDimitry Andric 61*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 62*0b57cec5SDimitry Andric // StmtPrinter Visitor 63*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 64*0b57cec5SDimitry Andric 65*0b57cec5SDimitry Andric namespace { 66*0b57cec5SDimitry Andric 67*0b57cec5SDimitry Andric class StmtPrinter : public StmtVisitor<StmtPrinter> { 68*0b57cec5SDimitry Andric raw_ostream &OS; 69*0b57cec5SDimitry Andric unsigned IndentLevel; 70*0b57cec5SDimitry Andric PrinterHelper* Helper; 71*0b57cec5SDimitry Andric PrintingPolicy Policy; 72*0b57cec5SDimitry Andric std::string NL; 73*0b57cec5SDimitry Andric const ASTContext *Context; 74*0b57cec5SDimitry Andric 75*0b57cec5SDimitry Andric public: 76*0b57cec5SDimitry Andric StmtPrinter(raw_ostream &os, PrinterHelper *helper, 77*0b57cec5SDimitry Andric const PrintingPolicy &Policy, unsigned Indentation = 0, 78*0b57cec5SDimitry Andric StringRef NL = "\n", 79*0b57cec5SDimitry Andric const ASTContext *Context = nullptr) 80*0b57cec5SDimitry Andric : OS(os), IndentLevel(Indentation), Helper(helper), Policy(Policy), 81*0b57cec5SDimitry Andric NL(NL), Context(Context) {} 82*0b57cec5SDimitry Andric 83*0b57cec5SDimitry Andric void PrintStmt(Stmt *S) { 84*0b57cec5SDimitry Andric PrintStmt(S, Policy.Indentation); 85*0b57cec5SDimitry Andric } 86*0b57cec5SDimitry Andric 87*0b57cec5SDimitry Andric void PrintStmt(Stmt *S, int SubIndent) { 88*0b57cec5SDimitry Andric IndentLevel += SubIndent; 89*0b57cec5SDimitry Andric if (S && isa<Expr>(S)) { 90*0b57cec5SDimitry Andric // If this is an expr used in a stmt context, indent and newline it. 91*0b57cec5SDimitry Andric Indent(); 92*0b57cec5SDimitry Andric Visit(S); 93*0b57cec5SDimitry Andric OS << ";" << NL; 94*0b57cec5SDimitry Andric } else if (S) { 95*0b57cec5SDimitry Andric Visit(S); 96*0b57cec5SDimitry Andric } else { 97*0b57cec5SDimitry Andric Indent() << "<<<NULL STATEMENT>>>" << NL; 98*0b57cec5SDimitry Andric } 99*0b57cec5SDimitry Andric IndentLevel -= SubIndent; 100*0b57cec5SDimitry Andric } 101*0b57cec5SDimitry Andric 102*0b57cec5SDimitry Andric void PrintInitStmt(Stmt *S, unsigned PrefixWidth) { 103*0b57cec5SDimitry Andric // FIXME: Cope better with odd prefix widths. 104*0b57cec5SDimitry Andric IndentLevel += (PrefixWidth + 1) / 2; 105*0b57cec5SDimitry Andric if (auto *DS = dyn_cast<DeclStmt>(S)) 106*0b57cec5SDimitry Andric PrintRawDeclStmt(DS); 107*0b57cec5SDimitry Andric else 108*0b57cec5SDimitry Andric PrintExpr(cast<Expr>(S)); 109*0b57cec5SDimitry Andric OS << "; "; 110*0b57cec5SDimitry Andric IndentLevel -= (PrefixWidth + 1) / 2; 111*0b57cec5SDimitry Andric } 112*0b57cec5SDimitry Andric 113*0b57cec5SDimitry Andric void PrintControlledStmt(Stmt *S) { 114*0b57cec5SDimitry Andric if (auto *CS = dyn_cast<CompoundStmt>(S)) { 115*0b57cec5SDimitry Andric OS << " "; 116*0b57cec5SDimitry Andric PrintRawCompoundStmt(CS); 117*0b57cec5SDimitry Andric OS << NL; 118*0b57cec5SDimitry Andric } else { 119*0b57cec5SDimitry Andric OS << NL; 120*0b57cec5SDimitry Andric PrintStmt(S); 121*0b57cec5SDimitry Andric } 122*0b57cec5SDimitry Andric } 123*0b57cec5SDimitry Andric 124*0b57cec5SDimitry Andric void PrintRawCompoundStmt(CompoundStmt *S); 125*0b57cec5SDimitry Andric void PrintRawDecl(Decl *D); 126*0b57cec5SDimitry Andric void PrintRawDeclStmt(const DeclStmt *S); 127*0b57cec5SDimitry Andric void PrintRawIfStmt(IfStmt *If); 128*0b57cec5SDimitry Andric void PrintRawCXXCatchStmt(CXXCatchStmt *Catch); 129*0b57cec5SDimitry Andric void PrintCallArgs(CallExpr *E); 130*0b57cec5SDimitry Andric void PrintRawSEHExceptHandler(SEHExceptStmt *S); 131*0b57cec5SDimitry Andric void PrintRawSEHFinallyStmt(SEHFinallyStmt *S); 132*0b57cec5SDimitry Andric void PrintOMPExecutableDirective(OMPExecutableDirective *S, 133*0b57cec5SDimitry Andric bool ForceNoStmt = false); 134*0b57cec5SDimitry Andric 135*0b57cec5SDimitry Andric void PrintExpr(Expr *E) { 136*0b57cec5SDimitry Andric if (E) 137*0b57cec5SDimitry Andric Visit(E); 138*0b57cec5SDimitry Andric else 139*0b57cec5SDimitry Andric OS << "<null expr>"; 140*0b57cec5SDimitry Andric } 141*0b57cec5SDimitry Andric 142*0b57cec5SDimitry Andric raw_ostream &Indent(int Delta = 0) { 143*0b57cec5SDimitry Andric for (int i = 0, e = IndentLevel+Delta; i < e; ++i) 144*0b57cec5SDimitry Andric OS << " "; 145*0b57cec5SDimitry Andric return OS; 146*0b57cec5SDimitry Andric } 147*0b57cec5SDimitry Andric 148*0b57cec5SDimitry Andric void Visit(Stmt* S) { 149*0b57cec5SDimitry Andric if (Helper && Helper->handledStmt(S,OS)) 150*0b57cec5SDimitry Andric return; 151*0b57cec5SDimitry Andric else StmtVisitor<StmtPrinter>::Visit(S); 152*0b57cec5SDimitry Andric } 153*0b57cec5SDimitry Andric 154*0b57cec5SDimitry Andric void VisitStmt(Stmt *Node) LLVM_ATTRIBUTE_UNUSED { 155*0b57cec5SDimitry Andric Indent() << "<<unknown stmt type>>" << NL; 156*0b57cec5SDimitry Andric } 157*0b57cec5SDimitry Andric 158*0b57cec5SDimitry Andric void VisitExpr(Expr *Node) LLVM_ATTRIBUTE_UNUSED { 159*0b57cec5SDimitry Andric OS << "<<unknown expr type>>"; 160*0b57cec5SDimitry Andric } 161*0b57cec5SDimitry Andric 162*0b57cec5SDimitry Andric void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node); 163*0b57cec5SDimitry Andric 164*0b57cec5SDimitry Andric #define ABSTRACT_STMT(CLASS) 165*0b57cec5SDimitry Andric #define STMT(CLASS, PARENT) \ 166*0b57cec5SDimitry Andric void Visit##CLASS(CLASS *Node); 167*0b57cec5SDimitry Andric #include "clang/AST/StmtNodes.inc" 168*0b57cec5SDimitry Andric }; 169*0b57cec5SDimitry Andric 170*0b57cec5SDimitry Andric } // namespace 171*0b57cec5SDimitry Andric 172*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 173*0b57cec5SDimitry Andric // Stmt printing methods. 174*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 175*0b57cec5SDimitry Andric 176*0b57cec5SDimitry Andric /// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and 177*0b57cec5SDimitry Andric /// with no newline after the }. 178*0b57cec5SDimitry Andric void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) { 179*0b57cec5SDimitry Andric OS << "{" << NL; 180*0b57cec5SDimitry Andric for (auto *I : Node->body()) 181*0b57cec5SDimitry Andric PrintStmt(I); 182*0b57cec5SDimitry Andric 183*0b57cec5SDimitry Andric Indent() << "}"; 184*0b57cec5SDimitry Andric } 185*0b57cec5SDimitry Andric 186*0b57cec5SDimitry Andric void StmtPrinter::PrintRawDecl(Decl *D) { 187*0b57cec5SDimitry Andric D->print(OS, Policy, IndentLevel); 188*0b57cec5SDimitry Andric } 189*0b57cec5SDimitry Andric 190*0b57cec5SDimitry Andric void StmtPrinter::PrintRawDeclStmt(const DeclStmt *S) { 191*0b57cec5SDimitry Andric SmallVector<Decl *, 2> Decls(S->decls()); 192*0b57cec5SDimitry Andric Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel); 193*0b57cec5SDimitry Andric } 194*0b57cec5SDimitry Andric 195*0b57cec5SDimitry Andric void StmtPrinter::VisitNullStmt(NullStmt *Node) { 196*0b57cec5SDimitry Andric Indent() << ";" << NL; 197*0b57cec5SDimitry Andric } 198*0b57cec5SDimitry Andric 199*0b57cec5SDimitry Andric void StmtPrinter::VisitDeclStmt(DeclStmt *Node) { 200*0b57cec5SDimitry Andric Indent(); 201*0b57cec5SDimitry Andric PrintRawDeclStmt(Node); 202*0b57cec5SDimitry Andric OS << ";" << NL; 203*0b57cec5SDimitry Andric } 204*0b57cec5SDimitry Andric 205*0b57cec5SDimitry Andric void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) { 206*0b57cec5SDimitry Andric Indent(); 207*0b57cec5SDimitry Andric PrintRawCompoundStmt(Node); 208*0b57cec5SDimitry Andric OS << "" << NL; 209*0b57cec5SDimitry Andric } 210*0b57cec5SDimitry Andric 211*0b57cec5SDimitry Andric void StmtPrinter::VisitCaseStmt(CaseStmt *Node) { 212*0b57cec5SDimitry Andric Indent(-1) << "case "; 213*0b57cec5SDimitry Andric PrintExpr(Node->getLHS()); 214*0b57cec5SDimitry Andric if (Node->getRHS()) { 215*0b57cec5SDimitry Andric OS << " ... "; 216*0b57cec5SDimitry Andric PrintExpr(Node->getRHS()); 217*0b57cec5SDimitry Andric } 218*0b57cec5SDimitry Andric OS << ":" << NL; 219*0b57cec5SDimitry Andric 220*0b57cec5SDimitry Andric PrintStmt(Node->getSubStmt(), 0); 221*0b57cec5SDimitry Andric } 222*0b57cec5SDimitry Andric 223*0b57cec5SDimitry Andric void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) { 224*0b57cec5SDimitry Andric Indent(-1) << "default:" << NL; 225*0b57cec5SDimitry Andric PrintStmt(Node->getSubStmt(), 0); 226*0b57cec5SDimitry Andric } 227*0b57cec5SDimitry Andric 228*0b57cec5SDimitry Andric void StmtPrinter::VisitLabelStmt(LabelStmt *Node) { 229*0b57cec5SDimitry Andric Indent(-1) << Node->getName() << ":" << NL; 230*0b57cec5SDimitry Andric PrintStmt(Node->getSubStmt(), 0); 231*0b57cec5SDimitry Andric } 232*0b57cec5SDimitry Andric 233*0b57cec5SDimitry Andric void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) { 234*0b57cec5SDimitry Andric for (const auto *Attr : Node->getAttrs()) { 235*0b57cec5SDimitry Andric Attr->printPretty(OS, Policy); 236*0b57cec5SDimitry Andric } 237*0b57cec5SDimitry Andric 238*0b57cec5SDimitry Andric PrintStmt(Node->getSubStmt(), 0); 239*0b57cec5SDimitry Andric } 240*0b57cec5SDimitry Andric 241*0b57cec5SDimitry Andric void StmtPrinter::PrintRawIfStmt(IfStmt *If) { 242*0b57cec5SDimitry Andric OS << "if ("; 243*0b57cec5SDimitry Andric if (If->getInit()) 244*0b57cec5SDimitry Andric PrintInitStmt(If->getInit(), 4); 245*0b57cec5SDimitry Andric if (const DeclStmt *DS = If->getConditionVariableDeclStmt()) 246*0b57cec5SDimitry Andric PrintRawDeclStmt(DS); 247*0b57cec5SDimitry Andric else 248*0b57cec5SDimitry Andric PrintExpr(If->getCond()); 249*0b57cec5SDimitry Andric OS << ')'; 250*0b57cec5SDimitry Andric 251*0b57cec5SDimitry Andric if (auto *CS = dyn_cast<CompoundStmt>(If->getThen())) { 252*0b57cec5SDimitry Andric OS << ' '; 253*0b57cec5SDimitry Andric PrintRawCompoundStmt(CS); 254*0b57cec5SDimitry Andric OS << (If->getElse() ? " " : NL); 255*0b57cec5SDimitry Andric } else { 256*0b57cec5SDimitry Andric OS << NL; 257*0b57cec5SDimitry Andric PrintStmt(If->getThen()); 258*0b57cec5SDimitry Andric if (If->getElse()) Indent(); 259*0b57cec5SDimitry Andric } 260*0b57cec5SDimitry Andric 261*0b57cec5SDimitry Andric if (Stmt *Else = If->getElse()) { 262*0b57cec5SDimitry Andric OS << "else"; 263*0b57cec5SDimitry Andric 264*0b57cec5SDimitry Andric if (auto *CS = dyn_cast<CompoundStmt>(Else)) { 265*0b57cec5SDimitry Andric OS << ' '; 266*0b57cec5SDimitry Andric PrintRawCompoundStmt(CS); 267*0b57cec5SDimitry Andric OS << NL; 268*0b57cec5SDimitry Andric } else if (auto *ElseIf = dyn_cast<IfStmt>(Else)) { 269*0b57cec5SDimitry Andric OS << ' '; 270*0b57cec5SDimitry Andric PrintRawIfStmt(ElseIf); 271*0b57cec5SDimitry Andric } else { 272*0b57cec5SDimitry Andric OS << NL; 273*0b57cec5SDimitry Andric PrintStmt(If->getElse()); 274*0b57cec5SDimitry Andric } 275*0b57cec5SDimitry Andric } 276*0b57cec5SDimitry Andric } 277*0b57cec5SDimitry Andric 278*0b57cec5SDimitry Andric void StmtPrinter::VisitIfStmt(IfStmt *If) { 279*0b57cec5SDimitry Andric Indent(); 280*0b57cec5SDimitry Andric PrintRawIfStmt(If); 281*0b57cec5SDimitry Andric } 282*0b57cec5SDimitry Andric 283*0b57cec5SDimitry Andric void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) { 284*0b57cec5SDimitry Andric Indent() << "switch ("; 285*0b57cec5SDimitry Andric if (Node->getInit()) 286*0b57cec5SDimitry Andric PrintInitStmt(Node->getInit(), 8); 287*0b57cec5SDimitry Andric if (const DeclStmt *DS = Node->getConditionVariableDeclStmt()) 288*0b57cec5SDimitry Andric PrintRawDeclStmt(DS); 289*0b57cec5SDimitry Andric else 290*0b57cec5SDimitry Andric PrintExpr(Node->getCond()); 291*0b57cec5SDimitry Andric OS << ")"; 292*0b57cec5SDimitry Andric PrintControlledStmt(Node->getBody()); 293*0b57cec5SDimitry Andric } 294*0b57cec5SDimitry Andric 295*0b57cec5SDimitry Andric void StmtPrinter::VisitWhileStmt(WhileStmt *Node) { 296*0b57cec5SDimitry Andric Indent() << "while ("; 297*0b57cec5SDimitry Andric if (const DeclStmt *DS = Node->getConditionVariableDeclStmt()) 298*0b57cec5SDimitry Andric PrintRawDeclStmt(DS); 299*0b57cec5SDimitry Andric else 300*0b57cec5SDimitry Andric PrintExpr(Node->getCond()); 301*0b57cec5SDimitry Andric OS << ")" << NL; 302*0b57cec5SDimitry Andric PrintStmt(Node->getBody()); 303*0b57cec5SDimitry Andric } 304*0b57cec5SDimitry Andric 305*0b57cec5SDimitry Andric void StmtPrinter::VisitDoStmt(DoStmt *Node) { 306*0b57cec5SDimitry Andric Indent() << "do "; 307*0b57cec5SDimitry Andric if (auto *CS = dyn_cast<CompoundStmt>(Node->getBody())) { 308*0b57cec5SDimitry Andric PrintRawCompoundStmt(CS); 309*0b57cec5SDimitry Andric OS << " "; 310*0b57cec5SDimitry Andric } else { 311*0b57cec5SDimitry Andric OS << NL; 312*0b57cec5SDimitry Andric PrintStmt(Node->getBody()); 313*0b57cec5SDimitry Andric Indent(); 314*0b57cec5SDimitry Andric } 315*0b57cec5SDimitry Andric 316*0b57cec5SDimitry Andric OS << "while ("; 317*0b57cec5SDimitry Andric PrintExpr(Node->getCond()); 318*0b57cec5SDimitry Andric OS << ");" << NL; 319*0b57cec5SDimitry Andric } 320*0b57cec5SDimitry Andric 321*0b57cec5SDimitry Andric void StmtPrinter::VisitForStmt(ForStmt *Node) { 322*0b57cec5SDimitry Andric Indent() << "for ("; 323*0b57cec5SDimitry Andric if (Node->getInit()) 324*0b57cec5SDimitry Andric PrintInitStmt(Node->getInit(), 5); 325*0b57cec5SDimitry Andric else 326*0b57cec5SDimitry Andric OS << (Node->getCond() ? "; " : ";"); 327*0b57cec5SDimitry Andric if (Node->getCond()) 328*0b57cec5SDimitry Andric PrintExpr(Node->getCond()); 329*0b57cec5SDimitry Andric OS << ";"; 330*0b57cec5SDimitry Andric if (Node->getInc()) { 331*0b57cec5SDimitry Andric OS << " "; 332*0b57cec5SDimitry Andric PrintExpr(Node->getInc()); 333*0b57cec5SDimitry Andric } 334*0b57cec5SDimitry Andric OS << ")"; 335*0b57cec5SDimitry Andric PrintControlledStmt(Node->getBody()); 336*0b57cec5SDimitry Andric } 337*0b57cec5SDimitry Andric 338*0b57cec5SDimitry Andric void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) { 339*0b57cec5SDimitry Andric Indent() << "for ("; 340*0b57cec5SDimitry Andric if (auto *DS = dyn_cast<DeclStmt>(Node->getElement())) 341*0b57cec5SDimitry Andric PrintRawDeclStmt(DS); 342*0b57cec5SDimitry Andric else 343*0b57cec5SDimitry Andric PrintExpr(cast<Expr>(Node->getElement())); 344*0b57cec5SDimitry Andric OS << " in "; 345*0b57cec5SDimitry Andric PrintExpr(Node->getCollection()); 346*0b57cec5SDimitry Andric OS << ")"; 347*0b57cec5SDimitry Andric PrintControlledStmt(Node->getBody()); 348*0b57cec5SDimitry Andric } 349*0b57cec5SDimitry Andric 350*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXForRangeStmt(CXXForRangeStmt *Node) { 351*0b57cec5SDimitry Andric Indent() << "for ("; 352*0b57cec5SDimitry Andric if (Node->getInit()) 353*0b57cec5SDimitry Andric PrintInitStmt(Node->getInit(), 5); 354*0b57cec5SDimitry Andric PrintingPolicy SubPolicy(Policy); 355*0b57cec5SDimitry Andric SubPolicy.SuppressInitializers = true; 356*0b57cec5SDimitry Andric Node->getLoopVariable()->print(OS, SubPolicy, IndentLevel); 357*0b57cec5SDimitry Andric OS << " : "; 358*0b57cec5SDimitry Andric PrintExpr(Node->getRangeInit()); 359*0b57cec5SDimitry Andric OS << ")"; 360*0b57cec5SDimitry Andric PrintControlledStmt(Node->getBody()); 361*0b57cec5SDimitry Andric } 362*0b57cec5SDimitry Andric 363*0b57cec5SDimitry Andric void StmtPrinter::VisitMSDependentExistsStmt(MSDependentExistsStmt *Node) { 364*0b57cec5SDimitry Andric Indent(); 365*0b57cec5SDimitry Andric if (Node->isIfExists()) 366*0b57cec5SDimitry Andric OS << "__if_exists ("; 367*0b57cec5SDimitry Andric else 368*0b57cec5SDimitry Andric OS << "__if_not_exists ("; 369*0b57cec5SDimitry Andric 370*0b57cec5SDimitry Andric if (NestedNameSpecifier *Qualifier 371*0b57cec5SDimitry Andric = Node->getQualifierLoc().getNestedNameSpecifier()) 372*0b57cec5SDimitry Andric Qualifier->print(OS, Policy); 373*0b57cec5SDimitry Andric 374*0b57cec5SDimitry Andric OS << Node->getNameInfo() << ") "; 375*0b57cec5SDimitry Andric 376*0b57cec5SDimitry Andric PrintRawCompoundStmt(Node->getSubStmt()); 377*0b57cec5SDimitry Andric } 378*0b57cec5SDimitry Andric 379*0b57cec5SDimitry Andric void StmtPrinter::VisitGotoStmt(GotoStmt *Node) { 380*0b57cec5SDimitry Andric Indent() << "goto " << Node->getLabel()->getName() << ";"; 381*0b57cec5SDimitry Andric if (Policy.IncludeNewlines) OS << NL; 382*0b57cec5SDimitry Andric } 383*0b57cec5SDimitry Andric 384*0b57cec5SDimitry Andric void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) { 385*0b57cec5SDimitry Andric Indent() << "goto *"; 386*0b57cec5SDimitry Andric PrintExpr(Node->getTarget()); 387*0b57cec5SDimitry Andric OS << ";"; 388*0b57cec5SDimitry Andric if (Policy.IncludeNewlines) OS << NL; 389*0b57cec5SDimitry Andric } 390*0b57cec5SDimitry Andric 391*0b57cec5SDimitry Andric void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) { 392*0b57cec5SDimitry Andric Indent() << "continue;"; 393*0b57cec5SDimitry Andric if (Policy.IncludeNewlines) OS << NL; 394*0b57cec5SDimitry Andric } 395*0b57cec5SDimitry Andric 396*0b57cec5SDimitry Andric void StmtPrinter::VisitBreakStmt(BreakStmt *Node) { 397*0b57cec5SDimitry Andric Indent() << "break;"; 398*0b57cec5SDimitry Andric if (Policy.IncludeNewlines) OS << NL; 399*0b57cec5SDimitry Andric } 400*0b57cec5SDimitry Andric 401*0b57cec5SDimitry Andric void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) { 402*0b57cec5SDimitry Andric Indent() << "return"; 403*0b57cec5SDimitry Andric if (Node->getRetValue()) { 404*0b57cec5SDimitry Andric OS << " "; 405*0b57cec5SDimitry Andric PrintExpr(Node->getRetValue()); 406*0b57cec5SDimitry Andric } 407*0b57cec5SDimitry Andric OS << ";"; 408*0b57cec5SDimitry Andric if (Policy.IncludeNewlines) OS << NL; 409*0b57cec5SDimitry Andric } 410*0b57cec5SDimitry Andric 411*0b57cec5SDimitry Andric void StmtPrinter::VisitGCCAsmStmt(GCCAsmStmt *Node) { 412*0b57cec5SDimitry Andric Indent() << "asm "; 413*0b57cec5SDimitry Andric 414*0b57cec5SDimitry Andric if (Node->isVolatile()) 415*0b57cec5SDimitry Andric OS << "volatile "; 416*0b57cec5SDimitry Andric 417*0b57cec5SDimitry Andric if (Node->isAsmGoto()) 418*0b57cec5SDimitry Andric OS << "goto "; 419*0b57cec5SDimitry Andric 420*0b57cec5SDimitry Andric OS << "("; 421*0b57cec5SDimitry Andric VisitStringLiteral(Node->getAsmString()); 422*0b57cec5SDimitry Andric 423*0b57cec5SDimitry Andric // Outputs 424*0b57cec5SDimitry Andric if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 || 425*0b57cec5SDimitry Andric Node->getNumClobbers() != 0 || Node->getNumLabels() != 0) 426*0b57cec5SDimitry Andric OS << " : "; 427*0b57cec5SDimitry Andric 428*0b57cec5SDimitry Andric for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) { 429*0b57cec5SDimitry Andric if (i != 0) 430*0b57cec5SDimitry Andric OS << ", "; 431*0b57cec5SDimitry Andric 432*0b57cec5SDimitry Andric if (!Node->getOutputName(i).empty()) { 433*0b57cec5SDimitry Andric OS << '['; 434*0b57cec5SDimitry Andric OS << Node->getOutputName(i); 435*0b57cec5SDimitry Andric OS << "] "; 436*0b57cec5SDimitry Andric } 437*0b57cec5SDimitry Andric 438*0b57cec5SDimitry Andric VisitStringLiteral(Node->getOutputConstraintLiteral(i)); 439*0b57cec5SDimitry Andric OS << " ("; 440*0b57cec5SDimitry Andric Visit(Node->getOutputExpr(i)); 441*0b57cec5SDimitry Andric OS << ")"; 442*0b57cec5SDimitry Andric } 443*0b57cec5SDimitry Andric 444*0b57cec5SDimitry Andric // Inputs 445*0b57cec5SDimitry Andric if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0 || 446*0b57cec5SDimitry Andric Node->getNumLabels() != 0) 447*0b57cec5SDimitry Andric OS << " : "; 448*0b57cec5SDimitry Andric 449*0b57cec5SDimitry Andric for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) { 450*0b57cec5SDimitry Andric if (i != 0) 451*0b57cec5SDimitry Andric OS << ", "; 452*0b57cec5SDimitry Andric 453*0b57cec5SDimitry Andric if (!Node->getInputName(i).empty()) { 454*0b57cec5SDimitry Andric OS << '['; 455*0b57cec5SDimitry Andric OS << Node->getInputName(i); 456*0b57cec5SDimitry Andric OS << "] "; 457*0b57cec5SDimitry Andric } 458*0b57cec5SDimitry Andric 459*0b57cec5SDimitry Andric VisitStringLiteral(Node->getInputConstraintLiteral(i)); 460*0b57cec5SDimitry Andric OS << " ("; 461*0b57cec5SDimitry Andric Visit(Node->getInputExpr(i)); 462*0b57cec5SDimitry Andric OS << ")"; 463*0b57cec5SDimitry Andric } 464*0b57cec5SDimitry Andric 465*0b57cec5SDimitry Andric // Clobbers 466*0b57cec5SDimitry Andric if (Node->getNumClobbers() != 0 || Node->getNumLabels()) 467*0b57cec5SDimitry Andric OS << " : "; 468*0b57cec5SDimitry Andric 469*0b57cec5SDimitry Andric for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) { 470*0b57cec5SDimitry Andric if (i != 0) 471*0b57cec5SDimitry Andric OS << ", "; 472*0b57cec5SDimitry Andric 473*0b57cec5SDimitry Andric VisitStringLiteral(Node->getClobberStringLiteral(i)); 474*0b57cec5SDimitry Andric } 475*0b57cec5SDimitry Andric 476*0b57cec5SDimitry Andric // Labels 477*0b57cec5SDimitry Andric if (Node->getNumLabels() != 0) 478*0b57cec5SDimitry Andric OS << " : "; 479*0b57cec5SDimitry Andric 480*0b57cec5SDimitry Andric for (unsigned i = 0, e = Node->getNumLabels(); i != e; ++i) { 481*0b57cec5SDimitry Andric if (i != 0) 482*0b57cec5SDimitry Andric OS << ", "; 483*0b57cec5SDimitry Andric OS << Node->getLabelName(i); 484*0b57cec5SDimitry Andric } 485*0b57cec5SDimitry Andric 486*0b57cec5SDimitry Andric OS << ");"; 487*0b57cec5SDimitry Andric if (Policy.IncludeNewlines) OS << NL; 488*0b57cec5SDimitry Andric } 489*0b57cec5SDimitry Andric 490*0b57cec5SDimitry Andric void StmtPrinter::VisitMSAsmStmt(MSAsmStmt *Node) { 491*0b57cec5SDimitry Andric // FIXME: Implement MS style inline asm statement printer. 492*0b57cec5SDimitry Andric Indent() << "__asm "; 493*0b57cec5SDimitry Andric if (Node->hasBraces()) 494*0b57cec5SDimitry Andric OS << "{" << NL; 495*0b57cec5SDimitry Andric OS << Node->getAsmString() << NL; 496*0b57cec5SDimitry Andric if (Node->hasBraces()) 497*0b57cec5SDimitry Andric Indent() << "}" << NL; 498*0b57cec5SDimitry Andric } 499*0b57cec5SDimitry Andric 500*0b57cec5SDimitry Andric void StmtPrinter::VisitCapturedStmt(CapturedStmt *Node) { 501*0b57cec5SDimitry Andric PrintStmt(Node->getCapturedDecl()->getBody()); 502*0b57cec5SDimitry Andric } 503*0b57cec5SDimitry Andric 504*0b57cec5SDimitry Andric void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) { 505*0b57cec5SDimitry Andric Indent() << "@try"; 506*0b57cec5SDimitry Andric if (auto *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) { 507*0b57cec5SDimitry Andric PrintRawCompoundStmt(TS); 508*0b57cec5SDimitry Andric OS << NL; 509*0b57cec5SDimitry Andric } 510*0b57cec5SDimitry Andric 511*0b57cec5SDimitry Andric for (unsigned I = 0, N = Node->getNumCatchStmts(); I != N; ++I) { 512*0b57cec5SDimitry Andric ObjCAtCatchStmt *catchStmt = Node->getCatchStmt(I); 513*0b57cec5SDimitry Andric Indent() << "@catch("; 514*0b57cec5SDimitry Andric if (catchStmt->getCatchParamDecl()) { 515*0b57cec5SDimitry Andric if (Decl *DS = catchStmt->getCatchParamDecl()) 516*0b57cec5SDimitry Andric PrintRawDecl(DS); 517*0b57cec5SDimitry Andric } 518*0b57cec5SDimitry Andric OS << ")"; 519*0b57cec5SDimitry Andric if (auto *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) { 520*0b57cec5SDimitry Andric PrintRawCompoundStmt(CS); 521*0b57cec5SDimitry Andric OS << NL; 522*0b57cec5SDimitry Andric } 523*0b57cec5SDimitry Andric } 524*0b57cec5SDimitry Andric 525*0b57cec5SDimitry Andric if (auto *FS = static_cast<ObjCAtFinallyStmt *>(Node->getFinallyStmt())) { 526*0b57cec5SDimitry Andric Indent() << "@finally"; 527*0b57cec5SDimitry Andric PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody())); 528*0b57cec5SDimitry Andric OS << NL; 529*0b57cec5SDimitry Andric } 530*0b57cec5SDimitry Andric } 531*0b57cec5SDimitry Andric 532*0b57cec5SDimitry Andric void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) { 533*0b57cec5SDimitry Andric } 534*0b57cec5SDimitry Andric 535*0b57cec5SDimitry Andric void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) { 536*0b57cec5SDimitry Andric Indent() << "@catch (...) { /* todo */ } " << NL; 537*0b57cec5SDimitry Andric } 538*0b57cec5SDimitry Andric 539*0b57cec5SDimitry Andric void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) { 540*0b57cec5SDimitry Andric Indent() << "@throw"; 541*0b57cec5SDimitry Andric if (Node->getThrowExpr()) { 542*0b57cec5SDimitry Andric OS << " "; 543*0b57cec5SDimitry Andric PrintExpr(Node->getThrowExpr()); 544*0b57cec5SDimitry Andric } 545*0b57cec5SDimitry Andric OS << ";" << NL; 546*0b57cec5SDimitry Andric } 547*0b57cec5SDimitry Andric 548*0b57cec5SDimitry Andric void StmtPrinter::VisitObjCAvailabilityCheckExpr( 549*0b57cec5SDimitry Andric ObjCAvailabilityCheckExpr *Node) { 550*0b57cec5SDimitry Andric OS << "@available(...)"; 551*0b57cec5SDimitry Andric } 552*0b57cec5SDimitry Andric 553*0b57cec5SDimitry Andric void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) { 554*0b57cec5SDimitry Andric Indent() << "@synchronized ("; 555*0b57cec5SDimitry Andric PrintExpr(Node->getSynchExpr()); 556*0b57cec5SDimitry Andric OS << ")"; 557*0b57cec5SDimitry Andric PrintRawCompoundStmt(Node->getSynchBody()); 558*0b57cec5SDimitry Andric OS << NL; 559*0b57cec5SDimitry Andric } 560*0b57cec5SDimitry Andric 561*0b57cec5SDimitry Andric void StmtPrinter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *Node) { 562*0b57cec5SDimitry Andric Indent() << "@autoreleasepool"; 563*0b57cec5SDimitry Andric PrintRawCompoundStmt(dyn_cast<CompoundStmt>(Node->getSubStmt())); 564*0b57cec5SDimitry Andric OS << NL; 565*0b57cec5SDimitry Andric } 566*0b57cec5SDimitry Andric 567*0b57cec5SDimitry Andric void StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) { 568*0b57cec5SDimitry Andric OS << "catch ("; 569*0b57cec5SDimitry Andric if (Decl *ExDecl = Node->getExceptionDecl()) 570*0b57cec5SDimitry Andric PrintRawDecl(ExDecl); 571*0b57cec5SDimitry Andric else 572*0b57cec5SDimitry Andric OS << "..."; 573*0b57cec5SDimitry Andric OS << ") "; 574*0b57cec5SDimitry Andric PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock())); 575*0b57cec5SDimitry Andric } 576*0b57cec5SDimitry Andric 577*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) { 578*0b57cec5SDimitry Andric Indent(); 579*0b57cec5SDimitry Andric PrintRawCXXCatchStmt(Node); 580*0b57cec5SDimitry Andric OS << NL; 581*0b57cec5SDimitry Andric } 582*0b57cec5SDimitry Andric 583*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) { 584*0b57cec5SDimitry Andric Indent() << "try "; 585*0b57cec5SDimitry Andric PrintRawCompoundStmt(Node->getTryBlock()); 586*0b57cec5SDimitry Andric for (unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) { 587*0b57cec5SDimitry Andric OS << " "; 588*0b57cec5SDimitry Andric PrintRawCXXCatchStmt(Node->getHandler(i)); 589*0b57cec5SDimitry Andric } 590*0b57cec5SDimitry Andric OS << NL; 591*0b57cec5SDimitry Andric } 592*0b57cec5SDimitry Andric 593*0b57cec5SDimitry Andric void StmtPrinter::VisitSEHTryStmt(SEHTryStmt *Node) { 594*0b57cec5SDimitry Andric Indent() << (Node->getIsCXXTry() ? "try " : "__try "); 595*0b57cec5SDimitry Andric PrintRawCompoundStmt(Node->getTryBlock()); 596*0b57cec5SDimitry Andric SEHExceptStmt *E = Node->getExceptHandler(); 597*0b57cec5SDimitry Andric SEHFinallyStmt *F = Node->getFinallyHandler(); 598*0b57cec5SDimitry Andric if(E) 599*0b57cec5SDimitry Andric PrintRawSEHExceptHandler(E); 600*0b57cec5SDimitry Andric else { 601*0b57cec5SDimitry Andric assert(F && "Must have a finally block..."); 602*0b57cec5SDimitry Andric PrintRawSEHFinallyStmt(F); 603*0b57cec5SDimitry Andric } 604*0b57cec5SDimitry Andric OS << NL; 605*0b57cec5SDimitry Andric } 606*0b57cec5SDimitry Andric 607*0b57cec5SDimitry Andric void StmtPrinter::PrintRawSEHFinallyStmt(SEHFinallyStmt *Node) { 608*0b57cec5SDimitry Andric OS << "__finally "; 609*0b57cec5SDimitry Andric PrintRawCompoundStmt(Node->getBlock()); 610*0b57cec5SDimitry Andric OS << NL; 611*0b57cec5SDimitry Andric } 612*0b57cec5SDimitry Andric 613*0b57cec5SDimitry Andric void StmtPrinter::PrintRawSEHExceptHandler(SEHExceptStmt *Node) { 614*0b57cec5SDimitry Andric OS << "__except ("; 615*0b57cec5SDimitry Andric VisitExpr(Node->getFilterExpr()); 616*0b57cec5SDimitry Andric OS << ")" << NL; 617*0b57cec5SDimitry Andric PrintRawCompoundStmt(Node->getBlock()); 618*0b57cec5SDimitry Andric OS << NL; 619*0b57cec5SDimitry Andric } 620*0b57cec5SDimitry Andric 621*0b57cec5SDimitry Andric void StmtPrinter::VisitSEHExceptStmt(SEHExceptStmt *Node) { 622*0b57cec5SDimitry Andric Indent(); 623*0b57cec5SDimitry Andric PrintRawSEHExceptHandler(Node); 624*0b57cec5SDimitry Andric OS << NL; 625*0b57cec5SDimitry Andric } 626*0b57cec5SDimitry Andric 627*0b57cec5SDimitry Andric void StmtPrinter::VisitSEHFinallyStmt(SEHFinallyStmt *Node) { 628*0b57cec5SDimitry Andric Indent(); 629*0b57cec5SDimitry Andric PrintRawSEHFinallyStmt(Node); 630*0b57cec5SDimitry Andric OS << NL; 631*0b57cec5SDimitry Andric } 632*0b57cec5SDimitry Andric 633*0b57cec5SDimitry Andric void StmtPrinter::VisitSEHLeaveStmt(SEHLeaveStmt *Node) { 634*0b57cec5SDimitry Andric Indent() << "__leave;"; 635*0b57cec5SDimitry Andric if (Policy.IncludeNewlines) OS << NL; 636*0b57cec5SDimitry Andric } 637*0b57cec5SDimitry Andric 638*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 639*0b57cec5SDimitry Andric // OpenMP directives printing methods 640*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 641*0b57cec5SDimitry Andric 642*0b57cec5SDimitry Andric void StmtPrinter::PrintOMPExecutableDirective(OMPExecutableDirective *S, 643*0b57cec5SDimitry Andric bool ForceNoStmt) { 644*0b57cec5SDimitry Andric OMPClausePrinter Printer(OS, Policy); 645*0b57cec5SDimitry Andric ArrayRef<OMPClause *> Clauses = S->clauses(); 646*0b57cec5SDimitry Andric for (auto *Clause : Clauses) 647*0b57cec5SDimitry Andric if (Clause && !Clause->isImplicit()) { 648*0b57cec5SDimitry Andric OS << ' '; 649*0b57cec5SDimitry Andric Printer.Visit(Clause); 650*0b57cec5SDimitry Andric } 651*0b57cec5SDimitry Andric OS << NL; 652*0b57cec5SDimitry Andric if (!ForceNoStmt && S->hasAssociatedStmt()) 653*0b57cec5SDimitry Andric PrintStmt(S->getInnermostCapturedStmt()->getCapturedStmt()); 654*0b57cec5SDimitry Andric } 655*0b57cec5SDimitry Andric 656*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPParallelDirective(OMPParallelDirective *Node) { 657*0b57cec5SDimitry Andric Indent() << "#pragma omp parallel"; 658*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 659*0b57cec5SDimitry Andric } 660*0b57cec5SDimitry Andric 661*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPSimdDirective(OMPSimdDirective *Node) { 662*0b57cec5SDimitry Andric Indent() << "#pragma omp simd"; 663*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 664*0b57cec5SDimitry Andric } 665*0b57cec5SDimitry Andric 666*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPForDirective(OMPForDirective *Node) { 667*0b57cec5SDimitry Andric Indent() << "#pragma omp for"; 668*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 669*0b57cec5SDimitry Andric } 670*0b57cec5SDimitry Andric 671*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPForSimdDirective(OMPForSimdDirective *Node) { 672*0b57cec5SDimitry Andric Indent() << "#pragma omp for simd"; 673*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 674*0b57cec5SDimitry Andric } 675*0b57cec5SDimitry Andric 676*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPSectionsDirective(OMPSectionsDirective *Node) { 677*0b57cec5SDimitry Andric Indent() << "#pragma omp sections"; 678*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 679*0b57cec5SDimitry Andric } 680*0b57cec5SDimitry Andric 681*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPSectionDirective(OMPSectionDirective *Node) { 682*0b57cec5SDimitry Andric Indent() << "#pragma omp section"; 683*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 684*0b57cec5SDimitry Andric } 685*0b57cec5SDimitry Andric 686*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPSingleDirective(OMPSingleDirective *Node) { 687*0b57cec5SDimitry Andric Indent() << "#pragma omp single"; 688*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 689*0b57cec5SDimitry Andric } 690*0b57cec5SDimitry Andric 691*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPMasterDirective(OMPMasterDirective *Node) { 692*0b57cec5SDimitry Andric Indent() << "#pragma omp master"; 693*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 694*0b57cec5SDimitry Andric } 695*0b57cec5SDimitry Andric 696*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPCriticalDirective(OMPCriticalDirective *Node) { 697*0b57cec5SDimitry Andric Indent() << "#pragma omp critical"; 698*0b57cec5SDimitry Andric if (Node->getDirectiveName().getName()) { 699*0b57cec5SDimitry Andric OS << " ("; 700*0b57cec5SDimitry Andric Node->getDirectiveName().printName(OS); 701*0b57cec5SDimitry Andric OS << ")"; 702*0b57cec5SDimitry Andric } 703*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 704*0b57cec5SDimitry Andric } 705*0b57cec5SDimitry Andric 706*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPParallelForDirective(OMPParallelForDirective *Node) { 707*0b57cec5SDimitry Andric Indent() << "#pragma omp parallel for"; 708*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 709*0b57cec5SDimitry Andric } 710*0b57cec5SDimitry Andric 711*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPParallelForSimdDirective( 712*0b57cec5SDimitry Andric OMPParallelForSimdDirective *Node) { 713*0b57cec5SDimitry Andric Indent() << "#pragma omp parallel for simd"; 714*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 715*0b57cec5SDimitry Andric } 716*0b57cec5SDimitry Andric 717*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPParallelSectionsDirective( 718*0b57cec5SDimitry Andric OMPParallelSectionsDirective *Node) { 719*0b57cec5SDimitry Andric Indent() << "#pragma omp parallel sections"; 720*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 721*0b57cec5SDimitry Andric } 722*0b57cec5SDimitry Andric 723*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPTaskDirective(OMPTaskDirective *Node) { 724*0b57cec5SDimitry Andric Indent() << "#pragma omp task"; 725*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 726*0b57cec5SDimitry Andric } 727*0b57cec5SDimitry Andric 728*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *Node) { 729*0b57cec5SDimitry Andric Indent() << "#pragma omp taskyield"; 730*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 731*0b57cec5SDimitry Andric } 732*0b57cec5SDimitry Andric 733*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPBarrierDirective(OMPBarrierDirective *Node) { 734*0b57cec5SDimitry Andric Indent() << "#pragma omp barrier"; 735*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 736*0b57cec5SDimitry Andric } 737*0b57cec5SDimitry Andric 738*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *Node) { 739*0b57cec5SDimitry Andric Indent() << "#pragma omp taskwait"; 740*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 741*0b57cec5SDimitry Andric } 742*0b57cec5SDimitry Andric 743*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *Node) { 744*0b57cec5SDimitry Andric Indent() << "#pragma omp taskgroup"; 745*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 746*0b57cec5SDimitry Andric } 747*0b57cec5SDimitry Andric 748*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) { 749*0b57cec5SDimitry Andric Indent() << "#pragma omp flush"; 750*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 751*0b57cec5SDimitry Andric } 752*0b57cec5SDimitry Andric 753*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPOrderedDirective(OMPOrderedDirective *Node) { 754*0b57cec5SDimitry Andric Indent() << "#pragma omp ordered"; 755*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node, Node->hasClausesOfKind<OMPDependClause>()); 756*0b57cec5SDimitry Andric } 757*0b57cec5SDimitry Andric 758*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPAtomicDirective(OMPAtomicDirective *Node) { 759*0b57cec5SDimitry Andric Indent() << "#pragma omp atomic"; 760*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 761*0b57cec5SDimitry Andric } 762*0b57cec5SDimitry Andric 763*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetDirective(OMPTargetDirective *Node) { 764*0b57cec5SDimitry Andric Indent() << "#pragma omp target"; 765*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 766*0b57cec5SDimitry Andric } 767*0b57cec5SDimitry Andric 768*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetDataDirective(OMPTargetDataDirective *Node) { 769*0b57cec5SDimitry Andric Indent() << "#pragma omp target data"; 770*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 771*0b57cec5SDimitry Andric } 772*0b57cec5SDimitry Andric 773*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetEnterDataDirective( 774*0b57cec5SDimitry Andric OMPTargetEnterDataDirective *Node) { 775*0b57cec5SDimitry Andric Indent() << "#pragma omp target enter data"; 776*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true); 777*0b57cec5SDimitry Andric } 778*0b57cec5SDimitry Andric 779*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetExitDataDirective( 780*0b57cec5SDimitry Andric OMPTargetExitDataDirective *Node) { 781*0b57cec5SDimitry Andric Indent() << "#pragma omp target exit data"; 782*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true); 783*0b57cec5SDimitry Andric } 784*0b57cec5SDimitry Andric 785*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetParallelDirective( 786*0b57cec5SDimitry Andric OMPTargetParallelDirective *Node) { 787*0b57cec5SDimitry Andric Indent() << "#pragma omp target parallel"; 788*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 789*0b57cec5SDimitry Andric } 790*0b57cec5SDimitry Andric 791*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetParallelForDirective( 792*0b57cec5SDimitry Andric OMPTargetParallelForDirective *Node) { 793*0b57cec5SDimitry Andric Indent() << "#pragma omp target parallel for"; 794*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 795*0b57cec5SDimitry Andric } 796*0b57cec5SDimitry Andric 797*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPTeamsDirective(OMPTeamsDirective *Node) { 798*0b57cec5SDimitry Andric Indent() << "#pragma omp teams"; 799*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 800*0b57cec5SDimitry Andric } 801*0b57cec5SDimitry Andric 802*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPCancellationPointDirective( 803*0b57cec5SDimitry Andric OMPCancellationPointDirective *Node) { 804*0b57cec5SDimitry Andric Indent() << "#pragma omp cancellation point " 805*0b57cec5SDimitry Andric << getOpenMPDirectiveName(Node->getCancelRegion()); 806*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 807*0b57cec5SDimitry Andric } 808*0b57cec5SDimitry Andric 809*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPCancelDirective(OMPCancelDirective *Node) { 810*0b57cec5SDimitry Andric Indent() << "#pragma omp cancel " 811*0b57cec5SDimitry Andric << getOpenMPDirectiveName(Node->getCancelRegion()); 812*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 813*0b57cec5SDimitry Andric } 814*0b57cec5SDimitry Andric 815*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *Node) { 816*0b57cec5SDimitry Andric Indent() << "#pragma omp taskloop"; 817*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 818*0b57cec5SDimitry Andric } 819*0b57cec5SDimitry Andric 820*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPTaskLoopSimdDirective( 821*0b57cec5SDimitry Andric OMPTaskLoopSimdDirective *Node) { 822*0b57cec5SDimitry Andric Indent() << "#pragma omp taskloop simd"; 823*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 824*0b57cec5SDimitry Andric } 825*0b57cec5SDimitry Andric 826*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPDistributeDirective(OMPDistributeDirective *Node) { 827*0b57cec5SDimitry Andric Indent() << "#pragma omp distribute"; 828*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 829*0b57cec5SDimitry Andric } 830*0b57cec5SDimitry Andric 831*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetUpdateDirective( 832*0b57cec5SDimitry Andric OMPTargetUpdateDirective *Node) { 833*0b57cec5SDimitry Andric Indent() << "#pragma omp target update"; 834*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true); 835*0b57cec5SDimitry Andric } 836*0b57cec5SDimitry Andric 837*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPDistributeParallelForDirective( 838*0b57cec5SDimitry Andric OMPDistributeParallelForDirective *Node) { 839*0b57cec5SDimitry Andric Indent() << "#pragma omp distribute parallel for"; 840*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 841*0b57cec5SDimitry Andric } 842*0b57cec5SDimitry Andric 843*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPDistributeParallelForSimdDirective( 844*0b57cec5SDimitry Andric OMPDistributeParallelForSimdDirective *Node) { 845*0b57cec5SDimitry Andric Indent() << "#pragma omp distribute parallel for simd"; 846*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 847*0b57cec5SDimitry Andric } 848*0b57cec5SDimitry Andric 849*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPDistributeSimdDirective( 850*0b57cec5SDimitry Andric OMPDistributeSimdDirective *Node) { 851*0b57cec5SDimitry Andric Indent() << "#pragma omp distribute simd"; 852*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 853*0b57cec5SDimitry Andric } 854*0b57cec5SDimitry Andric 855*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetParallelForSimdDirective( 856*0b57cec5SDimitry Andric OMPTargetParallelForSimdDirective *Node) { 857*0b57cec5SDimitry Andric Indent() << "#pragma omp target parallel for simd"; 858*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 859*0b57cec5SDimitry Andric } 860*0b57cec5SDimitry Andric 861*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *Node) { 862*0b57cec5SDimitry Andric Indent() << "#pragma omp target simd"; 863*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 864*0b57cec5SDimitry Andric } 865*0b57cec5SDimitry Andric 866*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPTeamsDistributeDirective( 867*0b57cec5SDimitry Andric OMPTeamsDistributeDirective *Node) { 868*0b57cec5SDimitry Andric Indent() << "#pragma omp teams distribute"; 869*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 870*0b57cec5SDimitry Andric } 871*0b57cec5SDimitry Andric 872*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPTeamsDistributeSimdDirective( 873*0b57cec5SDimitry Andric OMPTeamsDistributeSimdDirective *Node) { 874*0b57cec5SDimitry Andric Indent() << "#pragma omp teams distribute simd"; 875*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 876*0b57cec5SDimitry Andric } 877*0b57cec5SDimitry Andric 878*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPTeamsDistributeParallelForSimdDirective( 879*0b57cec5SDimitry Andric OMPTeamsDistributeParallelForSimdDirective *Node) { 880*0b57cec5SDimitry Andric Indent() << "#pragma omp teams distribute parallel for simd"; 881*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 882*0b57cec5SDimitry Andric } 883*0b57cec5SDimitry Andric 884*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPTeamsDistributeParallelForDirective( 885*0b57cec5SDimitry Andric OMPTeamsDistributeParallelForDirective *Node) { 886*0b57cec5SDimitry Andric Indent() << "#pragma omp teams distribute parallel for"; 887*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 888*0b57cec5SDimitry Andric } 889*0b57cec5SDimitry Andric 890*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *Node) { 891*0b57cec5SDimitry Andric Indent() << "#pragma omp target teams"; 892*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 893*0b57cec5SDimitry Andric } 894*0b57cec5SDimitry Andric 895*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetTeamsDistributeDirective( 896*0b57cec5SDimitry Andric OMPTargetTeamsDistributeDirective *Node) { 897*0b57cec5SDimitry Andric Indent() << "#pragma omp target teams distribute"; 898*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 899*0b57cec5SDimitry Andric } 900*0b57cec5SDimitry Andric 901*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForDirective( 902*0b57cec5SDimitry Andric OMPTargetTeamsDistributeParallelForDirective *Node) { 903*0b57cec5SDimitry Andric Indent() << "#pragma omp target teams distribute parallel for"; 904*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 905*0b57cec5SDimitry Andric } 906*0b57cec5SDimitry Andric 907*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForSimdDirective( 908*0b57cec5SDimitry Andric OMPTargetTeamsDistributeParallelForSimdDirective *Node) { 909*0b57cec5SDimitry Andric Indent() << "#pragma omp target teams distribute parallel for simd"; 910*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 911*0b57cec5SDimitry Andric } 912*0b57cec5SDimitry Andric 913*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetTeamsDistributeSimdDirective( 914*0b57cec5SDimitry Andric OMPTargetTeamsDistributeSimdDirective *Node) { 915*0b57cec5SDimitry Andric Indent() << "#pragma omp target teams distribute simd"; 916*0b57cec5SDimitry Andric PrintOMPExecutableDirective(Node); 917*0b57cec5SDimitry Andric } 918*0b57cec5SDimitry Andric 919*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 920*0b57cec5SDimitry Andric // Expr printing methods. 921*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 922*0b57cec5SDimitry Andric 923*0b57cec5SDimitry Andric void StmtPrinter::VisitSourceLocExpr(SourceLocExpr *Node) { 924*0b57cec5SDimitry Andric OS << Node->getBuiltinStr() << "()"; 925*0b57cec5SDimitry Andric } 926*0b57cec5SDimitry Andric 927*0b57cec5SDimitry Andric void StmtPrinter::VisitConstantExpr(ConstantExpr *Node) { 928*0b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 929*0b57cec5SDimitry Andric } 930*0b57cec5SDimitry Andric 931*0b57cec5SDimitry Andric void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) { 932*0b57cec5SDimitry Andric if (const auto *OCED = dyn_cast<OMPCapturedExprDecl>(Node->getDecl())) { 933*0b57cec5SDimitry Andric OCED->getInit()->IgnoreImpCasts()->printPretty(OS, nullptr, Policy); 934*0b57cec5SDimitry Andric return; 935*0b57cec5SDimitry Andric } 936*0b57cec5SDimitry Andric if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 937*0b57cec5SDimitry Andric Qualifier->print(OS, Policy); 938*0b57cec5SDimitry Andric if (Node->hasTemplateKeyword()) 939*0b57cec5SDimitry Andric OS << "template "; 940*0b57cec5SDimitry Andric OS << Node->getNameInfo(); 941*0b57cec5SDimitry Andric if (Node->hasExplicitTemplateArgs()) 942*0b57cec5SDimitry Andric printTemplateArgumentList(OS, Node->template_arguments(), Policy); 943*0b57cec5SDimitry Andric } 944*0b57cec5SDimitry Andric 945*0b57cec5SDimitry Andric void StmtPrinter::VisitDependentScopeDeclRefExpr( 946*0b57cec5SDimitry Andric DependentScopeDeclRefExpr *Node) { 947*0b57cec5SDimitry Andric if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 948*0b57cec5SDimitry Andric Qualifier->print(OS, Policy); 949*0b57cec5SDimitry Andric if (Node->hasTemplateKeyword()) 950*0b57cec5SDimitry Andric OS << "template "; 951*0b57cec5SDimitry Andric OS << Node->getNameInfo(); 952*0b57cec5SDimitry Andric if (Node->hasExplicitTemplateArgs()) 953*0b57cec5SDimitry Andric printTemplateArgumentList(OS, Node->template_arguments(), Policy); 954*0b57cec5SDimitry Andric } 955*0b57cec5SDimitry Andric 956*0b57cec5SDimitry Andric void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) { 957*0b57cec5SDimitry Andric if (Node->getQualifier()) 958*0b57cec5SDimitry Andric Node->getQualifier()->print(OS, Policy); 959*0b57cec5SDimitry Andric if (Node->hasTemplateKeyword()) 960*0b57cec5SDimitry Andric OS << "template "; 961*0b57cec5SDimitry Andric OS << Node->getNameInfo(); 962*0b57cec5SDimitry Andric if (Node->hasExplicitTemplateArgs()) 963*0b57cec5SDimitry Andric printTemplateArgumentList(OS, Node->template_arguments(), Policy); 964*0b57cec5SDimitry Andric } 965*0b57cec5SDimitry Andric 966*0b57cec5SDimitry Andric static bool isImplicitSelf(const Expr *E) { 967*0b57cec5SDimitry Andric if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) { 968*0b57cec5SDimitry Andric if (const auto *PD = dyn_cast<ImplicitParamDecl>(DRE->getDecl())) { 969*0b57cec5SDimitry Andric if (PD->getParameterKind() == ImplicitParamDecl::ObjCSelf && 970*0b57cec5SDimitry Andric DRE->getBeginLoc().isInvalid()) 971*0b57cec5SDimitry Andric return true; 972*0b57cec5SDimitry Andric } 973*0b57cec5SDimitry Andric } 974*0b57cec5SDimitry Andric return false; 975*0b57cec5SDimitry Andric } 976*0b57cec5SDimitry Andric 977*0b57cec5SDimitry Andric void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { 978*0b57cec5SDimitry Andric if (Node->getBase()) { 979*0b57cec5SDimitry Andric if (!Policy.SuppressImplicitBase || 980*0b57cec5SDimitry Andric !isImplicitSelf(Node->getBase()->IgnoreImpCasts())) { 981*0b57cec5SDimitry Andric PrintExpr(Node->getBase()); 982*0b57cec5SDimitry Andric OS << (Node->isArrow() ? "->" : "."); 983*0b57cec5SDimitry Andric } 984*0b57cec5SDimitry Andric } 985*0b57cec5SDimitry Andric OS << *Node->getDecl(); 986*0b57cec5SDimitry Andric } 987*0b57cec5SDimitry Andric 988*0b57cec5SDimitry Andric void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) { 989*0b57cec5SDimitry Andric if (Node->isSuperReceiver()) 990*0b57cec5SDimitry Andric OS << "super."; 991*0b57cec5SDimitry Andric else if (Node->isObjectReceiver() && Node->getBase()) { 992*0b57cec5SDimitry Andric PrintExpr(Node->getBase()); 993*0b57cec5SDimitry Andric OS << "."; 994*0b57cec5SDimitry Andric } else if (Node->isClassReceiver() && Node->getClassReceiver()) { 995*0b57cec5SDimitry Andric OS << Node->getClassReceiver()->getName() << "."; 996*0b57cec5SDimitry Andric } 997*0b57cec5SDimitry Andric 998*0b57cec5SDimitry Andric if (Node->isImplicitProperty()) { 999*0b57cec5SDimitry Andric if (const auto *Getter = Node->getImplicitPropertyGetter()) 1000*0b57cec5SDimitry Andric Getter->getSelector().print(OS); 1001*0b57cec5SDimitry Andric else 1002*0b57cec5SDimitry Andric OS << SelectorTable::getPropertyNameFromSetterSelector( 1003*0b57cec5SDimitry Andric Node->getImplicitPropertySetter()->getSelector()); 1004*0b57cec5SDimitry Andric } else 1005*0b57cec5SDimitry Andric OS << Node->getExplicitProperty()->getName(); 1006*0b57cec5SDimitry Andric } 1007*0b57cec5SDimitry Andric 1008*0b57cec5SDimitry Andric void StmtPrinter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node) { 1009*0b57cec5SDimitry Andric PrintExpr(Node->getBaseExpr()); 1010*0b57cec5SDimitry Andric OS << "["; 1011*0b57cec5SDimitry Andric PrintExpr(Node->getKeyExpr()); 1012*0b57cec5SDimitry Andric OS << "]"; 1013*0b57cec5SDimitry Andric } 1014*0b57cec5SDimitry Andric 1015*0b57cec5SDimitry Andric void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) { 1016*0b57cec5SDimitry Andric OS << PredefinedExpr::getIdentKindName(Node->getIdentKind()); 1017*0b57cec5SDimitry Andric } 1018*0b57cec5SDimitry Andric 1019*0b57cec5SDimitry Andric void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) { 1020*0b57cec5SDimitry Andric unsigned value = Node->getValue(); 1021*0b57cec5SDimitry Andric 1022*0b57cec5SDimitry Andric switch (Node->getKind()) { 1023*0b57cec5SDimitry Andric case CharacterLiteral::Ascii: break; // no prefix. 1024*0b57cec5SDimitry Andric case CharacterLiteral::Wide: OS << 'L'; break; 1025*0b57cec5SDimitry Andric case CharacterLiteral::UTF8: OS << "u8"; break; 1026*0b57cec5SDimitry Andric case CharacterLiteral::UTF16: OS << 'u'; break; 1027*0b57cec5SDimitry Andric case CharacterLiteral::UTF32: OS << 'U'; break; 1028*0b57cec5SDimitry Andric } 1029*0b57cec5SDimitry Andric 1030*0b57cec5SDimitry Andric switch (value) { 1031*0b57cec5SDimitry Andric case '\\': 1032*0b57cec5SDimitry Andric OS << "'\\\\'"; 1033*0b57cec5SDimitry Andric break; 1034*0b57cec5SDimitry Andric case '\'': 1035*0b57cec5SDimitry Andric OS << "'\\''"; 1036*0b57cec5SDimitry Andric break; 1037*0b57cec5SDimitry Andric case '\a': 1038*0b57cec5SDimitry Andric // TODO: K&R: the meaning of '\\a' is different in traditional C 1039*0b57cec5SDimitry Andric OS << "'\\a'"; 1040*0b57cec5SDimitry Andric break; 1041*0b57cec5SDimitry Andric case '\b': 1042*0b57cec5SDimitry Andric OS << "'\\b'"; 1043*0b57cec5SDimitry Andric break; 1044*0b57cec5SDimitry Andric // Nonstandard escape sequence. 1045*0b57cec5SDimitry Andric /*case '\e': 1046*0b57cec5SDimitry Andric OS << "'\\e'"; 1047*0b57cec5SDimitry Andric break;*/ 1048*0b57cec5SDimitry Andric case '\f': 1049*0b57cec5SDimitry Andric OS << "'\\f'"; 1050*0b57cec5SDimitry Andric break; 1051*0b57cec5SDimitry Andric case '\n': 1052*0b57cec5SDimitry Andric OS << "'\\n'"; 1053*0b57cec5SDimitry Andric break; 1054*0b57cec5SDimitry Andric case '\r': 1055*0b57cec5SDimitry Andric OS << "'\\r'"; 1056*0b57cec5SDimitry Andric break; 1057*0b57cec5SDimitry Andric case '\t': 1058*0b57cec5SDimitry Andric OS << "'\\t'"; 1059*0b57cec5SDimitry Andric break; 1060*0b57cec5SDimitry Andric case '\v': 1061*0b57cec5SDimitry Andric OS << "'\\v'"; 1062*0b57cec5SDimitry Andric break; 1063*0b57cec5SDimitry Andric default: 1064*0b57cec5SDimitry Andric // A character literal might be sign-extended, which 1065*0b57cec5SDimitry Andric // would result in an invalid \U escape sequence. 1066*0b57cec5SDimitry Andric // FIXME: multicharacter literals such as '\xFF\xFF\xFF\xFF' 1067*0b57cec5SDimitry Andric // are not correctly handled. 1068*0b57cec5SDimitry Andric if ((value & ~0xFFu) == ~0xFFu && Node->getKind() == CharacterLiteral::Ascii) 1069*0b57cec5SDimitry Andric value &= 0xFFu; 1070*0b57cec5SDimitry Andric if (value < 256 && isPrintable((unsigned char)value)) 1071*0b57cec5SDimitry Andric OS << "'" << (char)value << "'"; 1072*0b57cec5SDimitry Andric else if (value < 256) 1073*0b57cec5SDimitry Andric OS << "'\\x" << llvm::format("%02x", value) << "'"; 1074*0b57cec5SDimitry Andric else if (value <= 0xFFFF) 1075*0b57cec5SDimitry Andric OS << "'\\u" << llvm::format("%04x", value) << "'"; 1076*0b57cec5SDimitry Andric else 1077*0b57cec5SDimitry Andric OS << "'\\U" << llvm::format("%08x", value) << "'"; 1078*0b57cec5SDimitry Andric } 1079*0b57cec5SDimitry Andric } 1080*0b57cec5SDimitry Andric 1081*0b57cec5SDimitry Andric /// Prints the given expression using the original source text. Returns true on 1082*0b57cec5SDimitry Andric /// success, false otherwise. 1083*0b57cec5SDimitry Andric static bool printExprAsWritten(raw_ostream &OS, Expr *E, 1084*0b57cec5SDimitry Andric const ASTContext *Context) { 1085*0b57cec5SDimitry Andric if (!Context) 1086*0b57cec5SDimitry Andric return false; 1087*0b57cec5SDimitry Andric bool Invalid = false; 1088*0b57cec5SDimitry Andric StringRef Source = Lexer::getSourceText( 1089*0b57cec5SDimitry Andric CharSourceRange::getTokenRange(E->getSourceRange()), 1090*0b57cec5SDimitry Andric Context->getSourceManager(), Context->getLangOpts(), &Invalid); 1091*0b57cec5SDimitry Andric if (!Invalid) { 1092*0b57cec5SDimitry Andric OS << Source; 1093*0b57cec5SDimitry Andric return true; 1094*0b57cec5SDimitry Andric } 1095*0b57cec5SDimitry Andric return false; 1096*0b57cec5SDimitry Andric } 1097*0b57cec5SDimitry Andric 1098*0b57cec5SDimitry Andric void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) { 1099*0b57cec5SDimitry Andric if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context)) 1100*0b57cec5SDimitry Andric return; 1101*0b57cec5SDimitry Andric bool isSigned = Node->getType()->isSignedIntegerType(); 1102*0b57cec5SDimitry Andric OS << Node->getValue().toString(10, isSigned); 1103*0b57cec5SDimitry Andric 1104*0b57cec5SDimitry Andric // Emit suffixes. Integer literals are always a builtin integer type. 1105*0b57cec5SDimitry Andric switch (Node->getType()->getAs<BuiltinType>()->getKind()) { 1106*0b57cec5SDimitry Andric default: llvm_unreachable("Unexpected type for integer literal!"); 1107*0b57cec5SDimitry Andric case BuiltinType::Char_S: 1108*0b57cec5SDimitry Andric case BuiltinType::Char_U: OS << "i8"; break; 1109*0b57cec5SDimitry Andric case BuiltinType::UChar: OS << "Ui8"; break; 1110*0b57cec5SDimitry Andric case BuiltinType::Short: OS << "i16"; break; 1111*0b57cec5SDimitry Andric case BuiltinType::UShort: OS << "Ui16"; break; 1112*0b57cec5SDimitry Andric case BuiltinType::Int: break; // no suffix. 1113*0b57cec5SDimitry Andric case BuiltinType::UInt: OS << 'U'; break; 1114*0b57cec5SDimitry Andric case BuiltinType::Long: OS << 'L'; break; 1115*0b57cec5SDimitry Andric case BuiltinType::ULong: OS << "UL"; break; 1116*0b57cec5SDimitry Andric case BuiltinType::LongLong: OS << "LL"; break; 1117*0b57cec5SDimitry Andric case BuiltinType::ULongLong: OS << "ULL"; break; 1118*0b57cec5SDimitry Andric } 1119*0b57cec5SDimitry Andric } 1120*0b57cec5SDimitry Andric 1121*0b57cec5SDimitry Andric void StmtPrinter::VisitFixedPointLiteral(FixedPointLiteral *Node) { 1122*0b57cec5SDimitry Andric if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context)) 1123*0b57cec5SDimitry Andric return; 1124*0b57cec5SDimitry Andric OS << Node->getValueAsString(/*Radix=*/10); 1125*0b57cec5SDimitry Andric 1126*0b57cec5SDimitry Andric switch (Node->getType()->getAs<BuiltinType>()->getKind()) { 1127*0b57cec5SDimitry Andric default: llvm_unreachable("Unexpected type for fixed point literal!"); 1128*0b57cec5SDimitry Andric case BuiltinType::ShortFract: OS << "hr"; break; 1129*0b57cec5SDimitry Andric case BuiltinType::ShortAccum: OS << "hk"; break; 1130*0b57cec5SDimitry Andric case BuiltinType::UShortFract: OS << "uhr"; break; 1131*0b57cec5SDimitry Andric case BuiltinType::UShortAccum: OS << "uhk"; break; 1132*0b57cec5SDimitry Andric case BuiltinType::Fract: OS << "r"; break; 1133*0b57cec5SDimitry Andric case BuiltinType::Accum: OS << "k"; break; 1134*0b57cec5SDimitry Andric case BuiltinType::UFract: OS << "ur"; break; 1135*0b57cec5SDimitry Andric case BuiltinType::UAccum: OS << "uk"; break; 1136*0b57cec5SDimitry Andric case BuiltinType::LongFract: OS << "lr"; break; 1137*0b57cec5SDimitry Andric case BuiltinType::LongAccum: OS << "lk"; break; 1138*0b57cec5SDimitry Andric case BuiltinType::ULongFract: OS << "ulr"; break; 1139*0b57cec5SDimitry Andric case BuiltinType::ULongAccum: OS << "ulk"; break; 1140*0b57cec5SDimitry Andric } 1141*0b57cec5SDimitry Andric } 1142*0b57cec5SDimitry Andric 1143*0b57cec5SDimitry Andric static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node, 1144*0b57cec5SDimitry Andric bool PrintSuffix) { 1145*0b57cec5SDimitry Andric SmallString<16> Str; 1146*0b57cec5SDimitry Andric Node->getValue().toString(Str); 1147*0b57cec5SDimitry Andric OS << Str; 1148*0b57cec5SDimitry Andric if (Str.find_first_not_of("-0123456789") == StringRef::npos) 1149*0b57cec5SDimitry Andric OS << '.'; // Trailing dot in order to separate from ints. 1150*0b57cec5SDimitry Andric 1151*0b57cec5SDimitry Andric if (!PrintSuffix) 1152*0b57cec5SDimitry Andric return; 1153*0b57cec5SDimitry Andric 1154*0b57cec5SDimitry Andric // Emit suffixes. Float literals are always a builtin float type. 1155*0b57cec5SDimitry Andric switch (Node->getType()->getAs<BuiltinType>()->getKind()) { 1156*0b57cec5SDimitry Andric default: llvm_unreachable("Unexpected type for float literal!"); 1157*0b57cec5SDimitry Andric case BuiltinType::Half: break; // FIXME: suffix? 1158*0b57cec5SDimitry Andric case BuiltinType::Double: break; // no suffix. 1159*0b57cec5SDimitry Andric case BuiltinType::Float16: OS << "F16"; break; 1160*0b57cec5SDimitry Andric case BuiltinType::Float: OS << 'F'; break; 1161*0b57cec5SDimitry Andric case BuiltinType::LongDouble: OS << 'L'; break; 1162*0b57cec5SDimitry Andric case BuiltinType::Float128: OS << 'Q'; break; 1163*0b57cec5SDimitry Andric } 1164*0b57cec5SDimitry Andric } 1165*0b57cec5SDimitry Andric 1166*0b57cec5SDimitry Andric void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) { 1167*0b57cec5SDimitry Andric if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context)) 1168*0b57cec5SDimitry Andric return; 1169*0b57cec5SDimitry Andric PrintFloatingLiteral(OS, Node, /*PrintSuffix=*/true); 1170*0b57cec5SDimitry Andric } 1171*0b57cec5SDimitry Andric 1172*0b57cec5SDimitry Andric void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) { 1173*0b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 1174*0b57cec5SDimitry Andric OS << "i"; 1175*0b57cec5SDimitry Andric } 1176*0b57cec5SDimitry Andric 1177*0b57cec5SDimitry Andric void StmtPrinter::VisitStringLiteral(StringLiteral *Str) { 1178*0b57cec5SDimitry Andric Str->outputString(OS); 1179*0b57cec5SDimitry Andric } 1180*0b57cec5SDimitry Andric 1181*0b57cec5SDimitry Andric void StmtPrinter::VisitParenExpr(ParenExpr *Node) { 1182*0b57cec5SDimitry Andric OS << "("; 1183*0b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 1184*0b57cec5SDimitry Andric OS << ")"; 1185*0b57cec5SDimitry Andric } 1186*0b57cec5SDimitry Andric 1187*0b57cec5SDimitry Andric void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) { 1188*0b57cec5SDimitry Andric if (!Node->isPostfix()) { 1189*0b57cec5SDimitry Andric OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 1190*0b57cec5SDimitry Andric 1191*0b57cec5SDimitry Andric // Print a space if this is an "identifier operator" like __real, or if 1192*0b57cec5SDimitry Andric // it might be concatenated incorrectly like '+'. 1193*0b57cec5SDimitry Andric switch (Node->getOpcode()) { 1194*0b57cec5SDimitry Andric default: break; 1195*0b57cec5SDimitry Andric case UO_Real: 1196*0b57cec5SDimitry Andric case UO_Imag: 1197*0b57cec5SDimitry Andric case UO_Extension: 1198*0b57cec5SDimitry Andric OS << ' '; 1199*0b57cec5SDimitry Andric break; 1200*0b57cec5SDimitry Andric case UO_Plus: 1201*0b57cec5SDimitry Andric case UO_Minus: 1202*0b57cec5SDimitry Andric if (isa<UnaryOperator>(Node->getSubExpr())) 1203*0b57cec5SDimitry Andric OS << ' '; 1204*0b57cec5SDimitry Andric break; 1205*0b57cec5SDimitry Andric } 1206*0b57cec5SDimitry Andric } 1207*0b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 1208*0b57cec5SDimitry Andric 1209*0b57cec5SDimitry Andric if (Node->isPostfix()) 1210*0b57cec5SDimitry Andric OS << UnaryOperator::getOpcodeStr(Node->getOpcode()); 1211*0b57cec5SDimitry Andric } 1212*0b57cec5SDimitry Andric 1213*0b57cec5SDimitry Andric void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) { 1214*0b57cec5SDimitry Andric OS << "__builtin_offsetof("; 1215*0b57cec5SDimitry Andric Node->getTypeSourceInfo()->getType().print(OS, Policy); 1216*0b57cec5SDimitry Andric OS << ", "; 1217*0b57cec5SDimitry Andric bool PrintedSomething = false; 1218*0b57cec5SDimitry Andric for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) { 1219*0b57cec5SDimitry Andric OffsetOfNode ON = Node->getComponent(i); 1220*0b57cec5SDimitry Andric if (ON.getKind() == OffsetOfNode::Array) { 1221*0b57cec5SDimitry Andric // Array node 1222*0b57cec5SDimitry Andric OS << "["; 1223*0b57cec5SDimitry Andric PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex())); 1224*0b57cec5SDimitry Andric OS << "]"; 1225*0b57cec5SDimitry Andric PrintedSomething = true; 1226*0b57cec5SDimitry Andric continue; 1227*0b57cec5SDimitry Andric } 1228*0b57cec5SDimitry Andric 1229*0b57cec5SDimitry Andric // Skip implicit base indirections. 1230*0b57cec5SDimitry Andric if (ON.getKind() == OffsetOfNode::Base) 1231*0b57cec5SDimitry Andric continue; 1232*0b57cec5SDimitry Andric 1233*0b57cec5SDimitry Andric // Field or identifier node. 1234*0b57cec5SDimitry Andric IdentifierInfo *Id = ON.getFieldName(); 1235*0b57cec5SDimitry Andric if (!Id) 1236*0b57cec5SDimitry Andric continue; 1237*0b57cec5SDimitry Andric 1238*0b57cec5SDimitry Andric if (PrintedSomething) 1239*0b57cec5SDimitry Andric OS << "."; 1240*0b57cec5SDimitry Andric else 1241*0b57cec5SDimitry Andric PrintedSomething = true; 1242*0b57cec5SDimitry Andric OS << Id->getName(); 1243*0b57cec5SDimitry Andric } 1244*0b57cec5SDimitry Andric OS << ")"; 1245*0b57cec5SDimitry Andric } 1246*0b57cec5SDimitry Andric 1247*0b57cec5SDimitry Andric void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node){ 1248*0b57cec5SDimitry Andric switch(Node->getKind()) { 1249*0b57cec5SDimitry Andric case UETT_SizeOf: 1250*0b57cec5SDimitry Andric OS << "sizeof"; 1251*0b57cec5SDimitry Andric break; 1252*0b57cec5SDimitry Andric case UETT_AlignOf: 1253*0b57cec5SDimitry Andric if (Policy.Alignof) 1254*0b57cec5SDimitry Andric OS << "alignof"; 1255*0b57cec5SDimitry Andric else if (Policy.UnderscoreAlignof) 1256*0b57cec5SDimitry Andric OS << "_Alignof"; 1257*0b57cec5SDimitry Andric else 1258*0b57cec5SDimitry Andric OS << "__alignof"; 1259*0b57cec5SDimitry Andric break; 1260*0b57cec5SDimitry Andric case UETT_PreferredAlignOf: 1261*0b57cec5SDimitry Andric OS << "__alignof"; 1262*0b57cec5SDimitry Andric break; 1263*0b57cec5SDimitry Andric case UETT_VecStep: 1264*0b57cec5SDimitry Andric OS << "vec_step"; 1265*0b57cec5SDimitry Andric break; 1266*0b57cec5SDimitry Andric case UETT_OpenMPRequiredSimdAlign: 1267*0b57cec5SDimitry Andric OS << "__builtin_omp_required_simd_align"; 1268*0b57cec5SDimitry Andric break; 1269*0b57cec5SDimitry Andric } 1270*0b57cec5SDimitry Andric if (Node->isArgumentType()) { 1271*0b57cec5SDimitry Andric OS << '('; 1272*0b57cec5SDimitry Andric Node->getArgumentType().print(OS, Policy); 1273*0b57cec5SDimitry Andric OS << ')'; 1274*0b57cec5SDimitry Andric } else { 1275*0b57cec5SDimitry Andric OS << " "; 1276*0b57cec5SDimitry Andric PrintExpr(Node->getArgumentExpr()); 1277*0b57cec5SDimitry Andric } 1278*0b57cec5SDimitry Andric } 1279*0b57cec5SDimitry Andric 1280*0b57cec5SDimitry Andric void StmtPrinter::VisitGenericSelectionExpr(GenericSelectionExpr *Node) { 1281*0b57cec5SDimitry Andric OS << "_Generic("; 1282*0b57cec5SDimitry Andric PrintExpr(Node->getControllingExpr()); 1283*0b57cec5SDimitry Andric for (const GenericSelectionExpr::Association &Assoc : Node->associations()) { 1284*0b57cec5SDimitry Andric OS << ", "; 1285*0b57cec5SDimitry Andric QualType T = Assoc.getType(); 1286*0b57cec5SDimitry Andric if (T.isNull()) 1287*0b57cec5SDimitry Andric OS << "default"; 1288*0b57cec5SDimitry Andric else 1289*0b57cec5SDimitry Andric T.print(OS, Policy); 1290*0b57cec5SDimitry Andric OS << ": "; 1291*0b57cec5SDimitry Andric PrintExpr(Assoc.getAssociationExpr()); 1292*0b57cec5SDimitry Andric } 1293*0b57cec5SDimitry Andric OS << ")"; 1294*0b57cec5SDimitry Andric } 1295*0b57cec5SDimitry Andric 1296*0b57cec5SDimitry Andric void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) { 1297*0b57cec5SDimitry Andric PrintExpr(Node->getLHS()); 1298*0b57cec5SDimitry Andric OS << "["; 1299*0b57cec5SDimitry Andric PrintExpr(Node->getRHS()); 1300*0b57cec5SDimitry Andric OS << "]"; 1301*0b57cec5SDimitry Andric } 1302*0b57cec5SDimitry Andric 1303*0b57cec5SDimitry Andric void StmtPrinter::VisitOMPArraySectionExpr(OMPArraySectionExpr *Node) { 1304*0b57cec5SDimitry Andric PrintExpr(Node->getBase()); 1305*0b57cec5SDimitry Andric OS << "["; 1306*0b57cec5SDimitry Andric if (Node->getLowerBound()) 1307*0b57cec5SDimitry Andric PrintExpr(Node->getLowerBound()); 1308*0b57cec5SDimitry Andric if (Node->getColonLoc().isValid()) { 1309*0b57cec5SDimitry Andric OS << ":"; 1310*0b57cec5SDimitry Andric if (Node->getLength()) 1311*0b57cec5SDimitry Andric PrintExpr(Node->getLength()); 1312*0b57cec5SDimitry Andric } 1313*0b57cec5SDimitry Andric OS << "]"; 1314*0b57cec5SDimitry Andric } 1315*0b57cec5SDimitry Andric 1316*0b57cec5SDimitry Andric void StmtPrinter::PrintCallArgs(CallExpr *Call) { 1317*0b57cec5SDimitry Andric for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) { 1318*0b57cec5SDimitry Andric if (isa<CXXDefaultArgExpr>(Call->getArg(i))) { 1319*0b57cec5SDimitry Andric // Don't print any defaulted arguments 1320*0b57cec5SDimitry Andric break; 1321*0b57cec5SDimitry Andric } 1322*0b57cec5SDimitry Andric 1323*0b57cec5SDimitry Andric if (i) OS << ", "; 1324*0b57cec5SDimitry Andric PrintExpr(Call->getArg(i)); 1325*0b57cec5SDimitry Andric } 1326*0b57cec5SDimitry Andric } 1327*0b57cec5SDimitry Andric 1328*0b57cec5SDimitry Andric void StmtPrinter::VisitCallExpr(CallExpr *Call) { 1329*0b57cec5SDimitry Andric PrintExpr(Call->getCallee()); 1330*0b57cec5SDimitry Andric OS << "("; 1331*0b57cec5SDimitry Andric PrintCallArgs(Call); 1332*0b57cec5SDimitry Andric OS << ")"; 1333*0b57cec5SDimitry Andric } 1334*0b57cec5SDimitry Andric 1335*0b57cec5SDimitry Andric static bool isImplicitThis(const Expr *E) { 1336*0b57cec5SDimitry Andric if (const auto *TE = dyn_cast<CXXThisExpr>(E)) 1337*0b57cec5SDimitry Andric return TE->isImplicit(); 1338*0b57cec5SDimitry Andric return false; 1339*0b57cec5SDimitry Andric } 1340*0b57cec5SDimitry Andric 1341*0b57cec5SDimitry Andric void StmtPrinter::VisitMemberExpr(MemberExpr *Node) { 1342*0b57cec5SDimitry Andric if (!Policy.SuppressImplicitBase || !isImplicitThis(Node->getBase())) { 1343*0b57cec5SDimitry Andric PrintExpr(Node->getBase()); 1344*0b57cec5SDimitry Andric 1345*0b57cec5SDimitry Andric auto *ParentMember = dyn_cast<MemberExpr>(Node->getBase()); 1346*0b57cec5SDimitry Andric FieldDecl *ParentDecl = 1347*0b57cec5SDimitry Andric ParentMember ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl()) 1348*0b57cec5SDimitry Andric : nullptr; 1349*0b57cec5SDimitry Andric 1350*0b57cec5SDimitry Andric if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion()) 1351*0b57cec5SDimitry Andric OS << (Node->isArrow() ? "->" : "."); 1352*0b57cec5SDimitry Andric } 1353*0b57cec5SDimitry Andric 1354*0b57cec5SDimitry Andric if (auto *FD = dyn_cast<FieldDecl>(Node->getMemberDecl())) 1355*0b57cec5SDimitry Andric if (FD->isAnonymousStructOrUnion()) 1356*0b57cec5SDimitry Andric return; 1357*0b57cec5SDimitry Andric 1358*0b57cec5SDimitry Andric if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 1359*0b57cec5SDimitry Andric Qualifier->print(OS, Policy); 1360*0b57cec5SDimitry Andric if (Node->hasTemplateKeyword()) 1361*0b57cec5SDimitry Andric OS << "template "; 1362*0b57cec5SDimitry Andric OS << Node->getMemberNameInfo(); 1363*0b57cec5SDimitry Andric if (Node->hasExplicitTemplateArgs()) 1364*0b57cec5SDimitry Andric printTemplateArgumentList(OS, Node->template_arguments(), Policy); 1365*0b57cec5SDimitry Andric } 1366*0b57cec5SDimitry Andric 1367*0b57cec5SDimitry Andric void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) { 1368*0b57cec5SDimitry Andric PrintExpr(Node->getBase()); 1369*0b57cec5SDimitry Andric OS << (Node->isArrow() ? "->isa" : ".isa"); 1370*0b57cec5SDimitry Andric } 1371*0b57cec5SDimitry Andric 1372*0b57cec5SDimitry Andric void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) { 1373*0b57cec5SDimitry Andric PrintExpr(Node->getBase()); 1374*0b57cec5SDimitry Andric OS << "."; 1375*0b57cec5SDimitry Andric OS << Node->getAccessor().getName(); 1376*0b57cec5SDimitry Andric } 1377*0b57cec5SDimitry Andric 1378*0b57cec5SDimitry Andric void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) { 1379*0b57cec5SDimitry Andric OS << '('; 1380*0b57cec5SDimitry Andric Node->getTypeAsWritten().print(OS, Policy); 1381*0b57cec5SDimitry Andric OS << ')'; 1382*0b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 1383*0b57cec5SDimitry Andric } 1384*0b57cec5SDimitry Andric 1385*0b57cec5SDimitry Andric void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) { 1386*0b57cec5SDimitry Andric OS << '('; 1387*0b57cec5SDimitry Andric Node->getType().print(OS, Policy); 1388*0b57cec5SDimitry Andric OS << ')'; 1389*0b57cec5SDimitry Andric PrintExpr(Node->getInitializer()); 1390*0b57cec5SDimitry Andric } 1391*0b57cec5SDimitry Andric 1392*0b57cec5SDimitry Andric void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) { 1393*0b57cec5SDimitry Andric // No need to print anything, simply forward to the subexpression. 1394*0b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 1395*0b57cec5SDimitry Andric } 1396*0b57cec5SDimitry Andric 1397*0b57cec5SDimitry Andric void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) { 1398*0b57cec5SDimitry Andric PrintExpr(Node->getLHS()); 1399*0b57cec5SDimitry Andric OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 1400*0b57cec5SDimitry Andric PrintExpr(Node->getRHS()); 1401*0b57cec5SDimitry Andric } 1402*0b57cec5SDimitry Andric 1403*0b57cec5SDimitry Andric void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) { 1404*0b57cec5SDimitry Andric PrintExpr(Node->getLHS()); 1405*0b57cec5SDimitry Andric OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " "; 1406*0b57cec5SDimitry Andric PrintExpr(Node->getRHS()); 1407*0b57cec5SDimitry Andric } 1408*0b57cec5SDimitry Andric 1409*0b57cec5SDimitry Andric void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) { 1410*0b57cec5SDimitry Andric PrintExpr(Node->getCond()); 1411*0b57cec5SDimitry Andric OS << " ? "; 1412*0b57cec5SDimitry Andric PrintExpr(Node->getLHS()); 1413*0b57cec5SDimitry Andric OS << " : "; 1414*0b57cec5SDimitry Andric PrintExpr(Node->getRHS()); 1415*0b57cec5SDimitry Andric } 1416*0b57cec5SDimitry Andric 1417*0b57cec5SDimitry Andric // GNU extensions. 1418*0b57cec5SDimitry Andric 1419*0b57cec5SDimitry Andric void 1420*0b57cec5SDimitry Andric StmtPrinter::VisitBinaryConditionalOperator(BinaryConditionalOperator *Node) { 1421*0b57cec5SDimitry Andric PrintExpr(Node->getCommon()); 1422*0b57cec5SDimitry Andric OS << " ?: "; 1423*0b57cec5SDimitry Andric PrintExpr(Node->getFalseExpr()); 1424*0b57cec5SDimitry Andric } 1425*0b57cec5SDimitry Andric 1426*0b57cec5SDimitry Andric void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) { 1427*0b57cec5SDimitry Andric OS << "&&" << Node->getLabel()->getName(); 1428*0b57cec5SDimitry Andric } 1429*0b57cec5SDimitry Andric 1430*0b57cec5SDimitry Andric void StmtPrinter::VisitStmtExpr(StmtExpr *E) { 1431*0b57cec5SDimitry Andric OS << "("; 1432*0b57cec5SDimitry Andric PrintRawCompoundStmt(E->getSubStmt()); 1433*0b57cec5SDimitry Andric OS << ")"; 1434*0b57cec5SDimitry Andric } 1435*0b57cec5SDimitry Andric 1436*0b57cec5SDimitry Andric void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) { 1437*0b57cec5SDimitry Andric OS << "__builtin_choose_expr("; 1438*0b57cec5SDimitry Andric PrintExpr(Node->getCond()); 1439*0b57cec5SDimitry Andric OS << ", "; 1440*0b57cec5SDimitry Andric PrintExpr(Node->getLHS()); 1441*0b57cec5SDimitry Andric OS << ", "; 1442*0b57cec5SDimitry Andric PrintExpr(Node->getRHS()); 1443*0b57cec5SDimitry Andric OS << ")"; 1444*0b57cec5SDimitry Andric } 1445*0b57cec5SDimitry Andric 1446*0b57cec5SDimitry Andric void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) { 1447*0b57cec5SDimitry Andric OS << "__null"; 1448*0b57cec5SDimitry Andric } 1449*0b57cec5SDimitry Andric 1450*0b57cec5SDimitry Andric void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) { 1451*0b57cec5SDimitry Andric OS << "__builtin_shufflevector("; 1452*0b57cec5SDimitry Andric for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) { 1453*0b57cec5SDimitry Andric if (i) OS << ", "; 1454*0b57cec5SDimitry Andric PrintExpr(Node->getExpr(i)); 1455*0b57cec5SDimitry Andric } 1456*0b57cec5SDimitry Andric OS << ")"; 1457*0b57cec5SDimitry Andric } 1458*0b57cec5SDimitry Andric 1459*0b57cec5SDimitry Andric void StmtPrinter::VisitConvertVectorExpr(ConvertVectorExpr *Node) { 1460*0b57cec5SDimitry Andric OS << "__builtin_convertvector("; 1461*0b57cec5SDimitry Andric PrintExpr(Node->getSrcExpr()); 1462*0b57cec5SDimitry Andric OS << ", "; 1463*0b57cec5SDimitry Andric Node->getType().print(OS, Policy); 1464*0b57cec5SDimitry Andric OS << ")"; 1465*0b57cec5SDimitry Andric } 1466*0b57cec5SDimitry Andric 1467*0b57cec5SDimitry Andric void StmtPrinter::VisitInitListExpr(InitListExpr* Node) { 1468*0b57cec5SDimitry Andric if (Node->getSyntacticForm()) { 1469*0b57cec5SDimitry Andric Visit(Node->getSyntacticForm()); 1470*0b57cec5SDimitry Andric return; 1471*0b57cec5SDimitry Andric } 1472*0b57cec5SDimitry Andric 1473*0b57cec5SDimitry Andric OS << "{"; 1474*0b57cec5SDimitry Andric for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) { 1475*0b57cec5SDimitry Andric if (i) OS << ", "; 1476*0b57cec5SDimitry Andric if (Node->getInit(i)) 1477*0b57cec5SDimitry Andric PrintExpr(Node->getInit(i)); 1478*0b57cec5SDimitry Andric else 1479*0b57cec5SDimitry Andric OS << "{}"; 1480*0b57cec5SDimitry Andric } 1481*0b57cec5SDimitry Andric OS << "}"; 1482*0b57cec5SDimitry Andric } 1483*0b57cec5SDimitry Andric 1484*0b57cec5SDimitry Andric void StmtPrinter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *Node) { 1485*0b57cec5SDimitry Andric // There's no way to express this expression in any of our supported 1486*0b57cec5SDimitry Andric // languages, so just emit something terse and (hopefully) clear. 1487*0b57cec5SDimitry Andric OS << "{"; 1488*0b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 1489*0b57cec5SDimitry Andric OS << "}"; 1490*0b57cec5SDimitry Andric } 1491*0b57cec5SDimitry Andric 1492*0b57cec5SDimitry Andric void StmtPrinter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *Node) { 1493*0b57cec5SDimitry Andric OS << "*"; 1494*0b57cec5SDimitry Andric } 1495*0b57cec5SDimitry Andric 1496*0b57cec5SDimitry Andric void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) { 1497*0b57cec5SDimitry Andric OS << "("; 1498*0b57cec5SDimitry Andric for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) { 1499*0b57cec5SDimitry Andric if (i) OS << ", "; 1500*0b57cec5SDimitry Andric PrintExpr(Node->getExpr(i)); 1501*0b57cec5SDimitry Andric } 1502*0b57cec5SDimitry Andric OS << ")"; 1503*0b57cec5SDimitry Andric } 1504*0b57cec5SDimitry Andric 1505*0b57cec5SDimitry Andric void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) { 1506*0b57cec5SDimitry Andric bool NeedsEquals = true; 1507*0b57cec5SDimitry Andric for (const DesignatedInitExpr::Designator &D : Node->designators()) { 1508*0b57cec5SDimitry Andric if (D.isFieldDesignator()) { 1509*0b57cec5SDimitry Andric if (D.getDotLoc().isInvalid()) { 1510*0b57cec5SDimitry Andric if (IdentifierInfo *II = D.getFieldName()) { 1511*0b57cec5SDimitry Andric OS << II->getName() << ":"; 1512*0b57cec5SDimitry Andric NeedsEquals = false; 1513*0b57cec5SDimitry Andric } 1514*0b57cec5SDimitry Andric } else { 1515*0b57cec5SDimitry Andric OS << "." << D.getFieldName()->getName(); 1516*0b57cec5SDimitry Andric } 1517*0b57cec5SDimitry Andric } else { 1518*0b57cec5SDimitry Andric OS << "["; 1519*0b57cec5SDimitry Andric if (D.isArrayDesignator()) { 1520*0b57cec5SDimitry Andric PrintExpr(Node->getArrayIndex(D)); 1521*0b57cec5SDimitry Andric } else { 1522*0b57cec5SDimitry Andric PrintExpr(Node->getArrayRangeStart(D)); 1523*0b57cec5SDimitry Andric OS << " ... "; 1524*0b57cec5SDimitry Andric PrintExpr(Node->getArrayRangeEnd(D)); 1525*0b57cec5SDimitry Andric } 1526*0b57cec5SDimitry Andric OS << "]"; 1527*0b57cec5SDimitry Andric } 1528*0b57cec5SDimitry Andric } 1529*0b57cec5SDimitry Andric 1530*0b57cec5SDimitry Andric if (NeedsEquals) 1531*0b57cec5SDimitry Andric OS << " = "; 1532*0b57cec5SDimitry Andric else 1533*0b57cec5SDimitry Andric OS << " "; 1534*0b57cec5SDimitry Andric PrintExpr(Node->getInit()); 1535*0b57cec5SDimitry Andric } 1536*0b57cec5SDimitry Andric 1537*0b57cec5SDimitry Andric void StmtPrinter::VisitDesignatedInitUpdateExpr( 1538*0b57cec5SDimitry Andric DesignatedInitUpdateExpr *Node) { 1539*0b57cec5SDimitry Andric OS << "{"; 1540*0b57cec5SDimitry Andric OS << "/*base*/"; 1541*0b57cec5SDimitry Andric PrintExpr(Node->getBase()); 1542*0b57cec5SDimitry Andric OS << ", "; 1543*0b57cec5SDimitry Andric 1544*0b57cec5SDimitry Andric OS << "/*updater*/"; 1545*0b57cec5SDimitry Andric PrintExpr(Node->getUpdater()); 1546*0b57cec5SDimitry Andric OS << "}"; 1547*0b57cec5SDimitry Andric } 1548*0b57cec5SDimitry Andric 1549*0b57cec5SDimitry Andric void StmtPrinter::VisitNoInitExpr(NoInitExpr *Node) { 1550*0b57cec5SDimitry Andric OS << "/*no init*/"; 1551*0b57cec5SDimitry Andric } 1552*0b57cec5SDimitry Andric 1553*0b57cec5SDimitry Andric void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) { 1554*0b57cec5SDimitry Andric if (Node->getType()->getAsCXXRecordDecl()) { 1555*0b57cec5SDimitry Andric OS << "/*implicit*/"; 1556*0b57cec5SDimitry Andric Node->getType().print(OS, Policy); 1557*0b57cec5SDimitry Andric OS << "()"; 1558*0b57cec5SDimitry Andric } else { 1559*0b57cec5SDimitry Andric OS << "/*implicit*/("; 1560*0b57cec5SDimitry Andric Node->getType().print(OS, Policy); 1561*0b57cec5SDimitry Andric OS << ')'; 1562*0b57cec5SDimitry Andric if (Node->getType()->isRecordType()) 1563*0b57cec5SDimitry Andric OS << "{}"; 1564*0b57cec5SDimitry Andric else 1565*0b57cec5SDimitry Andric OS << 0; 1566*0b57cec5SDimitry Andric } 1567*0b57cec5SDimitry Andric } 1568*0b57cec5SDimitry Andric 1569*0b57cec5SDimitry Andric void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) { 1570*0b57cec5SDimitry Andric OS << "__builtin_va_arg("; 1571*0b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 1572*0b57cec5SDimitry Andric OS << ", "; 1573*0b57cec5SDimitry Andric Node->getType().print(OS, Policy); 1574*0b57cec5SDimitry Andric OS << ")"; 1575*0b57cec5SDimitry Andric } 1576*0b57cec5SDimitry Andric 1577*0b57cec5SDimitry Andric void StmtPrinter::VisitPseudoObjectExpr(PseudoObjectExpr *Node) { 1578*0b57cec5SDimitry Andric PrintExpr(Node->getSyntacticForm()); 1579*0b57cec5SDimitry Andric } 1580*0b57cec5SDimitry Andric 1581*0b57cec5SDimitry Andric void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) { 1582*0b57cec5SDimitry Andric const char *Name = nullptr; 1583*0b57cec5SDimitry Andric switch (Node->getOp()) { 1584*0b57cec5SDimitry Andric #define BUILTIN(ID, TYPE, ATTRS) 1585*0b57cec5SDimitry Andric #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \ 1586*0b57cec5SDimitry Andric case AtomicExpr::AO ## ID: \ 1587*0b57cec5SDimitry Andric Name = #ID "("; \ 1588*0b57cec5SDimitry Andric break; 1589*0b57cec5SDimitry Andric #include "clang/Basic/Builtins.def" 1590*0b57cec5SDimitry Andric } 1591*0b57cec5SDimitry Andric OS << Name; 1592*0b57cec5SDimitry Andric 1593*0b57cec5SDimitry Andric // AtomicExpr stores its subexpressions in a permuted order. 1594*0b57cec5SDimitry Andric PrintExpr(Node->getPtr()); 1595*0b57cec5SDimitry Andric if (Node->getOp() != AtomicExpr::AO__c11_atomic_load && 1596*0b57cec5SDimitry Andric Node->getOp() != AtomicExpr::AO__atomic_load_n && 1597*0b57cec5SDimitry Andric Node->getOp() != AtomicExpr::AO__opencl_atomic_load) { 1598*0b57cec5SDimitry Andric OS << ", "; 1599*0b57cec5SDimitry Andric PrintExpr(Node->getVal1()); 1600*0b57cec5SDimitry Andric } 1601*0b57cec5SDimitry Andric if (Node->getOp() == AtomicExpr::AO__atomic_exchange || 1602*0b57cec5SDimitry Andric Node->isCmpXChg()) { 1603*0b57cec5SDimitry Andric OS << ", "; 1604*0b57cec5SDimitry Andric PrintExpr(Node->getVal2()); 1605*0b57cec5SDimitry Andric } 1606*0b57cec5SDimitry Andric if (Node->getOp() == AtomicExpr::AO__atomic_compare_exchange || 1607*0b57cec5SDimitry Andric Node->getOp() == AtomicExpr::AO__atomic_compare_exchange_n) { 1608*0b57cec5SDimitry Andric OS << ", "; 1609*0b57cec5SDimitry Andric PrintExpr(Node->getWeak()); 1610*0b57cec5SDimitry Andric } 1611*0b57cec5SDimitry Andric if (Node->getOp() != AtomicExpr::AO__c11_atomic_init && 1612*0b57cec5SDimitry Andric Node->getOp() != AtomicExpr::AO__opencl_atomic_init) { 1613*0b57cec5SDimitry Andric OS << ", "; 1614*0b57cec5SDimitry Andric PrintExpr(Node->getOrder()); 1615*0b57cec5SDimitry Andric } 1616*0b57cec5SDimitry Andric if (Node->isCmpXChg()) { 1617*0b57cec5SDimitry Andric OS << ", "; 1618*0b57cec5SDimitry Andric PrintExpr(Node->getOrderFail()); 1619*0b57cec5SDimitry Andric } 1620*0b57cec5SDimitry Andric OS << ")"; 1621*0b57cec5SDimitry Andric } 1622*0b57cec5SDimitry Andric 1623*0b57cec5SDimitry Andric // C++ 1624*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) { 1625*0b57cec5SDimitry Andric OverloadedOperatorKind Kind = Node->getOperator(); 1626*0b57cec5SDimitry Andric if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) { 1627*0b57cec5SDimitry Andric if (Node->getNumArgs() == 1) { 1628*0b57cec5SDimitry Andric OS << getOperatorSpelling(Kind) << ' '; 1629*0b57cec5SDimitry Andric PrintExpr(Node->getArg(0)); 1630*0b57cec5SDimitry Andric } else { 1631*0b57cec5SDimitry Andric PrintExpr(Node->getArg(0)); 1632*0b57cec5SDimitry Andric OS << ' ' << getOperatorSpelling(Kind); 1633*0b57cec5SDimitry Andric } 1634*0b57cec5SDimitry Andric } else if (Kind == OO_Arrow) { 1635*0b57cec5SDimitry Andric PrintExpr(Node->getArg(0)); 1636*0b57cec5SDimitry Andric } else if (Kind == OO_Call) { 1637*0b57cec5SDimitry Andric PrintExpr(Node->getArg(0)); 1638*0b57cec5SDimitry Andric OS << '('; 1639*0b57cec5SDimitry Andric for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) { 1640*0b57cec5SDimitry Andric if (ArgIdx > 1) 1641*0b57cec5SDimitry Andric OS << ", "; 1642*0b57cec5SDimitry Andric if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx))) 1643*0b57cec5SDimitry Andric PrintExpr(Node->getArg(ArgIdx)); 1644*0b57cec5SDimitry Andric } 1645*0b57cec5SDimitry Andric OS << ')'; 1646*0b57cec5SDimitry Andric } else if (Kind == OO_Subscript) { 1647*0b57cec5SDimitry Andric PrintExpr(Node->getArg(0)); 1648*0b57cec5SDimitry Andric OS << '['; 1649*0b57cec5SDimitry Andric PrintExpr(Node->getArg(1)); 1650*0b57cec5SDimitry Andric OS << ']'; 1651*0b57cec5SDimitry Andric } else if (Node->getNumArgs() == 1) { 1652*0b57cec5SDimitry Andric OS << getOperatorSpelling(Kind) << ' '; 1653*0b57cec5SDimitry Andric PrintExpr(Node->getArg(0)); 1654*0b57cec5SDimitry Andric } else if (Node->getNumArgs() == 2) { 1655*0b57cec5SDimitry Andric PrintExpr(Node->getArg(0)); 1656*0b57cec5SDimitry Andric OS << ' ' << getOperatorSpelling(Kind) << ' '; 1657*0b57cec5SDimitry Andric PrintExpr(Node->getArg(1)); 1658*0b57cec5SDimitry Andric } else { 1659*0b57cec5SDimitry Andric llvm_unreachable("unknown overloaded operator"); 1660*0b57cec5SDimitry Andric } 1661*0b57cec5SDimitry Andric } 1662*0b57cec5SDimitry Andric 1663*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) { 1664*0b57cec5SDimitry Andric // If we have a conversion operator call only print the argument. 1665*0b57cec5SDimitry Andric CXXMethodDecl *MD = Node->getMethodDecl(); 1666*0b57cec5SDimitry Andric if (MD && isa<CXXConversionDecl>(MD)) { 1667*0b57cec5SDimitry Andric PrintExpr(Node->getImplicitObjectArgument()); 1668*0b57cec5SDimitry Andric return; 1669*0b57cec5SDimitry Andric } 1670*0b57cec5SDimitry Andric VisitCallExpr(cast<CallExpr>(Node)); 1671*0b57cec5SDimitry Andric } 1672*0b57cec5SDimitry Andric 1673*0b57cec5SDimitry Andric void StmtPrinter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *Node) { 1674*0b57cec5SDimitry Andric PrintExpr(Node->getCallee()); 1675*0b57cec5SDimitry Andric OS << "<<<"; 1676*0b57cec5SDimitry Andric PrintCallArgs(Node->getConfig()); 1677*0b57cec5SDimitry Andric OS << ">>>("; 1678*0b57cec5SDimitry Andric PrintCallArgs(Node); 1679*0b57cec5SDimitry Andric OS << ")"; 1680*0b57cec5SDimitry Andric } 1681*0b57cec5SDimitry Andric 1682*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) { 1683*0b57cec5SDimitry Andric OS << Node->getCastName() << '<'; 1684*0b57cec5SDimitry Andric Node->getTypeAsWritten().print(OS, Policy); 1685*0b57cec5SDimitry Andric OS << ">("; 1686*0b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 1687*0b57cec5SDimitry Andric OS << ")"; 1688*0b57cec5SDimitry Andric } 1689*0b57cec5SDimitry Andric 1690*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) { 1691*0b57cec5SDimitry Andric VisitCXXNamedCastExpr(Node); 1692*0b57cec5SDimitry Andric } 1693*0b57cec5SDimitry Andric 1694*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) { 1695*0b57cec5SDimitry Andric VisitCXXNamedCastExpr(Node); 1696*0b57cec5SDimitry Andric } 1697*0b57cec5SDimitry Andric 1698*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) { 1699*0b57cec5SDimitry Andric VisitCXXNamedCastExpr(Node); 1700*0b57cec5SDimitry Andric } 1701*0b57cec5SDimitry Andric 1702*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) { 1703*0b57cec5SDimitry Andric VisitCXXNamedCastExpr(Node); 1704*0b57cec5SDimitry Andric } 1705*0b57cec5SDimitry Andric 1706*0b57cec5SDimitry Andric void StmtPrinter::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *Node) { 1707*0b57cec5SDimitry Andric OS << "__builtin_bit_cast("; 1708*0b57cec5SDimitry Andric Node->getTypeInfoAsWritten()->getType().print(OS, Policy); 1709*0b57cec5SDimitry Andric OS << ", "; 1710*0b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 1711*0b57cec5SDimitry Andric OS << ")"; 1712*0b57cec5SDimitry Andric } 1713*0b57cec5SDimitry Andric 1714*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) { 1715*0b57cec5SDimitry Andric OS << "typeid("; 1716*0b57cec5SDimitry Andric if (Node->isTypeOperand()) { 1717*0b57cec5SDimitry Andric Node->getTypeOperandSourceInfo()->getType().print(OS, Policy); 1718*0b57cec5SDimitry Andric } else { 1719*0b57cec5SDimitry Andric PrintExpr(Node->getExprOperand()); 1720*0b57cec5SDimitry Andric } 1721*0b57cec5SDimitry Andric OS << ")"; 1722*0b57cec5SDimitry Andric } 1723*0b57cec5SDimitry Andric 1724*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) { 1725*0b57cec5SDimitry Andric OS << "__uuidof("; 1726*0b57cec5SDimitry Andric if (Node->isTypeOperand()) { 1727*0b57cec5SDimitry Andric Node->getTypeOperandSourceInfo()->getType().print(OS, Policy); 1728*0b57cec5SDimitry Andric } else { 1729*0b57cec5SDimitry Andric PrintExpr(Node->getExprOperand()); 1730*0b57cec5SDimitry Andric } 1731*0b57cec5SDimitry Andric OS << ")"; 1732*0b57cec5SDimitry Andric } 1733*0b57cec5SDimitry Andric 1734*0b57cec5SDimitry Andric void StmtPrinter::VisitMSPropertyRefExpr(MSPropertyRefExpr *Node) { 1735*0b57cec5SDimitry Andric PrintExpr(Node->getBaseExpr()); 1736*0b57cec5SDimitry Andric if (Node->isArrow()) 1737*0b57cec5SDimitry Andric OS << "->"; 1738*0b57cec5SDimitry Andric else 1739*0b57cec5SDimitry Andric OS << "."; 1740*0b57cec5SDimitry Andric if (NestedNameSpecifier *Qualifier = 1741*0b57cec5SDimitry Andric Node->getQualifierLoc().getNestedNameSpecifier()) 1742*0b57cec5SDimitry Andric Qualifier->print(OS, Policy); 1743*0b57cec5SDimitry Andric OS << Node->getPropertyDecl()->getDeclName(); 1744*0b57cec5SDimitry Andric } 1745*0b57cec5SDimitry Andric 1746*0b57cec5SDimitry Andric void StmtPrinter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *Node) { 1747*0b57cec5SDimitry Andric PrintExpr(Node->getBase()); 1748*0b57cec5SDimitry Andric OS << "["; 1749*0b57cec5SDimitry Andric PrintExpr(Node->getIdx()); 1750*0b57cec5SDimitry Andric OS << "]"; 1751*0b57cec5SDimitry Andric } 1752*0b57cec5SDimitry Andric 1753*0b57cec5SDimitry Andric void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) { 1754*0b57cec5SDimitry Andric switch (Node->getLiteralOperatorKind()) { 1755*0b57cec5SDimitry Andric case UserDefinedLiteral::LOK_Raw: 1756*0b57cec5SDimitry Andric OS << cast<StringLiteral>(Node->getArg(0)->IgnoreImpCasts())->getString(); 1757*0b57cec5SDimitry Andric break; 1758*0b57cec5SDimitry Andric case UserDefinedLiteral::LOK_Template: { 1759*0b57cec5SDimitry Andric const auto *DRE = cast<DeclRefExpr>(Node->getCallee()->IgnoreImpCasts()); 1760*0b57cec5SDimitry Andric const TemplateArgumentList *Args = 1761*0b57cec5SDimitry Andric cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs(); 1762*0b57cec5SDimitry Andric assert(Args); 1763*0b57cec5SDimitry Andric 1764*0b57cec5SDimitry Andric if (Args->size() != 1) { 1765*0b57cec5SDimitry Andric OS << "operator\"\"" << Node->getUDSuffix()->getName(); 1766*0b57cec5SDimitry Andric printTemplateArgumentList(OS, Args->asArray(), Policy); 1767*0b57cec5SDimitry Andric OS << "()"; 1768*0b57cec5SDimitry Andric return; 1769*0b57cec5SDimitry Andric } 1770*0b57cec5SDimitry Andric 1771*0b57cec5SDimitry Andric const TemplateArgument &Pack = Args->get(0); 1772*0b57cec5SDimitry Andric for (const auto &P : Pack.pack_elements()) { 1773*0b57cec5SDimitry Andric char C = (char)P.getAsIntegral().getZExtValue(); 1774*0b57cec5SDimitry Andric OS << C; 1775*0b57cec5SDimitry Andric } 1776*0b57cec5SDimitry Andric break; 1777*0b57cec5SDimitry Andric } 1778*0b57cec5SDimitry Andric case UserDefinedLiteral::LOK_Integer: { 1779*0b57cec5SDimitry Andric // Print integer literal without suffix. 1780*0b57cec5SDimitry Andric const auto *Int = cast<IntegerLiteral>(Node->getCookedLiteral()); 1781*0b57cec5SDimitry Andric OS << Int->getValue().toString(10, /*isSigned*/false); 1782*0b57cec5SDimitry Andric break; 1783*0b57cec5SDimitry Andric } 1784*0b57cec5SDimitry Andric case UserDefinedLiteral::LOK_Floating: { 1785*0b57cec5SDimitry Andric // Print floating literal without suffix. 1786*0b57cec5SDimitry Andric auto *Float = cast<FloatingLiteral>(Node->getCookedLiteral()); 1787*0b57cec5SDimitry Andric PrintFloatingLiteral(OS, Float, /*PrintSuffix=*/false); 1788*0b57cec5SDimitry Andric break; 1789*0b57cec5SDimitry Andric } 1790*0b57cec5SDimitry Andric case UserDefinedLiteral::LOK_String: 1791*0b57cec5SDimitry Andric case UserDefinedLiteral::LOK_Character: 1792*0b57cec5SDimitry Andric PrintExpr(Node->getCookedLiteral()); 1793*0b57cec5SDimitry Andric break; 1794*0b57cec5SDimitry Andric } 1795*0b57cec5SDimitry Andric OS << Node->getUDSuffix()->getName(); 1796*0b57cec5SDimitry Andric } 1797*0b57cec5SDimitry Andric 1798*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) { 1799*0b57cec5SDimitry Andric OS << (Node->getValue() ? "true" : "false"); 1800*0b57cec5SDimitry Andric } 1801*0b57cec5SDimitry Andric 1802*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) { 1803*0b57cec5SDimitry Andric OS << "nullptr"; 1804*0b57cec5SDimitry Andric } 1805*0b57cec5SDimitry Andric 1806*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) { 1807*0b57cec5SDimitry Andric OS << "this"; 1808*0b57cec5SDimitry Andric } 1809*0b57cec5SDimitry Andric 1810*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) { 1811*0b57cec5SDimitry Andric if (!Node->getSubExpr()) 1812*0b57cec5SDimitry Andric OS << "throw"; 1813*0b57cec5SDimitry Andric else { 1814*0b57cec5SDimitry Andric OS << "throw "; 1815*0b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 1816*0b57cec5SDimitry Andric } 1817*0b57cec5SDimitry Andric } 1818*0b57cec5SDimitry Andric 1819*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) { 1820*0b57cec5SDimitry Andric // Nothing to print: we picked up the default argument. 1821*0b57cec5SDimitry Andric } 1822*0b57cec5SDimitry Andric 1823*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Node) { 1824*0b57cec5SDimitry Andric // Nothing to print: we picked up the default initializer. 1825*0b57cec5SDimitry Andric } 1826*0b57cec5SDimitry Andric 1827*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) { 1828*0b57cec5SDimitry Andric Node->getType().print(OS, Policy); 1829*0b57cec5SDimitry Andric // If there are no parens, this is list-initialization, and the braces are 1830*0b57cec5SDimitry Andric // part of the syntax of the inner construct. 1831*0b57cec5SDimitry Andric if (Node->getLParenLoc().isValid()) 1832*0b57cec5SDimitry Andric OS << "("; 1833*0b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 1834*0b57cec5SDimitry Andric if (Node->getLParenLoc().isValid()) 1835*0b57cec5SDimitry Andric OS << ")"; 1836*0b57cec5SDimitry Andric } 1837*0b57cec5SDimitry Andric 1838*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) { 1839*0b57cec5SDimitry Andric PrintExpr(Node->getSubExpr()); 1840*0b57cec5SDimitry Andric } 1841*0b57cec5SDimitry Andric 1842*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) { 1843*0b57cec5SDimitry Andric Node->getType().print(OS, Policy); 1844*0b57cec5SDimitry Andric if (Node->isStdInitListInitialization()) 1845*0b57cec5SDimitry Andric /* Nothing to do; braces are part of creating the std::initializer_list. */; 1846*0b57cec5SDimitry Andric else if (Node->isListInitialization()) 1847*0b57cec5SDimitry Andric OS << "{"; 1848*0b57cec5SDimitry Andric else 1849*0b57cec5SDimitry Andric OS << "("; 1850*0b57cec5SDimitry Andric for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(), 1851*0b57cec5SDimitry Andric ArgEnd = Node->arg_end(); 1852*0b57cec5SDimitry Andric Arg != ArgEnd; ++Arg) { 1853*0b57cec5SDimitry Andric if ((*Arg)->isDefaultArgument()) 1854*0b57cec5SDimitry Andric break; 1855*0b57cec5SDimitry Andric if (Arg != Node->arg_begin()) 1856*0b57cec5SDimitry Andric OS << ", "; 1857*0b57cec5SDimitry Andric PrintExpr(*Arg); 1858*0b57cec5SDimitry Andric } 1859*0b57cec5SDimitry Andric if (Node->isStdInitListInitialization()) 1860*0b57cec5SDimitry Andric /* See above. */; 1861*0b57cec5SDimitry Andric else if (Node->isListInitialization()) 1862*0b57cec5SDimitry Andric OS << "}"; 1863*0b57cec5SDimitry Andric else 1864*0b57cec5SDimitry Andric OS << ")"; 1865*0b57cec5SDimitry Andric } 1866*0b57cec5SDimitry Andric 1867*0b57cec5SDimitry Andric void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) { 1868*0b57cec5SDimitry Andric OS << '['; 1869*0b57cec5SDimitry Andric bool NeedComma = false; 1870*0b57cec5SDimitry Andric switch (Node->getCaptureDefault()) { 1871*0b57cec5SDimitry Andric case LCD_None: 1872*0b57cec5SDimitry Andric break; 1873*0b57cec5SDimitry Andric 1874*0b57cec5SDimitry Andric case LCD_ByCopy: 1875*0b57cec5SDimitry Andric OS << '='; 1876*0b57cec5SDimitry Andric NeedComma = true; 1877*0b57cec5SDimitry Andric break; 1878*0b57cec5SDimitry Andric 1879*0b57cec5SDimitry Andric case LCD_ByRef: 1880*0b57cec5SDimitry Andric OS << '&'; 1881*0b57cec5SDimitry Andric NeedComma = true; 1882*0b57cec5SDimitry Andric break; 1883*0b57cec5SDimitry Andric } 1884*0b57cec5SDimitry Andric for (LambdaExpr::capture_iterator C = Node->explicit_capture_begin(), 1885*0b57cec5SDimitry Andric CEnd = Node->explicit_capture_end(); 1886*0b57cec5SDimitry Andric C != CEnd; 1887*0b57cec5SDimitry Andric ++C) { 1888*0b57cec5SDimitry Andric if (C->capturesVLAType()) 1889*0b57cec5SDimitry Andric continue; 1890*0b57cec5SDimitry Andric 1891*0b57cec5SDimitry Andric if (NeedComma) 1892*0b57cec5SDimitry Andric OS << ", "; 1893*0b57cec5SDimitry Andric NeedComma = true; 1894*0b57cec5SDimitry Andric 1895*0b57cec5SDimitry Andric switch (C->getCaptureKind()) { 1896*0b57cec5SDimitry Andric case LCK_This: 1897*0b57cec5SDimitry Andric OS << "this"; 1898*0b57cec5SDimitry Andric break; 1899*0b57cec5SDimitry Andric 1900*0b57cec5SDimitry Andric case LCK_StarThis: 1901*0b57cec5SDimitry Andric OS << "*this"; 1902*0b57cec5SDimitry Andric break; 1903*0b57cec5SDimitry Andric 1904*0b57cec5SDimitry Andric case LCK_ByRef: 1905*0b57cec5SDimitry Andric if (Node->getCaptureDefault() != LCD_ByRef || Node->isInitCapture(C)) 1906*0b57cec5SDimitry Andric OS << '&'; 1907*0b57cec5SDimitry Andric OS << C->getCapturedVar()->getName(); 1908*0b57cec5SDimitry Andric break; 1909*0b57cec5SDimitry Andric 1910*0b57cec5SDimitry Andric case LCK_ByCopy: 1911*0b57cec5SDimitry Andric OS << C->getCapturedVar()->getName(); 1912*0b57cec5SDimitry Andric break; 1913*0b57cec5SDimitry Andric 1914*0b57cec5SDimitry Andric case LCK_VLAType: 1915*0b57cec5SDimitry Andric llvm_unreachable("VLA type in explicit captures."); 1916*0b57cec5SDimitry Andric } 1917*0b57cec5SDimitry Andric 1918*0b57cec5SDimitry Andric if (C->isPackExpansion()) 1919*0b57cec5SDimitry Andric OS << "..."; 1920*0b57cec5SDimitry Andric 1921*0b57cec5SDimitry Andric if (Node->isInitCapture(C)) 1922*0b57cec5SDimitry Andric PrintExpr(C->getCapturedVar()->getInit()); 1923*0b57cec5SDimitry Andric } 1924*0b57cec5SDimitry Andric OS << ']'; 1925*0b57cec5SDimitry Andric 1926*0b57cec5SDimitry Andric if (!Node->getExplicitTemplateParameters().empty()) { 1927*0b57cec5SDimitry Andric Node->getTemplateParameterList()->print( 1928*0b57cec5SDimitry Andric OS, Node->getLambdaClass()->getASTContext(), 1929*0b57cec5SDimitry Andric /*OmitTemplateKW*/true); 1930*0b57cec5SDimitry Andric } 1931*0b57cec5SDimitry Andric 1932*0b57cec5SDimitry Andric if (Node->hasExplicitParameters()) { 1933*0b57cec5SDimitry Andric OS << '('; 1934*0b57cec5SDimitry Andric CXXMethodDecl *Method = Node->getCallOperator(); 1935*0b57cec5SDimitry Andric NeedComma = false; 1936*0b57cec5SDimitry Andric for (const auto *P : Method->parameters()) { 1937*0b57cec5SDimitry Andric if (NeedComma) { 1938*0b57cec5SDimitry Andric OS << ", "; 1939*0b57cec5SDimitry Andric } else { 1940*0b57cec5SDimitry Andric NeedComma = true; 1941*0b57cec5SDimitry Andric } 1942*0b57cec5SDimitry Andric std::string ParamStr = P->getNameAsString(); 1943*0b57cec5SDimitry Andric P->getOriginalType().print(OS, Policy, ParamStr); 1944*0b57cec5SDimitry Andric } 1945*0b57cec5SDimitry Andric if (Method->isVariadic()) { 1946*0b57cec5SDimitry Andric if (NeedComma) 1947*0b57cec5SDimitry Andric OS << ", "; 1948*0b57cec5SDimitry Andric OS << "..."; 1949*0b57cec5SDimitry Andric } 1950*0b57cec5SDimitry Andric OS << ')'; 1951*0b57cec5SDimitry Andric 1952*0b57cec5SDimitry Andric if (Node->isMutable()) 1953*0b57cec5SDimitry Andric OS << " mutable"; 1954*0b57cec5SDimitry Andric 1955*0b57cec5SDimitry Andric auto *Proto = Method->getType()->getAs<FunctionProtoType>(); 1956*0b57cec5SDimitry Andric Proto->printExceptionSpecification(OS, Policy); 1957*0b57cec5SDimitry Andric 1958*0b57cec5SDimitry Andric // FIXME: Attributes 1959*0b57cec5SDimitry Andric 1960*0b57cec5SDimitry Andric // Print the trailing return type if it was specified in the source. 1961*0b57cec5SDimitry Andric if (Node->hasExplicitResultType()) { 1962*0b57cec5SDimitry Andric OS << " -> "; 1963*0b57cec5SDimitry Andric Proto->getReturnType().print(OS, Policy); 1964*0b57cec5SDimitry Andric } 1965*0b57cec5SDimitry Andric } 1966*0b57cec5SDimitry Andric 1967*0b57cec5SDimitry Andric // Print the body. 1968*0b57cec5SDimitry Andric OS << ' '; 1969*0b57cec5SDimitry Andric if (Policy.TerseOutput) 1970*0b57cec5SDimitry Andric OS << "{}"; 1971*0b57cec5SDimitry Andric else 1972*0b57cec5SDimitry Andric PrintRawCompoundStmt(Node->getBody()); 1973*0b57cec5SDimitry Andric } 1974*0b57cec5SDimitry Andric 1975*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) { 1976*0b57cec5SDimitry Andric if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo()) 1977*0b57cec5SDimitry Andric TSInfo->getType().print(OS, Policy); 1978*0b57cec5SDimitry Andric else 1979*0b57cec5SDimitry Andric Node->getType().print(OS, Policy); 1980*0b57cec5SDimitry Andric OS << "()"; 1981*0b57cec5SDimitry Andric } 1982*0b57cec5SDimitry Andric 1983*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) { 1984*0b57cec5SDimitry Andric if (E->isGlobalNew()) 1985*0b57cec5SDimitry Andric OS << "::"; 1986*0b57cec5SDimitry Andric OS << "new "; 1987*0b57cec5SDimitry Andric unsigned NumPlace = E->getNumPlacementArgs(); 1988*0b57cec5SDimitry Andric if (NumPlace > 0 && !isa<CXXDefaultArgExpr>(E->getPlacementArg(0))) { 1989*0b57cec5SDimitry Andric OS << "("; 1990*0b57cec5SDimitry Andric PrintExpr(E->getPlacementArg(0)); 1991*0b57cec5SDimitry Andric for (unsigned i = 1; i < NumPlace; ++i) { 1992*0b57cec5SDimitry Andric if (isa<CXXDefaultArgExpr>(E->getPlacementArg(i))) 1993*0b57cec5SDimitry Andric break; 1994*0b57cec5SDimitry Andric OS << ", "; 1995*0b57cec5SDimitry Andric PrintExpr(E->getPlacementArg(i)); 1996*0b57cec5SDimitry Andric } 1997*0b57cec5SDimitry Andric OS << ") "; 1998*0b57cec5SDimitry Andric } 1999*0b57cec5SDimitry Andric if (E->isParenTypeId()) 2000*0b57cec5SDimitry Andric OS << "("; 2001*0b57cec5SDimitry Andric std::string TypeS; 2002*0b57cec5SDimitry Andric if (Optional<Expr *> Size = E->getArraySize()) { 2003*0b57cec5SDimitry Andric llvm::raw_string_ostream s(TypeS); 2004*0b57cec5SDimitry Andric s << '['; 2005*0b57cec5SDimitry Andric if (*Size) 2006*0b57cec5SDimitry Andric (*Size)->printPretty(s, Helper, Policy); 2007*0b57cec5SDimitry Andric s << ']'; 2008*0b57cec5SDimitry Andric } 2009*0b57cec5SDimitry Andric E->getAllocatedType().print(OS, Policy, TypeS); 2010*0b57cec5SDimitry Andric if (E->isParenTypeId()) 2011*0b57cec5SDimitry Andric OS << ")"; 2012*0b57cec5SDimitry Andric 2013*0b57cec5SDimitry Andric CXXNewExpr::InitializationStyle InitStyle = E->getInitializationStyle(); 2014*0b57cec5SDimitry Andric if (InitStyle) { 2015*0b57cec5SDimitry Andric if (InitStyle == CXXNewExpr::CallInit) 2016*0b57cec5SDimitry Andric OS << "("; 2017*0b57cec5SDimitry Andric PrintExpr(E->getInitializer()); 2018*0b57cec5SDimitry Andric if (InitStyle == CXXNewExpr::CallInit) 2019*0b57cec5SDimitry Andric OS << ")"; 2020*0b57cec5SDimitry Andric } 2021*0b57cec5SDimitry Andric } 2022*0b57cec5SDimitry Andric 2023*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) { 2024*0b57cec5SDimitry Andric if (E->isGlobalDelete()) 2025*0b57cec5SDimitry Andric OS << "::"; 2026*0b57cec5SDimitry Andric OS << "delete "; 2027*0b57cec5SDimitry Andric if (E->isArrayForm()) 2028*0b57cec5SDimitry Andric OS << "[] "; 2029*0b57cec5SDimitry Andric PrintExpr(E->getArgument()); 2030*0b57cec5SDimitry Andric } 2031*0b57cec5SDimitry Andric 2032*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) { 2033*0b57cec5SDimitry Andric PrintExpr(E->getBase()); 2034*0b57cec5SDimitry Andric if (E->isArrow()) 2035*0b57cec5SDimitry Andric OS << "->"; 2036*0b57cec5SDimitry Andric else 2037*0b57cec5SDimitry Andric OS << '.'; 2038*0b57cec5SDimitry Andric if (E->getQualifier()) 2039*0b57cec5SDimitry Andric E->getQualifier()->print(OS, Policy); 2040*0b57cec5SDimitry Andric OS << "~"; 2041*0b57cec5SDimitry Andric 2042*0b57cec5SDimitry Andric if (IdentifierInfo *II = E->getDestroyedTypeIdentifier()) 2043*0b57cec5SDimitry Andric OS << II->getName(); 2044*0b57cec5SDimitry Andric else 2045*0b57cec5SDimitry Andric E->getDestroyedType().print(OS, Policy); 2046*0b57cec5SDimitry Andric } 2047*0b57cec5SDimitry Andric 2048*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) { 2049*0b57cec5SDimitry Andric if (E->isListInitialization() && !E->isStdInitListInitialization()) 2050*0b57cec5SDimitry Andric OS << "{"; 2051*0b57cec5SDimitry Andric 2052*0b57cec5SDimitry Andric for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { 2053*0b57cec5SDimitry Andric if (isa<CXXDefaultArgExpr>(E->getArg(i))) { 2054*0b57cec5SDimitry Andric // Don't print any defaulted arguments 2055*0b57cec5SDimitry Andric break; 2056*0b57cec5SDimitry Andric } 2057*0b57cec5SDimitry Andric 2058*0b57cec5SDimitry Andric if (i) OS << ", "; 2059*0b57cec5SDimitry Andric PrintExpr(E->getArg(i)); 2060*0b57cec5SDimitry Andric } 2061*0b57cec5SDimitry Andric 2062*0b57cec5SDimitry Andric if (E->isListInitialization() && !E->isStdInitListInitialization()) 2063*0b57cec5SDimitry Andric OS << "}"; 2064*0b57cec5SDimitry Andric } 2065*0b57cec5SDimitry Andric 2066*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) { 2067*0b57cec5SDimitry Andric // Parens are printed by the surrounding context. 2068*0b57cec5SDimitry Andric OS << "<forwarded>"; 2069*0b57cec5SDimitry Andric } 2070*0b57cec5SDimitry Andric 2071*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) { 2072*0b57cec5SDimitry Andric PrintExpr(E->getSubExpr()); 2073*0b57cec5SDimitry Andric } 2074*0b57cec5SDimitry Andric 2075*0b57cec5SDimitry Andric void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) { 2076*0b57cec5SDimitry Andric // Just forward to the subexpression. 2077*0b57cec5SDimitry Andric PrintExpr(E->getSubExpr()); 2078*0b57cec5SDimitry Andric } 2079*0b57cec5SDimitry Andric 2080*0b57cec5SDimitry Andric void 2081*0b57cec5SDimitry Andric StmtPrinter::VisitCXXUnresolvedConstructExpr( 2082*0b57cec5SDimitry Andric CXXUnresolvedConstructExpr *Node) { 2083*0b57cec5SDimitry Andric Node->getTypeAsWritten().print(OS, Policy); 2084*0b57cec5SDimitry Andric OS << "("; 2085*0b57cec5SDimitry Andric for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(), 2086*0b57cec5SDimitry Andric ArgEnd = Node->arg_end(); 2087*0b57cec5SDimitry Andric Arg != ArgEnd; ++Arg) { 2088*0b57cec5SDimitry Andric if (Arg != Node->arg_begin()) 2089*0b57cec5SDimitry Andric OS << ", "; 2090*0b57cec5SDimitry Andric PrintExpr(*Arg); 2091*0b57cec5SDimitry Andric } 2092*0b57cec5SDimitry Andric OS << ")"; 2093*0b57cec5SDimitry Andric } 2094*0b57cec5SDimitry Andric 2095*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXDependentScopeMemberExpr( 2096*0b57cec5SDimitry Andric CXXDependentScopeMemberExpr *Node) { 2097*0b57cec5SDimitry Andric if (!Node->isImplicitAccess()) { 2098*0b57cec5SDimitry Andric PrintExpr(Node->getBase()); 2099*0b57cec5SDimitry Andric OS << (Node->isArrow() ? "->" : "."); 2100*0b57cec5SDimitry Andric } 2101*0b57cec5SDimitry Andric if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 2102*0b57cec5SDimitry Andric Qualifier->print(OS, Policy); 2103*0b57cec5SDimitry Andric if (Node->hasTemplateKeyword()) 2104*0b57cec5SDimitry Andric OS << "template "; 2105*0b57cec5SDimitry Andric OS << Node->getMemberNameInfo(); 2106*0b57cec5SDimitry Andric if (Node->hasExplicitTemplateArgs()) 2107*0b57cec5SDimitry Andric printTemplateArgumentList(OS, Node->template_arguments(), Policy); 2108*0b57cec5SDimitry Andric } 2109*0b57cec5SDimitry Andric 2110*0b57cec5SDimitry Andric void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) { 2111*0b57cec5SDimitry Andric if (!Node->isImplicitAccess()) { 2112*0b57cec5SDimitry Andric PrintExpr(Node->getBase()); 2113*0b57cec5SDimitry Andric OS << (Node->isArrow() ? "->" : "."); 2114*0b57cec5SDimitry Andric } 2115*0b57cec5SDimitry Andric if (NestedNameSpecifier *Qualifier = Node->getQualifier()) 2116*0b57cec5SDimitry Andric Qualifier->print(OS, Policy); 2117*0b57cec5SDimitry Andric if (Node->hasTemplateKeyword()) 2118*0b57cec5SDimitry Andric OS << "template "; 2119*0b57cec5SDimitry Andric OS << Node->getMemberNameInfo(); 2120*0b57cec5SDimitry Andric if (Node->hasExplicitTemplateArgs()) 2121*0b57cec5SDimitry Andric printTemplateArgumentList(OS, Node->template_arguments(), Policy); 2122*0b57cec5SDimitry Andric } 2123*0b57cec5SDimitry Andric 2124*0b57cec5SDimitry Andric static const char *getTypeTraitName(TypeTrait TT) { 2125*0b57cec5SDimitry Andric switch (TT) { 2126*0b57cec5SDimitry Andric #define TYPE_TRAIT_1(Spelling, Name, Key) \ 2127*0b57cec5SDimitry Andric case clang::UTT_##Name: return #Spelling; 2128*0b57cec5SDimitry Andric #define TYPE_TRAIT_2(Spelling, Name, Key) \ 2129*0b57cec5SDimitry Andric case clang::BTT_##Name: return #Spelling; 2130*0b57cec5SDimitry Andric #define TYPE_TRAIT_N(Spelling, Name, Key) \ 2131*0b57cec5SDimitry Andric case clang::TT_##Name: return #Spelling; 2132*0b57cec5SDimitry Andric #include "clang/Basic/TokenKinds.def" 2133*0b57cec5SDimitry Andric } 2134*0b57cec5SDimitry Andric llvm_unreachable("Type trait not covered by switch"); 2135*0b57cec5SDimitry Andric } 2136*0b57cec5SDimitry Andric 2137*0b57cec5SDimitry Andric static const char *getTypeTraitName(ArrayTypeTrait ATT) { 2138*0b57cec5SDimitry Andric switch (ATT) { 2139*0b57cec5SDimitry Andric case ATT_ArrayRank: return "__array_rank"; 2140*0b57cec5SDimitry Andric case ATT_ArrayExtent: return "__array_extent"; 2141*0b57cec5SDimitry Andric } 2142*0b57cec5SDimitry Andric llvm_unreachable("Array type trait not covered by switch"); 2143*0b57cec5SDimitry Andric } 2144*0b57cec5SDimitry Andric 2145*0b57cec5SDimitry Andric static const char *getExpressionTraitName(ExpressionTrait ET) { 2146*0b57cec5SDimitry Andric switch (ET) { 2147*0b57cec5SDimitry Andric case ET_IsLValueExpr: return "__is_lvalue_expr"; 2148*0b57cec5SDimitry Andric case ET_IsRValueExpr: return "__is_rvalue_expr"; 2149*0b57cec5SDimitry Andric } 2150*0b57cec5SDimitry Andric llvm_unreachable("Expression type trait not covered by switch"); 2151*0b57cec5SDimitry Andric } 2152*0b57cec5SDimitry Andric 2153*0b57cec5SDimitry Andric void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) { 2154*0b57cec5SDimitry Andric OS << getTypeTraitName(E->getTrait()) << "("; 2155*0b57cec5SDimitry Andric for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) { 2156*0b57cec5SDimitry Andric if (I > 0) 2157*0b57cec5SDimitry Andric OS << ", "; 2158*0b57cec5SDimitry Andric E->getArg(I)->getType().print(OS, Policy); 2159*0b57cec5SDimitry Andric } 2160*0b57cec5SDimitry Andric OS << ")"; 2161*0b57cec5SDimitry Andric } 2162*0b57cec5SDimitry Andric 2163*0b57cec5SDimitry Andric void StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) { 2164*0b57cec5SDimitry Andric OS << getTypeTraitName(E->getTrait()) << '('; 2165*0b57cec5SDimitry Andric E->getQueriedType().print(OS, Policy); 2166*0b57cec5SDimitry Andric OS << ')'; 2167*0b57cec5SDimitry Andric } 2168*0b57cec5SDimitry Andric 2169*0b57cec5SDimitry Andric void StmtPrinter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) { 2170*0b57cec5SDimitry Andric OS << getExpressionTraitName(E->getTrait()) << '('; 2171*0b57cec5SDimitry Andric PrintExpr(E->getQueriedExpression()); 2172*0b57cec5SDimitry Andric OS << ')'; 2173*0b57cec5SDimitry Andric } 2174*0b57cec5SDimitry Andric 2175*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { 2176*0b57cec5SDimitry Andric OS << "noexcept("; 2177*0b57cec5SDimitry Andric PrintExpr(E->getOperand()); 2178*0b57cec5SDimitry Andric OS << ")"; 2179*0b57cec5SDimitry Andric } 2180*0b57cec5SDimitry Andric 2181*0b57cec5SDimitry Andric void StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) { 2182*0b57cec5SDimitry Andric PrintExpr(E->getPattern()); 2183*0b57cec5SDimitry Andric OS << "..."; 2184*0b57cec5SDimitry Andric } 2185*0b57cec5SDimitry Andric 2186*0b57cec5SDimitry Andric void StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) { 2187*0b57cec5SDimitry Andric OS << "sizeof...(" << *E->getPack() << ")"; 2188*0b57cec5SDimitry Andric } 2189*0b57cec5SDimitry Andric 2190*0b57cec5SDimitry Andric void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr( 2191*0b57cec5SDimitry Andric SubstNonTypeTemplateParmPackExpr *Node) { 2192*0b57cec5SDimitry Andric OS << *Node->getParameterPack(); 2193*0b57cec5SDimitry Andric } 2194*0b57cec5SDimitry Andric 2195*0b57cec5SDimitry Andric void StmtPrinter::VisitSubstNonTypeTemplateParmExpr( 2196*0b57cec5SDimitry Andric SubstNonTypeTemplateParmExpr *Node) { 2197*0b57cec5SDimitry Andric Visit(Node->getReplacement()); 2198*0b57cec5SDimitry Andric } 2199*0b57cec5SDimitry Andric 2200*0b57cec5SDimitry Andric void StmtPrinter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) { 2201*0b57cec5SDimitry Andric OS << *E->getParameterPack(); 2202*0b57cec5SDimitry Andric } 2203*0b57cec5SDimitry Andric 2204*0b57cec5SDimitry Andric void StmtPrinter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *Node){ 2205*0b57cec5SDimitry Andric PrintExpr(Node->GetTemporaryExpr()); 2206*0b57cec5SDimitry Andric } 2207*0b57cec5SDimitry Andric 2208*0b57cec5SDimitry Andric void StmtPrinter::VisitCXXFoldExpr(CXXFoldExpr *E) { 2209*0b57cec5SDimitry Andric OS << "("; 2210*0b57cec5SDimitry Andric if (E->getLHS()) { 2211*0b57cec5SDimitry Andric PrintExpr(E->getLHS()); 2212*0b57cec5SDimitry Andric OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " "; 2213*0b57cec5SDimitry Andric } 2214*0b57cec5SDimitry Andric OS << "..."; 2215*0b57cec5SDimitry Andric if (E->getRHS()) { 2216*0b57cec5SDimitry Andric OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " "; 2217*0b57cec5SDimitry Andric PrintExpr(E->getRHS()); 2218*0b57cec5SDimitry Andric } 2219*0b57cec5SDimitry Andric OS << ")"; 2220*0b57cec5SDimitry Andric } 2221*0b57cec5SDimitry Andric 2222*0b57cec5SDimitry Andric // C++ Coroutines TS 2223*0b57cec5SDimitry Andric 2224*0b57cec5SDimitry Andric void StmtPrinter::VisitCoroutineBodyStmt(CoroutineBodyStmt *S) { 2225*0b57cec5SDimitry Andric Visit(S->getBody()); 2226*0b57cec5SDimitry Andric } 2227*0b57cec5SDimitry Andric 2228*0b57cec5SDimitry Andric void StmtPrinter::VisitCoreturnStmt(CoreturnStmt *S) { 2229*0b57cec5SDimitry Andric OS << "co_return"; 2230*0b57cec5SDimitry Andric if (S->getOperand()) { 2231*0b57cec5SDimitry Andric OS << " "; 2232*0b57cec5SDimitry Andric Visit(S->getOperand()); 2233*0b57cec5SDimitry Andric } 2234*0b57cec5SDimitry Andric OS << ";"; 2235*0b57cec5SDimitry Andric } 2236*0b57cec5SDimitry Andric 2237*0b57cec5SDimitry Andric void StmtPrinter::VisitCoawaitExpr(CoawaitExpr *S) { 2238*0b57cec5SDimitry Andric OS << "co_await "; 2239*0b57cec5SDimitry Andric PrintExpr(S->getOperand()); 2240*0b57cec5SDimitry Andric } 2241*0b57cec5SDimitry Andric 2242*0b57cec5SDimitry Andric void StmtPrinter::VisitDependentCoawaitExpr(DependentCoawaitExpr *S) { 2243*0b57cec5SDimitry Andric OS << "co_await "; 2244*0b57cec5SDimitry Andric PrintExpr(S->getOperand()); 2245*0b57cec5SDimitry Andric } 2246*0b57cec5SDimitry Andric 2247*0b57cec5SDimitry Andric void StmtPrinter::VisitCoyieldExpr(CoyieldExpr *S) { 2248*0b57cec5SDimitry Andric OS << "co_yield "; 2249*0b57cec5SDimitry Andric PrintExpr(S->getOperand()); 2250*0b57cec5SDimitry Andric } 2251*0b57cec5SDimitry Andric 2252*0b57cec5SDimitry Andric // Obj-C 2253*0b57cec5SDimitry Andric 2254*0b57cec5SDimitry Andric void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) { 2255*0b57cec5SDimitry Andric OS << "@"; 2256*0b57cec5SDimitry Andric VisitStringLiteral(Node->getString()); 2257*0b57cec5SDimitry Andric } 2258*0b57cec5SDimitry Andric 2259*0b57cec5SDimitry Andric void StmtPrinter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) { 2260*0b57cec5SDimitry Andric OS << "@"; 2261*0b57cec5SDimitry Andric Visit(E->getSubExpr()); 2262*0b57cec5SDimitry Andric } 2263*0b57cec5SDimitry Andric 2264*0b57cec5SDimitry Andric void StmtPrinter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) { 2265*0b57cec5SDimitry Andric OS << "@[ "; 2266*0b57cec5SDimitry Andric ObjCArrayLiteral::child_range Ch = E->children(); 2267*0b57cec5SDimitry Andric for (auto I = Ch.begin(), E = Ch.end(); I != E; ++I) { 2268*0b57cec5SDimitry Andric if (I != Ch.begin()) 2269*0b57cec5SDimitry Andric OS << ", "; 2270*0b57cec5SDimitry Andric Visit(*I); 2271*0b57cec5SDimitry Andric } 2272*0b57cec5SDimitry Andric OS << " ]"; 2273*0b57cec5SDimitry Andric } 2274*0b57cec5SDimitry Andric 2275*0b57cec5SDimitry Andric void StmtPrinter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) { 2276*0b57cec5SDimitry Andric OS << "@{ "; 2277*0b57cec5SDimitry Andric for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) { 2278*0b57cec5SDimitry Andric if (I > 0) 2279*0b57cec5SDimitry Andric OS << ", "; 2280*0b57cec5SDimitry Andric 2281*0b57cec5SDimitry Andric ObjCDictionaryElement Element = E->getKeyValueElement(I); 2282*0b57cec5SDimitry Andric Visit(Element.Key); 2283*0b57cec5SDimitry Andric OS << " : "; 2284*0b57cec5SDimitry Andric Visit(Element.Value); 2285*0b57cec5SDimitry Andric if (Element.isPackExpansion()) 2286*0b57cec5SDimitry Andric OS << "..."; 2287*0b57cec5SDimitry Andric } 2288*0b57cec5SDimitry Andric OS << " }"; 2289*0b57cec5SDimitry Andric } 2290*0b57cec5SDimitry Andric 2291*0b57cec5SDimitry Andric void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) { 2292*0b57cec5SDimitry Andric OS << "@encode("; 2293*0b57cec5SDimitry Andric Node->getEncodedType().print(OS, Policy); 2294*0b57cec5SDimitry Andric OS << ')'; 2295*0b57cec5SDimitry Andric } 2296*0b57cec5SDimitry Andric 2297*0b57cec5SDimitry Andric void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) { 2298*0b57cec5SDimitry Andric OS << "@selector("; 2299*0b57cec5SDimitry Andric Node->getSelector().print(OS); 2300*0b57cec5SDimitry Andric OS << ')'; 2301*0b57cec5SDimitry Andric } 2302*0b57cec5SDimitry Andric 2303*0b57cec5SDimitry Andric void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) { 2304*0b57cec5SDimitry Andric OS << "@protocol(" << *Node->getProtocol() << ')'; 2305*0b57cec5SDimitry Andric } 2306*0b57cec5SDimitry Andric 2307*0b57cec5SDimitry Andric void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) { 2308*0b57cec5SDimitry Andric OS << "["; 2309*0b57cec5SDimitry Andric switch (Mess->getReceiverKind()) { 2310*0b57cec5SDimitry Andric case ObjCMessageExpr::Instance: 2311*0b57cec5SDimitry Andric PrintExpr(Mess->getInstanceReceiver()); 2312*0b57cec5SDimitry Andric break; 2313*0b57cec5SDimitry Andric 2314*0b57cec5SDimitry Andric case ObjCMessageExpr::Class: 2315*0b57cec5SDimitry Andric Mess->getClassReceiver().print(OS, Policy); 2316*0b57cec5SDimitry Andric break; 2317*0b57cec5SDimitry Andric 2318*0b57cec5SDimitry Andric case ObjCMessageExpr::SuperInstance: 2319*0b57cec5SDimitry Andric case ObjCMessageExpr::SuperClass: 2320*0b57cec5SDimitry Andric OS << "Super"; 2321*0b57cec5SDimitry Andric break; 2322*0b57cec5SDimitry Andric } 2323*0b57cec5SDimitry Andric 2324*0b57cec5SDimitry Andric OS << ' '; 2325*0b57cec5SDimitry Andric Selector selector = Mess->getSelector(); 2326*0b57cec5SDimitry Andric if (selector.isUnarySelector()) { 2327*0b57cec5SDimitry Andric OS << selector.getNameForSlot(0); 2328*0b57cec5SDimitry Andric } else { 2329*0b57cec5SDimitry Andric for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) { 2330*0b57cec5SDimitry Andric if (i < selector.getNumArgs()) { 2331*0b57cec5SDimitry Andric if (i > 0) OS << ' '; 2332*0b57cec5SDimitry Andric if (selector.getIdentifierInfoForSlot(i)) 2333*0b57cec5SDimitry Andric OS << selector.getIdentifierInfoForSlot(i)->getName() << ':'; 2334*0b57cec5SDimitry Andric else 2335*0b57cec5SDimitry Andric OS << ":"; 2336*0b57cec5SDimitry Andric } 2337*0b57cec5SDimitry Andric else OS << ", "; // Handle variadic methods. 2338*0b57cec5SDimitry Andric 2339*0b57cec5SDimitry Andric PrintExpr(Mess->getArg(i)); 2340*0b57cec5SDimitry Andric } 2341*0b57cec5SDimitry Andric } 2342*0b57cec5SDimitry Andric OS << "]"; 2343*0b57cec5SDimitry Andric } 2344*0b57cec5SDimitry Andric 2345*0b57cec5SDimitry Andric void StmtPrinter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) { 2346*0b57cec5SDimitry Andric OS << (Node->getValue() ? "__objc_yes" : "__objc_no"); 2347*0b57cec5SDimitry Andric } 2348*0b57cec5SDimitry Andric 2349*0b57cec5SDimitry Andric void 2350*0b57cec5SDimitry Andric StmtPrinter::VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) { 2351*0b57cec5SDimitry Andric PrintExpr(E->getSubExpr()); 2352*0b57cec5SDimitry Andric } 2353*0b57cec5SDimitry Andric 2354*0b57cec5SDimitry Andric void 2355*0b57cec5SDimitry Andric StmtPrinter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) { 2356*0b57cec5SDimitry Andric OS << '(' << E->getBridgeKindName(); 2357*0b57cec5SDimitry Andric E->getType().print(OS, Policy); 2358*0b57cec5SDimitry Andric OS << ')'; 2359*0b57cec5SDimitry Andric PrintExpr(E->getSubExpr()); 2360*0b57cec5SDimitry Andric } 2361*0b57cec5SDimitry Andric 2362*0b57cec5SDimitry Andric void StmtPrinter::VisitBlockExpr(BlockExpr *Node) { 2363*0b57cec5SDimitry Andric BlockDecl *BD = Node->getBlockDecl(); 2364*0b57cec5SDimitry Andric OS << "^"; 2365*0b57cec5SDimitry Andric 2366*0b57cec5SDimitry Andric const FunctionType *AFT = Node->getFunctionType(); 2367*0b57cec5SDimitry Andric 2368*0b57cec5SDimitry Andric if (isa<FunctionNoProtoType>(AFT)) { 2369*0b57cec5SDimitry Andric OS << "()"; 2370*0b57cec5SDimitry Andric } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) { 2371*0b57cec5SDimitry Andric OS << '('; 2372*0b57cec5SDimitry Andric for (BlockDecl::param_iterator AI = BD->param_begin(), 2373*0b57cec5SDimitry Andric E = BD->param_end(); AI != E; ++AI) { 2374*0b57cec5SDimitry Andric if (AI != BD->param_begin()) OS << ", "; 2375*0b57cec5SDimitry Andric std::string ParamStr = (*AI)->getNameAsString(); 2376*0b57cec5SDimitry Andric (*AI)->getType().print(OS, Policy, ParamStr); 2377*0b57cec5SDimitry Andric } 2378*0b57cec5SDimitry Andric 2379*0b57cec5SDimitry Andric const auto *FT = cast<FunctionProtoType>(AFT); 2380*0b57cec5SDimitry Andric if (FT->isVariadic()) { 2381*0b57cec5SDimitry Andric if (!BD->param_empty()) OS << ", "; 2382*0b57cec5SDimitry Andric OS << "..."; 2383*0b57cec5SDimitry Andric } 2384*0b57cec5SDimitry Andric OS << ')'; 2385*0b57cec5SDimitry Andric } 2386*0b57cec5SDimitry Andric OS << "{ }"; 2387*0b57cec5SDimitry Andric } 2388*0b57cec5SDimitry Andric 2389*0b57cec5SDimitry Andric void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) { 2390*0b57cec5SDimitry Andric PrintExpr(Node->getSourceExpr()); 2391*0b57cec5SDimitry Andric } 2392*0b57cec5SDimitry Andric 2393*0b57cec5SDimitry Andric void StmtPrinter::VisitTypoExpr(TypoExpr *Node) { 2394*0b57cec5SDimitry Andric // TODO: Print something reasonable for a TypoExpr, if necessary. 2395*0b57cec5SDimitry Andric llvm_unreachable("Cannot print TypoExpr nodes"); 2396*0b57cec5SDimitry Andric } 2397*0b57cec5SDimitry Andric 2398*0b57cec5SDimitry Andric void StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) { 2399*0b57cec5SDimitry Andric OS << "__builtin_astype("; 2400*0b57cec5SDimitry Andric PrintExpr(Node->getSrcExpr()); 2401*0b57cec5SDimitry Andric OS << ", "; 2402*0b57cec5SDimitry Andric Node->getType().print(OS, Policy); 2403*0b57cec5SDimitry Andric OS << ")"; 2404*0b57cec5SDimitry Andric } 2405*0b57cec5SDimitry Andric 2406*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 2407*0b57cec5SDimitry Andric // Stmt method implementations 2408*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 2409*0b57cec5SDimitry Andric 2410*0b57cec5SDimitry Andric void Stmt::dumpPretty(const ASTContext &Context) const { 2411*0b57cec5SDimitry Andric printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts())); 2412*0b57cec5SDimitry Andric } 2413*0b57cec5SDimitry Andric 2414*0b57cec5SDimitry Andric void Stmt::printPretty(raw_ostream &Out, PrinterHelper *Helper, 2415*0b57cec5SDimitry Andric const PrintingPolicy &Policy, unsigned Indentation, 2416*0b57cec5SDimitry Andric StringRef NL, const ASTContext *Context) const { 2417*0b57cec5SDimitry Andric StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context); 2418*0b57cec5SDimitry Andric P.Visit(const_cast<Stmt *>(this)); 2419*0b57cec5SDimitry Andric } 2420*0b57cec5SDimitry Andric 2421*0b57cec5SDimitry Andric void Stmt::printJson(raw_ostream &Out, PrinterHelper *Helper, 2422*0b57cec5SDimitry Andric const PrintingPolicy &Policy, bool AddQuotes) const { 2423*0b57cec5SDimitry Andric std::string Buf; 2424*0b57cec5SDimitry Andric llvm::raw_string_ostream TempOut(Buf); 2425*0b57cec5SDimitry Andric 2426*0b57cec5SDimitry Andric printPretty(TempOut, Helper, Policy); 2427*0b57cec5SDimitry Andric 2428*0b57cec5SDimitry Andric Out << JsonFormat(TempOut.str(), AddQuotes); 2429*0b57cec5SDimitry Andric } 2430*0b57cec5SDimitry Andric 2431*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 2432*0b57cec5SDimitry Andric // PrinterHelper 2433*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 2434*0b57cec5SDimitry Andric 2435*0b57cec5SDimitry Andric // Implement virtual destructor. 2436*0b57cec5SDimitry Andric PrinterHelper::~PrinterHelper() = default; 2437