xref: /freebsd/contrib/llvm-project/clang/lib/AST/StmtPrinter.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
10b57cec5SDimitry Andric //===- StmtPrinter.cpp - Printing implementation for Stmt ASTs ------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the Stmt::dumpPretty/Stmt::printPretty methods, which
100b57cec5SDimitry Andric // pretty print the AST back out to C code.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
150b57cec5SDimitry Andric #include "clang/AST/Attr.h"
160b57cec5SDimitry Andric #include "clang/AST/Decl.h"
170b57cec5SDimitry Andric #include "clang/AST/DeclBase.h"
180b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h"
190b57cec5SDimitry Andric #include "clang/AST/DeclObjC.h"
200b57cec5SDimitry Andric #include "clang/AST/DeclOpenMP.h"
210b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h"
220b57cec5SDimitry Andric #include "clang/AST/Expr.h"
230b57cec5SDimitry Andric #include "clang/AST/ExprCXX.h"
240b57cec5SDimitry Andric #include "clang/AST/ExprObjC.h"
250b57cec5SDimitry Andric #include "clang/AST/ExprOpenMP.h"
260b57cec5SDimitry Andric #include "clang/AST/NestedNameSpecifier.h"
270b57cec5SDimitry Andric #include "clang/AST/OpenMPClause.h"
280b57cec5SDimitry Andric #include "clang/AST/PrettyPrinter.h"
290b57cec5SDimitry Andric #include "clang/AST/Stmt.h"
300b57cec5SDimitry Andric #include "clang/AST/StmtCXX.h"
310b57cec5SDimitry Andric #include "clang/AST/StmtObjC.h"
320b57cec5SDimitry Andric #include "clang/AST/StmtOpenMP.h"
330b57cec5SDimitry Andric #include "clang/AST/StmtVisitor.h"
340b57cec5SDimitry Andric #include "clang/AST/TemplateBase.h"
350b57cec5SDimitry Andric #include "clang/AST/Type.h"
360b57cec5SDimitry Andric #include "clang/Basic/CharInfo.h"
370b57cec5SDimitry Andric #include "clang/Basic/ExpressionTraits.h"
380b57cec5SDimitry Andric #include "clang/Basic/IdentifierTable.h"
390b57cec5SDimitry Andric #include "clang/Basic/JsonSupport.h"
400b57cec5SDimitry Andric #include "clang/Basic/LLVM.h"
410b57cec5SDimitry Andric #include "clang/Basic/Lambda.h"
420b57cec5SDimitry Andric #include "clang/Basic/OpenMPKinds.h"
430b57cec5SDimitry Andric #include "clang/Basic/OperatorKinds.h"
440b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h"
450b57cec5SDimitry Andric #include "clang/Basic/TypeTraits.h"
460b57cec5SDimitry Andric #include "clang/Lex/Lexer.h"
470b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
480b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
490b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
50fe6060f1SDimitry Andric #include "llvm/ADT/StringExtras.h"
510b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
520b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
530b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
540b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
550b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
560b57cec5SDimitry Andric #include <cassert>
57bdd1243dSDimitry Andric #include <optional>
580b57cec5SDimitry Andric #include <string>
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric using namespace clang;
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
630b57cec5SDimitry Andric // StmtPrinter Visitor
640b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric namespace {
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric   class StmtPrinter : public StmtVisitor<StmtPrinter> {
690b57cec5SDimitry Andric     raw_ostream &OS;
700b57cec5SDimitry Andric     unsigned IndentLevel;
710b57cec5SDimitry Andric     PrinterHelper* Helper;
720b57cec5SDimitry Andric     PrintingPolicy Policy;
730b57cec5SDimitry Andric     std::string NL;
740b57cec5SDimitry Andric     const ASTContext *Context;
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric   public:
770b57cec5SDimitry Andric     StmtPrinter(raw_ostream &os, PrinterHelper *helper,
780b57cec5SDimitry Andric                 const PrintingPolicy &Policy, unsigned Indentation = 0,
795ffd83dbSDimitry Andric                 StringRef NL = "\n", const ASTContext *Context = nullptr)
800b57cec5SDimitry Andric         : OS(os), IndentLevel(Indentation), Helper(helper), Policy(Policy),
810b57cec5SDimitry Andric           NL(NL), Context(Context) {}
820b57cec5SDimitry Andric 
835ffd83dbSDimitry Andric     void PrintStmt(Stmt *S) { PrintStmt(S, Policy.Indentation); }
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric     void PrintStmt(Stmt *S, int SubIndent) {
860b57cec5SDimitry Andric       IndentLevel += SubIndent;
870b57cec5SDimitry Andric       if (S && isa<Expr>(S)) {
880b57cec5SDimitry Andric         // If this is an expr used in a stmt context, indent and newline it.
890b57cec5SDimitry Andric         Indent();
900b57cec5SDimitry Andric         Visit(S);
910b57cec5SDimitry Andric         OS << ";" << NL;
920b57cec5SDimitry Andric       } else if (S) {
930b57cec5SDimitry Andric         Visit(S);
940b57cec5SDimitry Andric       } else {
950b57cec5SDimitry Andric         Indent() << "<<<NULL STATEMENT>>>" << NL;
960b57cec5SDimitry Andric       }
970b57cec5SDimitry Andric       IndentLevel -= SubIndent;
980b57cec5SDimitry Andric     }
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric     void PrintInitStmt(Stmt *S, unsigned PrefixWidth) {
1010b57cec5SDimitry Andric       // FIXME: Cope better with odd prefix widths.
1020b57cec5SDimitry Andric       IndentLevel += (PrefixWidth + 1) / 2;
1030b57cec5SDimitry Andric       if (auto *DS = dyn_cast<DeclStmt>(S))
1040b57cec5SDimitry Andric         PrintRawDeclStmt(DS);
1050b57cec5SDimitry Andric       else
1060b57cec5SDimitry Andric         PrintExpr(cast<Expr>(S));
1070b57cec5SDimitry Andric       OS << "; ";
1080b57cec5SDimitry Andric       IndentLevel -= (PrefixWidth + 1) / 2;
1090b57cec5SDimitry Andric     }
1100b57cec5SDimitry Andric 
1110b57cec5SDimitry Andric     void PrintControlledStmt(Stmt *S) {
1120b57cec5SDimitry Andric       if (auto *CS = dyn_cast<CompoundStmt>(S)) {
1130b57cec5SDimitry Andric         OS << " ";
1140b57cec5SDimitry Andric         PrintRawCompoundStmt(CS);
1150b57cec5SDimitry Andric         OS << NL;
1160b57cec5SDimitry Andric       } else {
1170b57cec5SDimitry Andric         OS << NL;
1180b57cec5SDimitry Andric         PrintStmt(S);
1190b57cec5SDimitry Andric       }
1200b57cec5SDimitry Andric     }
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric     void PrintRawCompoundStmt(CompoundStmt *S);
1230b57cec5SDimitry Andric     void PrintRawDecl(Decl *D);
1240b57cec5SDimitry Andric     void PrintRawDeclStmt(const DeclStmt *S);
1250b57cec5SDimitry Andric     void PrintRawIfStmt(IfStmt *If);
1260b57cec5SDimitry Andric     void PrintRawCXXCatchStmt(CXXCatchStmt *Catch);
1270b57cec5SDimitry Andric     void PrintCallArgs(CallExpr *E);
1280b57cec5SDimitry Andric     void PrintRawSEHExceptHandler(SEHExceptStmt *S);
1290b57cec5SDimitry Andric     void PrintRawSEHFinallyStmt(SEHFinallyStmt *S);
1300b57cec5SDimitry Andric     void PrintOMPExecutableDirective(OMPExecutableDirective *S,
1310b57cec5SDimitry Andric                                      bool ForceNoStmt = false);
13281ad6265SDimitry Andric     void PrintFPPragmas(CompoundStmt *S);
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric     void PrintExpr(Expr *E) {
1350b57cec5SDimitry Andric       if (E)
1360b57cec5SDimitry Andric         Visit(E);
1370b57cec5SDimitry Andric       else
1380b57cec5SDimitry Andric         OS << "<null expr>";
1390b57cec5SDimitry Andric     }
1400b57cec5SDimitry Andric 
1410b57cec5SDimitry Andric     raw_ostream &Indent(int Delta = 0) {
1420b57cec5SDimitry Andric       for (int i = 0, e = IndentLevel+Delta; i < e; ++i)
1430b57cec5SDimitry Andric         OS << "  ";
1440b57cec5SDimitry Andric       return OS;
1450b57cec5SDimitry Andric     }
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric     void Visit(Stmt* S) {
1480b57cec5SDimitry Andric       if (Helper && Helper->handledStmt(S,OS))
1490b57cec5SDimitry Andric           return;
1500b57cec5SDimitry Andric       else StmtVisitor<StmtPrinter>::Visit(S);
1510b57cec5SDimitry Andric     }
1520b57cec5SDimitry Andric 
1530b57cec5SDimitry Andric     void VisitStmt(Stmt *Node) LLVM_ATTRIBUTE_UNUSED {
1540b57cec5SDimitry Andric       Indent() << "<<unknown stmt type>>" << NL;
1550b57cec5SDimitry Andric     }
1560b57cec5SDimitry Andric 
1570b57cec5SDimitry Andric     void VisitExpr(Expr *Node) LLVM_ATTRIBUTE_UNUSED {
1580b57cec5SDimitry Andric       OS << "<<unknown expr type>>";
1590b57cec5SDimitry Andric     }
1600b57cec5SDimitry Andric 
1610b57cec5SDimitry Andric     void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node);
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric #define ABSTRACT_STMT(CLASS)
1640b57cec5SDimitry Andric #define STMT(CLASS, PARENT) \
1650b57cec5SDimitry Andric     void Visit##CLASS(CLASS *Node);
1660b57cec5SDimitry Andric #include "clang/AST/StmtNodes.inc"
1670b57cec5SDimitry Andric   };
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric } // namespace
1700b57cec5SDimitry Andric 
1710b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1720b57cec5SDimitry Andric //  Stmt printing methods.
1730b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric /// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and
1760b57cec5SDimitry Andric /// with no newline after the }.
1770b57cec5SDimitry Andric void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
178*5f757f3fSDimitry Andric   assert(Node && "Compound statement cannot be null");
1790b57cec5SDimitry Andric   OS << "{" << NL;
18081ad6265SDimitry Andric   PrintFPPragmas(Node);
1810b57cec5SDimitry Andric   for (auto *I : Node->body())
1820b57cec5SDimitry Andric     PrintStmt(I);
1830b57cec5SDimitry Andric 
1840b57cec5SDimitry Andric   Indent() << "}";
1850b57cec5SDimitry Andric }
1860b57cec5SDimitry Andric 
18781ad6265SDimitry Andric void StmtPrinter::PrintFPPragmas(CompoundStmt *S) {
18881ad6265SDimitry Andric   if (!S->hasStoredFPFeatures())
18981ad6265SDimitry Andric     return;
19081ad6265SDimitry Andric   FPOptionsOverride FPO = S->getStoredFPFeatures();
19181ad6265SDimitry Andric   bool FEnvAccess = false;
19281ad6265SDimitry Andric   if (FPO.hasAllowFEnvAccessOverride()) {
19381ad6265SDimitry Andric     FEnvAccess = FPO.getAllowFEnvAccessOverride();
19481ad6265SDimitry Andric     Indent() << "#pragma STDC FENV_ACCESS " << (FEnvAccess ? "ON" : "OFF")
19581ad6265SDimitry Andric              << NL;
19681ad6265SDimitry Andric   }
19781ad6265SDimitry Andric   if (FPO.hasSpecifiedExceptionModeOverride()) {
19881ad6265SDimitry Andric     LangOptions::FPExceptionModeKind EM =
19981ad6265SDimitry Andric         FPO.getSpecifiedExceptionModeOverride();
20081ad6265SDimitry Andric     if (!FEnvAccess || EM != LangOptions::FPE_Strict) {
20181ad6265SDimitry Andric       Indent() << "#pragma clang fp exceptions(";
20281ad6265SDimitry Andric       switch (FPO.getSpecifiedExceptionModeOverride()) {
20381ad6265SDimitry Andric       default:
20481ad6265SDimitry Andric         break;
20581ad6265SDimitry Andric       case LangOptions::FPE_Ignore:
20681ad6265SDimitry Andric         OS << "ignore";
20781ad6265SDimitry Andric         break;
20881ad6265SDimitry Andric       case LangOptions::FPE_MayTrap:
20981ad6265SDimitry Andric         OS << "maytrap";
21081ad6265SDimitry Andric         break;
21181ad6265SDimitry Andric       case LangOptions::FPE_Strict:
21281ad6265SDimitry Andric         OS << "strict";
21381ad6265SDimitry Andric         break;
21481ad6265SDimitry Andric       }
21581ad6265SDimitry Andric       OS << ")\n";
21681ad6265SDimitry Andric     }
21781ad6265SDimitry Andric   }
21881ad6265SDimitry Andric   if (FPO.hasConstRoundingModeOverride()) {
21981ad6265SDimitry Andric     LangOptions::RoundingMode RM = FPO.getConstRoundingModeOverride();
22081ad6265SDimitry Andric     Indent() << "#pragma STDC FENV_ROUND ";
22181ad6265SDimitry Andric     switch (RM) {
22281ad6265SDimitry Andric     case llvm::RoundingMode::TowardZero:
22381ad6265SDimitry Andric       OS << "FE_TOWARDZERO";
22481ad6265SDimitry Andric       break;
22581ad6265SDimitry Andric     case llvm::RoundingMode::NearestTiesToEven:
22681ad6265SDimitry Andric       OS << "FE_TONEAREST";
22781ad6265SDimitry Andric       break;
22881ad6265SDimitry Andric     case llvm::RoundingMode::TowardPositive:
22981ad6265SDimitry Andric       OS << "FE_UPWARD";
23081ad6265SDimitry Andric       break;
23181ad6265SDimitry Andric     case llvm::RoundingMode::TowardNegative:
23281ad6265SDimitry Andric       OS << "FE_DOWNWARD";
23381ad6265SDimitry Andric       break;
23481ad6265SDimitry Andric     case llvm::RoundingMode::NearestTiesToAway:
23581ad6265SDimitry Andric       OS << "FE_TONEARESTFROMZERO";
23681ad6265SDimitry Andric       break;
23781ad6265SDimitry Andric     case llvm::RoundingMode::Dynamic:
23881ad6265SDimitry Andric       OS << "FE_DYNAMIC";
23981ad6265SDimitry Andric       break;
24081ad6265SDimitry Andric     default:
24181ad6265SDimitry Andric       llvm_unreachable("Invalid rounding mode");
24281ad6265SDimitry Andric     }
24381ad6265SDimitry Andric     OS << NL;
24481ad6265SDimitry Andric   }
24581ad6265SDimitry Andric }
24681ad6265SDimitry Andric 
2470b57cec5SDimitry Andric void StmtPrinter::PrintRawDecl(Decl *D) {
2480b57cec5SDimitry Andric   D->print(OS, Policy, IndentLevel);
2490b57cec5SDimitry Andric }
2500b57cec5SDimitry Andric 
2510b57cec5SDimitry Andric void StmtPrinter::PrintRawDeclStmt(const DeclStmt *S) {
2520b57cec5SDimitry Andric   SmallVector<Decl *, 2> Decls(S->decls());
2530b57cec5SDimitry Andric   Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel);
2540b57cec5SDimitry Andric }
2550b57cec5SDimitry Andric 
2560b57cec5SDimitry Andric void StmtPrinter::VisitNullStmt(NullStmt *Node) {
2570b57cec5SDimitry Andric   Indent() << ";" << NL;
2580b57cec5SDimitry Andric }
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
2610b57cec5SDimitry Andric   Indent();
2620b57cec5SDimitry Andric   PrintRawDeclStmt(Node);
2630b57cec5SDimitry Andric   OS << ";" << NL;
2640b57cec5SDimitry Andric }
2650b57cec5SDimitry Andric 
2660b57cec5SDimitry Andric void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
2670b57cec5SDimitry Andric   Indent();
2680b57cec5SDimitry Andric   PrintRawCompoundStmt(Node);
2690b57cec5SDimitry Andric   OS << "" << NL;
2700b57cec5SDimitry Andric }
2710b57cec5SDimitry Andric 
2720b57cec5SDimitry Andric void StmtPrinter::VisitCaseStmt(CaseStmt *Node) {
2730b57cec5SDimitry Andric   Indent(-1) << "case ";
2740b57cec5SDimitry Andric   PrintExpr(Node->getLHS());
2750b57cec5SDimitry Andric   if (Node->getRHS()) {
2760b57cec5SDimitry Andric     OS << " ... ";
2770b57cec5SDimitry Andric     PrintExpr(Node->getRHS());
2780b57cec5SDimitry Andric   }
2790b57cec5SDimitry Andric   OS << ":" << NL;
2800b57cec5SDimitry Andric 
2810b57cec5SDimitry Andric   PrintStmt(Node->getSubStmt(), 0);
2820b57cec5SDimitry Andric }
2830b57cec5SDimitry Andric 
2840b57cec5SDimitry Andric void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) {
2850b57cec5SDimitry Andric   Indent(-1) << "default:" << NL;
2860b57cec5SDimitry Andric   PrintStmt(Node->getSubStmt(), 0);
2870b57cec5SDimitry Andric }
2880b57cec5SDimitry Andric 
2890b57cec5SDimitry Andric void StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
2900b57cec5SDimitry Andric   Indent(-1) << Node->getName() << ":" << NL;
2910b57cec5SDimitry Andric   PrintStmt(Node->getSubStmt(), 0);
2920b57cec5SDimitry Andric }
2930b57cec5SDimitry Andric 
2940b57cec5SDimitry Andric void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) {
2950b57cec5SDimitry Andric   for (const auto *Attr : Node->getAttrs()) {
2960b57cec5SDimitry Andric     Attr->printPretty(OS, Policy);
2970b57cec5SDimitry Andric   }
2980b57cec5SDimitry Andric 
2990b57cec5SDimitry Andric   PrintStmt(Node->getSubStmt(), 0);
3000b57cec5SDimitry Andric }
3010b57cec5SDimitry Andric 
3020b57cec5SDimitry Andric void StmtPrinter::PrintRawIfStmt(IfStmt *If) {
303349cc55cSDimitry Andric   if (If->isConsteval()) {
304349cc55cSDimitry Andric     OS << "if ";
305349cc55cSDimitry Andric     if (If->isNegatedConsteval())
306349cc55cSDimitry Andric       OS << "!";
307349cc55cSDimitry Andric     OS << "consteval";
308349cc55cSDimitry Andric     OS << NL;
309349cc55cSDimitry Andric     PrintStmt(If->getThen());
310349cc55cSDimitry Andric     if (Stmt *Else = If->getElse()) {
311349cc55cSDimitry Andric       Indent();
312349cc55cSDimitry Andric       OS << "else";
313349cc55cSDimitry Andric       PrintStmt(Else);
314349cc55cSDimitry Andric       OS << NL;
315349cc55cSDimitry Andric     }
316349cc55cSDimitry Andric     return;
317349cc55cSDimitry Andric   }
318349cc55cSDimitry Andric 
3190b57cec5SDimitry Andric   OS << "if (";
3200b57cec5SDimitry Andric   if (If->getInit())
3210b57cec5SDimitry Andric     PrintInitStmt(If->getInit(), 4);
3220b57cec5SDimitry Andric   if (const DeclStmt *DS = If->getConditionVariableDeclStmt())
3230b57cec5SDimitry Andric     PrintRawDeclStmt(DS);
3240b57cec5SDimitry Andric   else
3250b57cec5SDimitry Andric     PrintExpr(If->getCond());
3260b57cec5SDimitry Andric   OS << ')';
3270b57cec5SDimitry Andric 
3280b57cec5SDimitry Andric   if (auto *CS = dyn_cast<CompoundStmt>(If->getThen())) {
3290b57cec5SDimitry Andric     OS << ' ';
3300b57cec5SDimitry Andric     PrintRawCompoundStmt(CS);
3310b57cec5SDimitry Andric     OS << (If->getElse() ? " " : NL);
3320b57cec5SDimitry Andric   } else {
3330b57cec5SDimitry Andric     OS << NL;
3340b57cec5SDimitry Andric     PrintStmt(If->getThen());
3350b57cec5SDimitry Andric     if (If->getElse()) Indent();
3360b57cec5SDimitry Andric   }
3370b57cec5SDimitry Andric 
3380b57cec5SDimitry Andric   if (Stmt *Else = If->getElse()) {
3390b57cec5SDimitry Andric     OS << "else";
3400b57cec5SDimitry Andric 
3410b57cec5SDimitry Andric     if (auto *CS = dyn_cast<CompoundStmt>(Else)) {
3420b57cec5SDimitry Andric       OS << ' ';
3430b57cec5SDimitry Andric       PrintRawCompoundStmt(CS);
3440b57cec5SDimitry Andric       OS << NL;
3450b57cec5SDimitry Andric     } else if (auto *ElseIf = dyn_cast<IfStmt>(Else)) {
3460b57cec5SDimitry Andric       OS << ' ';
3470b57cec5SDimitry Andric       PrintRawIfStmt(ElseIf);
3480b57cec5SDimitry Andric     } else {
3490b57cec5SDimitry Andric       OS << NL;
3500b57cec5SDimitry Andric       PrintStmt(If->getElse());
3510b57cec5SDimitry Andric     }
3520b57cec5SDimitry Andric   }
3530b57cec5SDimitry Andric }
3540b57cec5SDimitry Andric 
3550b57cec5SDimitry Andric void StmtPrinter::VisitIfStmt(IfStmt *If) {
3560b57cec5SDimitry Andric   Indent();
3570b57cec5SDimitry Andric   PrintRawIfStmt(If);
3580b57cec5SDimitry Andric }
3590b57cec5SDimitry Andric 
3600b57cec5SDimitry Andric void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) {
3610b57cec5SDimitry Andric   Indent() << "switch (";
3620b57cec5SDimitry Andric   if (Node->getInit())
3630b57cec5SDimitry Andric     PrintInitStmt(Node->getInit(), 8);
3640b57cec5SDimitry Andric   if (const DeclStmt *DS = Node->getConditionVariableDeclStmt())
3650b57cec5SDimitry Andric     PrintRawDeclStmt(DS);
3660b57cec5SDimitry Andric   else
3670b57cec5SDimitry Andric     PrintExpr(Node->getCond());
3680b57cec5SDimitry Andric   OS << ")";
3690b57cec5SDimitry Andric   PrintControlledStmt(Node->getBody());
3700b57cec5SDimitry Andric }
3710b57cec5SDimitry Andric 
3720b57cec5SDimitry Andric void StmtPrinter::VisitWhileStmt(WhileStmt *Node) {
3730b57cec5SDimitry Andric   Indent() << "while (";
3740b57cec5SDimitry Andric   if (const DeclStmt *DS = Node->getConditionVariableDeclStmt())
3750b57cec5SDimitry Andric     PrintRawDeclStmt(DS);
3760b57cec5SDimitry Andric   else
3770b57cec5SDimitry Andric     PrintExpr(Node->getCond());
3780b57cec5SDimitry Andric   OS << ")" << NL;
3790b57cec5SDimitry Andric   PrintStmt(Node->getBody());
3800b57cec5SDimitry Andric }
3810b57cec5SDimitry Andric 
3820b57cec5SDimitry Andric void StmtPrinter::VisitDoStmt(DoStmt *Node) {
3830b57cec5SDimitry Andric   Indent() << "do ";
3840b57cec5SDimitry Andric   if (auto *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
3850b57cec5SDimitry Andric     PrintRawCompoundStmt(CS);
3860b57cec5SDimitry Andric     OS << " ";
3870b57cec5SDimitry Andric   } else {
3880b57cec5SDimitry Andric     OS << NL;
3890b57cec5SDimitry Andric     PrintStmt(Node->getBody());
3900b57cec5SDimitry Andric     Indent();
3910b57cec5SDimitry Andric   }
3920b57cec5SDimitry Andric 
3930b57cec5SDimitry Andric   OS << "while (";
3940b57cec5SDimitry Andric   PrintExpr(Node->getCond());
3950b57cec5SDimitry Andric   OS << ");" << NL;
3960b57cec5SDimitry Andric }
3970b57cec5SDimitry Andric 
3980b57cec5SDimitry Andric void StmtPrinter::VisitForStmt(ForStmt *Node) {
3990b57cec5SDimitry Andric   Indent() << "for (";
4000b57cec5SDimitry Andric   if (Node->getInit())
4010b57cec5SDimitry Andric     PrintInitStmt(Node->getInit(), 5);
4020b57cec5SDimitry Andric   else
4030b57cec5SDimitry Andric     OS << (Node->getCond() ? "; " : ";");
40406c3fb27SDimitry Andric   if (const DeclStmt *DS = Node->getConditionVariableDeclStmt())
40506c3fb27SDimitry Andric     PrintRawDeclStmt(DS);
40606c3fb27SDimitry Andric   else if (Node->getCond())
4070b57cec5SDimitry Andric     PrintExpr(Node->getCond());
4080b57cec5SDimitry Andric   OS << ";";
4090b57cec5SDimitry Andric   if (Node->getInc()) {
4100b57cec5SDimitry Andric     OS << " ";
4110b57cec5SDimitry Andric     PrintExpr(Node->getInc());
4120b57cec5SDimitry Andric   }
4130b57cec5SDimitry Andric   OS << ")";
4140b57cec5SDimitry Andric   PrintControlledStmt(Node->getBody());
4150b57cec5SDimitry Andric }
4160b57cec5SDimitry Andric 
4170b57cec5SDimitry Andric void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) {
4180b57cec5SDimitry Andric   Indent() << "for (";
4190b57cec5SDimitry Andric   if (auto *DS = dyn_cast<DeclStmt>(Node->getElement()))
4200b57cec5SDimitry Andric     PrintRawDeclStmt(DS);
4210b57cec5SDimitry Andric   else
4220b57cec5SDimitry Andric     PrintExpr(cast<Expr>(Node->getElement()));
4230b57cec5SDimitry Andric   OS << " in ";
4240b57cec5SDimitry Andric   PrintExpr(Node->getCollection());
4250b57cec5SDimitry Andric   OS << ")";
4260b57cec5SDimitry Andric   PrintControlledStmt(Node->getBody());
4270b57cec5SDimitry Andric }
4280b57cec5SDimitry Andric 
4290b57cec5SDimitry Andric void StmtPrinter::VisitCXXForRangeStmt(CXXForRangeStmt *Node) {
4300b57cec5SDimitry Andric   Indent() << "for (";
4310b57cec5SDimitry Andric   if (Node->getInit())
4320b57cec5SDimitry Andric     PrintInitStmt(Node->getInit(), 5);
4330b57cec5SDimitry Andric   PrintingPolicy SubPolicy(Policy);
4340b57cec5SDimitry Andric   SubPolicy.SuppressInitializers = true;
4350b57cec5SDimitry Andric   Node->getLoopVariable()->print(OS, SubPolicy, IndentLevel);
4360b57cec5SDimitry Andric   OS << " : ";
4370b57cec5SDimitry Andric   PrintExpr(Node->getRangeInit());
4380b57cec5SDimitry Andric   OS << ")";
4390b57cec5SDimitry Andric   PrintControlledStmt(Node->getBody());
4400b57cec5SDimitry Andric }
4410b57cec5SDimitry Andric 
4420b57cec5SDimitry Andric void StmtPrinter::VisitMSDependentExistsStmt(MSDependentExistsStmt *Node) {
4430b57cec5SDimitry Andric   Indent();
4440b57cec5SDimitry Andric   if (Node->isIfExists())
4450b57cec5SDimitry Andric     OS << "__if_exists (";
4460b57cec5SDimitry Andric   else
4470b57cec5SDimitry Andric     OS << "__if_not_exists (";
4480b57cec5SDimitry Andric 
4490b57cec5SDimitry Andric   if (NestedNameSpecifier *Qualifier
4500b57cec5SDimitry Andric         = Node->getQualifierLoc().getNestedNameSpecifier())
4510b57cec5SDimitry Andric     Qualifier->print(OS, Policy);
4520b57cec5SDimitry Andric 
4530b57cec5SDimitry Andric   OS << Node->getNameInfo() << ") ";
4540b57cec5SDimitry Andric 
4550b57cec5SDimitry Andric   PrintRawCompoundStmt(Node->getSubStmt());
4560b57cec5SDimitry Andric }
4570b57cec5SDimitry Andric 
4580b57cec5SDimitry Andric void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
4590b57cec5SDimitry Andric   Indent() << "goto " << Node->getLabel()->getName() << ";";
4600b57cec5SDimitry Andric   if (Policy.IncludeNewlines) OS << NL;
4610b57cec5SDimitry Andric }
4620b57cec5SDimitry Andric 
4630b57cec5SDimitry Andric void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
4640b57cec5SDimitry Andric   Indent() << "goto *";
4650b57cec5SDimitry Andric   PrintExpr(Node->getTarget());
4660b57cec5SDimitry Andric   OS << ";";
4670b57cec5SDimitry Andric   if (Policy.IncludeNewlines) OS << NL;
4680b57cec5SDimitry Andric }
4690b57cec5SDimitry Andric 
4700b57cec5SDimitry Andric void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
4710b57cec5SDimitry Andric   Indent() << "continue;";
4720b57cec5SDimitry Andric   if (Policy.IncludeNewlines) OS << NL;
4730b57cec5SDimitry Andric }
4740b57cec5SDimitry Andric 
4750b57cec5SDimitry Andric void StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
4760b57cec5SDimitry Andric   Indent() << "break;";
4770b57cec5SDimitry Andric   if (Policy.IncludeNewlines) OS << NL;
4780b57cec5SDimitry Andric }
4790b57cec5SDimitry Andric 
4800b57cec5SDimitry Andric void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
4810b57cec5SDimitry Andric   Indent() << "return";
4820b57cec5SDimitry Andric   if (Node->getRetValue()) {
4830b57cec5SDimitry Andric     OS << " ";
4840b57cec5SDimitry Andric     PrintExpr(Node->getRetValue());
4850b57cec5SDimitry Andric   }
4860b57cec5SDimitry Andric   OS << ";";
4870b57cec5SDimitry Andric   if (Policy.IncludeNewlines) OS << NL;
4880b57cec5SDimitry Andric }
4890b57cec5SDimitry Andric 
4900b57cec5SDimitry Andric void StmtPrinter::VisitGCCAsmStmt(GCCAsmStmt *Node) {
4910b57cec5SDimitry Andric   Indent() << "asm ";
4920b57cec5SDimitry Andric 
4930b57cec5SDimitry Andric   if (Node->isVolatile())
4940b57cec5SDimitry Andric     OS << "volatile ";
4950b57cec5SDimitry Andric 
4960b57cec5SDimitry Andric   if (Node->isAsmGoto())
4970b57cec5SDimitry Andric     OS << "goto ";
4980b57cec5SDimitry Andric 
4990b57cec5SDimitry Andric   OS << "(";
5000b57cec5SDimitry Andric   VisitStringLiteral(Node->getAsmString());
5010b57cec5SDimitry Andric 
5020b57cec5SDimitry Andric   // Outputs
5030b57cec5SDimitry Andric   if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 ||
5040b57cec5SDimitry Andric       Node->getNumClobbers() != 0 || Node->getNumLabels() != 0)
5050b57cec5SDimitry Andric     OS << " : ";
5060b57cec5SDimitry Andric 
5070b57cec5SDimitry Andric   for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) {
5080b57cec5SDimitry Andric     if (i != 0)
5090b57cec5SDimitry Andric       OS << ", ";
5100b57cec5SDimitry Andric 
5110b57cec5SDimitry Andric     if (!Node->getOutputName(i).empty()) {
5120b57cec5SDimitry Andric       OS << '[';
5130b57cec5SDimitry Andric       OS << Node->getOutputName(i);
5140b57cec5SDimitry Andric       OS << "] ";
5150b57cec5SDimitry Andric     }
5160b57cec5SDimitry Andric 
5170b57cec5SDimitry Andric     VisitStringLiteral(Node->getOutputConstraintLiteral(i));
5180b57cec5SDimitry Andric     OS << " (";
5190b57cec5SDimitry Andric     Visit(Node->getOutputExpr(i));
5200b57cec5SDimitry Andric     OS << ")";
5210b57cec5SDimitry Andric   }
5220b57cec5SDimitry Andric 
5230b57cec5SDimitry Andric   // Inputs
5240b57cec5SDimitry Andric   if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0 ||
5250b57cec5SDimitry Andric       Node->getNumLabels() != 0)
5260b57cec5SDimitry Andric     OS << " : ";
5270b57cec5SDimitry Andric 
5280b57cec5SDimitry Andric   for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) {
5290b57cec5SDimitry Andric     if (i != 0)
5300b57cec5SDimitry Andric       OS << ", ";
5310b57cec5SDimitry Andric 
5320b57cec5SDimitry Andric     if (!Node->getInputName(i).empty()) {
5330b57cec5SDimitry Andric       OS << '[';
5340b57cec5SDimitry Andric       OS << Node->getInputName(i);
5350b57cec5SDimitry Andric       OS << "] ";
5360b57cec5SDimitry Andric     }
5370b57cec5SDimitry Andric 
5380b57cec5SDimitry Andric     VisitStringLiteral(Node->getInputConstraintLiteral(i));
5390b57cec5SDimitry Andric     OS << " (";
5400b57cec5SDimitry Andric     Visit(Node->getInputExpr(i));
5410b57cec5SDimitry Andric     OS << ")";
5420b57cec5SDimitry Andric   }
5430b57cec5SDimitry Andric 
5440b57cec5SDimitry Andric   // Clobbers
5450b57cec5SDimitry Andric   if (Node->getNumClobbers() != 0 || Node->getNumLabels())
5460b57cec5SDimitry Andric     OS << " : ";
5470b57cec5SDimitry Andric 
5480b57cec5SDimitry Andric   for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) {
5490b57cec5SDimitry Andric     if (i != 0)
5500b57cec5SDimitry Andric       OS << ", ";
5510b57cec5SDimitry Andric 
5520b57cec5SDimitry Andric     VisitStringLiteral(Node->getClobberStringLiteral(i));
5530b57cec5SDimitry Andric   }
5540b57cec5SDimitry Andric 
5550b57cec5SDimitry Andric   // Labels
5560b57cec5SDimitry Andric   if (Node->getNumLabels() != 0)
5570b57cec5SDimitry Andric     OS << " : ";
5580b57cec5SDimitry Andric 
5590b57cec5SDimitry Andric   for (unsigned i = 0, e = Node->getNumLabels(); i != e; ++i) {
5600b57cec5SDimitry Andric     if (i != 0)
5610b57cec5SDimitry Andric       OS << ", ";
5620b57cec5SDimitry Andric     OS << Node->getLabelName(i);
5630b57cec5SDimitry Andric   }
5640b57cec5SDimitry Andric 
5650b57cec5SDimitry Andric   OS << ");";
5660b57cec5SDimitry Andric   if (Policy.IncludeNewlines) OS << NL;
5670b57cec5SDimitry Andric }
5680b57cec5SDimitry Andric 
5690b57cec5SDimitry Andric void StmtPrinter::VisitMSAsmStmt(MSAsmStmt *Node) {
5700b57cec5SDimitry Andric   // FIXME: Implement MS style inline asm statement printer.
5710b57cec5SDimitry Andric   Indent() << "__asm ";
5720b57cec5SDimitry Andric   if (Node->hasBraces())
5730b57cec5SDimitry Andric     OS << "{" << NL;
5740b57cec5SDimitry Andric   OS << Node->getAsmString() << NL;
5750b57cec5SDimitry Andric   if (Node->hasBraces())
5760b57cec5SDimitry Andric     Indent() << "}" << NL;
5770b57cec5SDimitry Andric }
5780b57cec5SDimitry Andric 
5790b57cec5SDimitry Andric void StmtPrinter::VisitCapturedStmt(CapturedStmt *Node) {
5800b57cec5SDimitry Andric   PrintStmt(Node->getCapturedDecl()->getBody());
5810b57cec5SDimitry Andric }
5820b57cec5SDimitry Andric 
5830b57cec5SDimitry Andric void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) {
5840b57cec5SDimitry Andric   Indent() << "@try";
5850b57cec5SDimitry Andric   if (auto *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) {
5860b57cec5SDimitry Andric     PrintRawCompoundStmt(TS);
5870b57cec5SDimitry Andric     OS << NL;
5880b57cec5SDimitry Andric   }
5890b57cec5SDimitry Andric 
590349cc55cSDimitry Andric   for (ObjCAtCatchStmt *catchStmt : Node->catch_stmts()) {
5910b57cec5SDimitry Andric     Indent() << "@catch(";
5920b57cec5SDimitry Andric     if (Decl *DS = catchStmt->getCatchParamDecl())
5930b57cec5SDimitry Andric       PrintRawDecl(DS);
5940b57cec5SDimitry Andric     OS << ")";
5950b57cec5SDimitry Andric     if (auto *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) {
5960b57cec5SDimitry Andric       PrintRawCompoundStmt(CS);
5970b57cec5SDimitry Andric       OS << NL;
5980b57cec5SDimitry Andric     }
5990b57cec5SDimitry Andric   }
6000b57cec5SDimitry Andric 
6010b57cec5SDimitry Andric   if (auto *FS = static_cast<ObjCAtFinallyStmt *>(Node->getFinallyStmt())) {
6020b57cec5SDimitry Andric     Indent() << "@finally";
603*5f757f3fSDimitry Andric     if (auto *CS = dyn_cast<CompoundStmt>(FS->getFinallyBody())) {
604*5f757f3fSDimitry Andric       PrintRawCompoundStmt(CS);
6050b57cec5SDimitry Andric       OS << NL;
6060b57cec5SDimitry Andric     }
6070b57cec5SDimitry Andric   }
608*5f757f3fSDimitry Andric }
6090b57cec5SDimitry Andric 
6100b57cec5SDimitry Andric void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) {
6110b57cec5SDimitry Andric }
6120b57cec5SDimitry Andric 
6130b57cec5SDimitry Andric void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) {
6140b57cec5SDimitry Andric   Indent() << "@catch (...) { /* todo */ } " << NL;
6150b57cec5SDimitry Andric }
6160b57cec5SDimitry Andric 
6170b57cec5SDimitry Andric void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) {
6180b57cec5SDimitry Andric   Indent() << "@throw";
6190b57cec5SDimitry Andric   if (Node->getThrowExpr()) {
6200b57cec5SDimitry Andric     OS << " ";
6210b57cec5SDimitry Andric     PrintExpr(Node->getThrowExpr());
6220b57cec5SDimitry Andric   }
6230b57cec5SDimitry Andric   OS << ";" << NL;
6240b57cec5SDimitry Andric }
6250b57cec5SDimitry Andric 
6260b57cec5SDimitry Andric void StmtPrinter::VisitObjCAvailabilityCheckExpr(
6270b57cec5SDimitry Andric     ObjCAvailabilityCheckExpr *Node) {
6280b57cec5SDimitry Andric   OS << "@available(...)";
6290b57cec5SDimitry Andric }
6300b57cec5SDimitry Andric 
6310b57cec5SDimitry Andric void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) {
6320b57cec5SDimitry Andric   Indent() << "@synchronized (";
6330b57cec5SDimitry Andric   PrintExpr(Node->getSynchExpr());
6340b57cec5SDimitry Andric   OS << ")";
6350b57cec5SDimitry Andric   PrintRawCompoundStmt(Node->getSynchBody());
6360b57cec5SDimitry Andric   OS << NL;
6370b57cec5SDimitry Andric }
6380b57cec5SDimitry Andric 
6390b57cec5SDimitry Andric void StmtPrinter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *Node) {
6400b57cec5SDimitry Andric   Indent() << "@autoreleasepool";
641*5f757f3fSDimitry Andric   PrintRawCompoundStmt(cast<CompoundStmt>(Node->getSubStmt()));
6420b57cec5SDimitry Andric   OS << NL;
6430b57cec5SDimitry Andric }
6440b57cec5SDimitry Andric 
6450b57cec5SDimitry Andric void StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) {
6460b57cec5SDimitry Andric   OS << "catch (";
6470b57cec5SDimitry Andric   if (Decl *ExDecl = Node->getExceptionDecl())
6480b57cec5SDimitry Andric     PrintRawDecl(ExDecl);
6490b57cec5SDimitry Andric   else
6500b57cec5SDimitry Andric     OS << "...";
6510b57cec5SDimitry Andric   OS << ") ";
6520b57cec5SDimitry Andric   PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock()));
6530b57cec5SDimitry Andric }
6540b57cec5SDimitry Andric 
6550b57cec5SDimitry Andric void StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) {
6560b57cec5SDimitry Andric   Indent();
6570b57cec5SDimitry Andric   PrintRawCXXCatchStmt(Node);
6580b57cec5SDimitry Andric   OS << NL;
6590b57cec5SDimitry Andric }
6600b57cec5SDimitry Andric 
6610b57cec5SDimitry Andric void StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) {
6620b57cec5SDimitry Andric   Indent() << "try ";
6630b57cec5SDimitry Andric   PrintRawCompoundStmt(Node->getTryBlock());
6640b57cec5SDimitry Andric   for (unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) {
6650b57cec5SDimitry Andric     OS << " ";
6660b57cec5SDimitry Andric     PrintRawCXXCatchStmt(Node->getHandler(i));
6670b57cec5SDimitry Andric   }
6680b57cec5SDimitry Andric   OS << NL;
6690b57cec5SDimitry Andric }
6700b57cec5SDimitry Andric 
6710b57cec5SDimitry Andric void StmtPrinter::VisitSEHTryStmt(SEHTryStmt *Node) {
6720b57cec5SDimitry Andric   Indent() << (Node->getIsCXXTry() ? "try " : "__try ");
6730b57cec5SDimitry Andric   PrintRawCompoundStmt(Node->getTryBlock());
6740b57cec5SDimitry Andric   SEHExceptStmt *E = Node->getExceptHandler();
6750b57cec5SDimitry Andric   SEHFinallyStmt *F = Node->getFinallyHandler();
6760b57cec5SDimitry Andric   if(E)
6770b57cec5SDimitry Andric     PrintRawSEHExceptHandler(E);
6780b57cec5SDimitry Andric   else {
6790b57cec5SDimitry Andric     assert(F && "Must have a finally block...");
6800b57cec5SDimitry Andric     PrintRawSEHFinallyStmt(F);
6810b57cec5SDimitry Andric   }
6820b57cec5SDimitry Andric   OS << NL;
6830b57cec5SDimitry Andric }
6840b57cec5SDimitry Andric 
6850b57cec5SDimitry Andric void StmtPrinter::PrintRawSEHFinallyStmt(SEHFinallyStmt *Node) {
6860b57cec5SDimitry Andric   OS << "__finally ";
6870b57cec5SDimitry Andric   PrintRawCompoundStmt(Node->getBlock());
6880b57cec5SDimitry Andric   OS << NL;
6890b57cec5SDimitry Andric }
6900b57cec5SDimitry Andric 
6910b57cec5SDimitry Andric void StmtPrinter::PrintRawSEHExceptHandler(SEHExceptStmt *Node) {
6920b57cec5SDimitry Andric   OS << "__except (";
6930b57cec5SDimitry Andric   VisitExpr(Node->getFilterExpr());
6940b57cec5SDimitry Andric   OS << ")" << NL;
6950b57cec5SDimitry Andric   PrintRawCompoundStmt(Node->getBlock());
6960b57cec5SDimitry Andric   OS << NL;
6970b57cec5SDimitry Andric }
6980b57cec5SDimitry Andric 
6990b57cec5SDimitry Andric void StmtPrinter::VisitSEHExceptStmt(SEHExceptStmt *Node) {
7000b57cec5SDimitry Andric   Indent();
7010b57cec5SDimitry Andric   PrintRawSEHExceptHandler(Node);
7020b57cec5SDimitry Andric   OS << NL;
7030b57cec5SDimitry Andric }
7040b57cec5SDimitry Andric 
7050b57cec5SDimitry Andric void StmtPrinter::VisitSEHFinallyStmt(SEHFinallyStmt *Node) {
7060b57cec5SDimitry Andric   Indent();
7070b57cec5SDimitry Andric   PrintRawSEHFinallyStmt(Node);
7080b57cec5SDimitry Andric   OS << NL;
7090b57cec5SDimitry Andric }
7100b57cec5SDimitry Andric 
7110b57cec5SDimitry Andric void StmtPrinter::VisitSEHLeaveStmt(SEHLeaveStmt *Node) {
7120b57cec5SDimitry Andric   Indent() << "__leave;";
7130b57cec5SDimitry Andric   if (Policy.IncludeNewlines) OS << NL;
7140b57cec5SDimitry Andric }
7150b57cec5SDimitry Andric 
7160b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
7170b57cec5SDimitry Andric //  OpenMP directives printing methods
7180b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
7190b57cec5SDimitry Andric 
720fe6060f1SDimitry Andric void StmtPrinter::VisitOMPCanonicalLoop(OMPCanonicalLoop *Node) {
721fe6060f1SDimitry Andric   PrintStmt(Node->getLoopStmt());
722fe6060f1SDimitry Andric }
723fe6060f1SDimitry Andric 
7240b57cec5SDimitry Andric void StmtPrinter::PrintOMPExecutableDirective(OMPExecutableDirective *S,
7250b57cec5SDimitry Andric                                               bool ForceNoStmt) {
7260b57cec5SDimitry Andric   OMPClausePrinter Printer(OS, Policy);
7270b57cec5SDimitry Andric   ArrayRef<OMPClause *> Clauses = S->clauses();
7280b57cec5SDimitry Andric   for (auto *Clause : Clauses)
7290b57cec5SDimitry Andric     if (Clause && !Clause->isImplicit()) {
7300b57cec5SDimitry Andric       OS << ' ';
7310b57cec5SDimitry Andric       Printer.Visit(Clause);
7320b57cec5SDimitry Andric     }
7330b57cec5SDimitry Andric   OS << NL;
7340b57cec5SDimitry Andric   if (!ForceNoStmt && S->hasAssociatedStmt())
735e8d8bef9SDimitry Andric     PrintStmt(S->getRawStmt());
7360b57cec5SDimitry Andric }
7370b57cec5SDimitry Andric 
738349cc55cSDimitry Andric void StmtPrinter::VisitOMPMetaDirective(OMPMetaDirective *Node) {
739349cc55cSDimitry Andric   Indent() << "#pragma omp metadirective";
740349cc55cSDimitry Andric   PrintOMPExecutableDirective(Node);
741349cc55cSDimitry Andric }
742349cc55cSDimitry Andric 
7430b57cec5SDimitry Andric void StmtPrinter::VisitOMPParallelDirective(OMPParallelDirective *Node) {
7440b57cec5SDimitry Andric   Indent() << "#pragma omp parallel";
7450b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
7460b57cec5SDimitry Andric }
7470b57cec5SDimitry Andric 
7480b57cec5SDimitry Andric void StmtPrinter::VisitOMPSimdDirective(OMPSimdDirective *Node) {
7490b57cec5SDimitry Andric   Indent() << "#pragma omp simd";
7500b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
7510b57cec5SDimitry Andric }
7520b57cec5SDimitry Andric 
753fe6060f1SDimitry Andric void StmtPrinter::VisitOMPTileDirective(OMPTileDirective *Node) {
754fe6060f1SDimitry Andric   Indent() << "#pragma omp tile";
755fe6060f1SDimitry Andric   PrintOMPExecutableDirective(Node);
756fe6060f1SDimitry Andric }
757fe6060f1SDimitry Andric 
758fe6060f1SDimitry Andric void StmtPrinter::VisitOMPUnrollDirective(OMPUnrollDirective *Node) {
759fe6060f1SDimitry Andric   Indent() << "#pragma omp unroll";
760fe6060f1SDimitry Andric   PrintOMPExecutableDirective(Node);
761fe6060f1SDimitry Andric }
762fe6060f1SDimitry Andric 
7630b57cec5SDimitry Andric void StmtPrinter::VisitOMPForDirective(OMPForDirective *Node) {
7640b57cec5SDimitry Andric   Indent() << "#pragma omp for";
7650b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
7660b57cec5SDimitry Andric }
7670b57cec5SDimitry Andric 
7680b57cec5SDimitry Andric void StmtPrinter::VisitOMPForSimdDirective(OMPForSimdDirective *Node) {
7690b57cec5SDimitry Andric   Indent() << "#pragma omp for simd";
7700b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
7710b57cec5SDimitry Andric }
7720b57cec5SDimitry Andric 
7730b57cec5SDimitry Andric void StmtPrinter::VisitOMPSectionsDirective(OMPSectionsDirective *Node) {
7740b57cec5SDimitry Andric   Indent() << "#pragma omp sections";
7750b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
7760b57cec5SDimitry Andric }
7770b57cec5SDimitry Andric 
7780b57cec5SDimitry Andric void StmtPrinter::VisitOMPSectionDirective(OMPSectionDirective *Node) {
7790b57cec5SDimitry Andric   Indent() << "#pragma omp section";
7800b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
7810b57cec5SDimitry Andric }
7820b57cec5SDimitry Andric 
783*5f757f3fSDimitry Andric void StmtPrinter::VisitOMPScopeDirective(OMPScopeDirective *Node) {
784*5f757f3fSDimitry Andric   Indent() << "#pragma omp scope";
785*5f757f3fSDimitry Andric   PrintOMPExecutableDirective(Node);
786*5f757f3fSDimitry Andric }
787*5f757f3fSDimitry Andric 
7880b57cec5SDimitry Andric void StmtPrinter::VisitOMPSingleDirective(OMPSingleDirective *Node) {
7890b57cec5SDimitry Andric   Indent() << "#pragma omp single";
7900b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
7910b57cec5SDimitry Andric }
7920b57cec5SDimitry Andric 
7930b57cec5SDimitry Andric void StmtPrinter::VisitOMPMasterDirective(OMPMasterDirective *Node) {
7940b57cec5SDimitry Andric   Indent() << "#pragma omp master";
7950b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
7960b57cec5SDimitry Andric }
7970b57cec5SDimitry Andric 
7980b57cec5SDimitry Andric void StmtPrinter::VisitOMPCriticalDirective(OMPCriticalDirective *Node) {
7990b57cec5SDimitry Andric   Indent() << "#pragma omp critical";
8000b57cec5SDimitry Andric   if (Node->getDirectiveName().getName()) {
8010b57cec5SDimitry Andric     OS << " (";
802480093f4SDimitry Andric     Node->getDirectiveName().printName(OS, Policy);
8030b57cec5SDimitry Andric     OS << ")";
8040b57cec5SDimitry Andric   }
8050b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
8060b57cec5SDimitry Andric }
8070b57cec5SDimitry Andric 
8080b57cec5SDimitry Andric void StmtPrinter::VisitOMPParallelForDirective(OMPParallelForDirective *Node) {
8090b57cec5SDimitry Andric   Indent() << "#pragma omp parallel for";
8100b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
8110b57cec5SDimitry Andric }
8120b57cec5SDimitry Andric 
8130b57cec5SDimitry Andric void StmtPrinter::VisitOMPParallelForSimdDirective(
8140b57cec5SDimitry Andric     OMPParallelForSimdDirective *Node) {
8150b57cec5SDimitry Andric   Indent() << "#pragma omp parallel for simd";
8160b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
8170b57cec5SDimitry Andric }
8180b57cec5SDimitry Andric 
819480093f4SDimitry Andric void StmtPrinter::VisitOMPParallelMasterDirective(
820480093f4SDimitry Andric     OMPParallelMasterDirective *Node) {
821480093f4SDimitry Andric   Indent() << "#pragma omp parallel master";
822480093f4SDimitry Andric   PrintOMPExecutableDirective(Node);
823480093f4SDimitry Andric }
824480093f4SDimitry Andric 
82581ad6265SDimitry Andric void StmtPrinter::VisitOMPParallelMaskedDirective(
82681ad6265SDimitry Andric     OMPParallelMaskedDirective *Node) {
82781ad6265SDimitry Andric   Indent() << "#pragma omp parallel masked";
82881ad6265SDimitry Andric   PrintOMPExecutableDirective(Node);
82981ad6265SDimitry Andric }
83081ad6265SDimitry Andric 
8310b57cec5SDimitry Andric void StmtPrinter::VisitOMPParallelSectionsDirective(
8320b57cec5SDimitry Andric     OMPParallelSectionsDirective *Node) {
8330b57cec5SDimitry Andric   Indent() << "#pragma omp parallel sections";
8340b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
8350b57cec5SDimitry Andric }
8360b57cec5SDimitry Andric 
8370b57cec5SDimitry Andric void StmtPrinter::VisitOMPTaskDirective(OMPTaskDirective *Node) {
8380b57cec5SDimitry Andric   Indent() << "#pragma omp task";
8390b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
8400b57cec5SDimitry Andric }
8410b57cec5SDimitry Andric 
8420b57cec5SDimitry Andric void StmtPrinter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *Node) {
8430b57cec5SDimitry Andric   Indent() << "#pragma omp taskyield";
8440b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
8450b57cec5SDimitry Andric }
8460b57cec5SDimitry Andric 
8470b57cec5SDimitry Andric void StmtPrinter::VisitOMPBarrierDirective(OMPBarrierDirective *Node) {
8480b57cec5SDimitry Andric   Indent() << "#pragma omp barrier";
8490b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
8500b57cec5SDimitry Andric }
8510b57cec5SDimitry Andric 
8520b57cec5SDimitry Andric void StmtPrinter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *Node) {
8530b57cec5SDimitry Andric   Indent() << "#pragma omp taskwait";
8540b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
8550b57cec5SDimitry Andric }
8560b57cec5SDimitry Andric 
857bdd1243dSDimitry Andric void StmtPrinter::VisitOMPErrorDirective(OMPErrorDirective *Node) {
858bdd1243dSDimitry Andric   Indent() << "#pragma omp error";
859bdd1243dSDimitry Andric   PrintOMPExecutableDirective(Node);
860bdd1243dSDimitry Andric }
861bdd1243dSDimitry Andric 
8620b57cec5SDimitry Andric void StmtPrinter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *Node) {
8630b57cec5SDimitry Andric   Indent() << "#pragma omp taskgroup";
8640b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
8650b57cec5SDimitry Andric }
8660b57cec5SDimitry Andric 
8670b57cec5SDimitry Andric void StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) {
8680b57cec5SDimitry Andric   Indent() << "#pragma omp flush";
8690b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
8700b57cec5SDimitry Andric }
8710b57cec5SDimitry Andric 
8725ffd83dbSDimitry Andric void StmtPrinter::VisitOMPDepobjDirective(OMPDepobjDirective *Node) {
8735ffd83dbSDimitry Andric   Indent() << "#pragma omp depobj";
8745ffd83dbSDimitry Andric   PrintOMPExecutableDirective(Node);
8755ffd83dbSDimitry Andric }
8765ffd83dbSDimitry Andric 
8775ffd83dbSDimitry Andric void StmtPrinter::VisitOMPScanDirective(OMPScanDirective *Node) {
8785ffd83dbSDimitry Andric   Indent() << "#pragma omp scan";
8795ffd83dbSDimitry Andric   PrintOMPExecutableDirective(Node);
8805ffd83dbSDimitry Andric }
8815ffd83dbSDimitry Andric 
8820b57cec5SDimitry Andric void StmtPrinter::VisitOMPOrderedDirective(OMPOrderedDirective *Node) {
8830b57cec5SDimitry Andric   Indent() << "#pragma omp ordered";
8840b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node, Node->hasClausesOfKind<OMPDependClause>());
8850b57cec5SDimitry Andric }
8860b57cec5SDimitry Andric 
8870b57cec5SDimitry Andric void StmtPrinter::VisitOMPAtomicDirective(OMPAtomicDirective *Node) {
8880b57cec5SDimitry Andric   Indent() << "#pragma omp atomic";
8890b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
8900b57cec5SDimitry Andric }
8910b57cec5SDimitry Andric 
8920b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetDirective(OMPTargetDirective *Node) {
8930b57cec5SDimitry Andric   Indent() << "#pragma omp target";
8940b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
8950b57cec5SDimitry Andric }
8960b57cec5SDimitry Andric 
8970b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetDataDirective(OMPTargetDataDirective *Node) {
8980b57cec5SDimitry Andric   Indent() << "#pragma omp target data";
8990b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
9000b57cec5SDimitry Andric }
9010b57cec5SDimitry Andric 
9020b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetEnterDataDirective(
9030b57cec5SDimitry Andric     OMPTargetEnterDataDirective *Node) {
9040b57cec5SDimitry Andric   Indent() << "#pragma omp target enter data";
9050b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
9060b57cec5SDimitry Andric }
9070b57cec5SDimitry Andric 
9080b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetExitDataDirective(
9090b57cec5SDimitry Andric     OMPTargetExitDataDirective *Node) {
9100b57cec5SDimitry Andric   Indent() << "#pragma omp target exit data";
9110b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
9120b57cec5SDimitry Andric }
9130b57cec5SDimitry Andric 
9140b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetParallelDirective(
9150b57cec5SDimitry Andric     OMPTargetParallelDirective *Node) {
9160b57cec5SDimitry Andric   Indent() << "#pragma omp target parallel";
9170b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
9180b57cec5SDimitry Andric }
9190b57cec5SDimitry Andric 
9200b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetParallelForDirective(
9210b57cec5SDimitry Andric     OMPTargetParallelForDirective *Node) {
9220b57cec5SDimitry Andric   Indent() << "#pragma omp target parallel for";
9230b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
9240b57cec5SDimitry Andric }
9250b57cec5SDimitry Andric 
9260b57cec5SDimitry Andric void StmtPrinter::VisitOMPTeamsDirective(OMPTeamsDirective *Node) {
9270b57cec5SDimitry Andric   Indent() << "#pragma omp teams";
9280b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
9290b57cec5SDimitry Andric }
9300b57cec5SDimitry Andric 
9310b57cec5SDimitry Andric void StmtPrinter::VisitOMPCancellationPointDirective(
9320b57cec5SDimitry Andric     OMPCancellationPointDirective *Node) {
9330b57cec5SDimitry Andric   Indent() << "#pragma omp cancellation point "
9340b57cec5SDimitry Andric            << getOpenMPDirectiveName(Node->getCancelRegion());
9350b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
9360b57cec5SDimitry Andric }
9370b57cec5SDimitry Andric 
9380b57cec5SDimitry Andric void StmtPrinter::VisitOMPCancelDirective(OMPCancelDirective *Node) {
9390b57cec5SDimitry Andric   Indent() << "#pragma omp cancel "
9400b57cec5SDimitry Andric            << getOpenMPDirectiveName(Node->getCancelRegion());
9410b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
9420b57cec5SDimitry Andric }
9430b57cec5SDimitry Andric 
9440b57cec5SDimitry Andric void StmtPrinter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *Node) {
9450b57cec5SDimitry Andric   Indent() << "#pragma omp taskloop";
9460b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
9470b57cec5SDimitry Andric }
9480b57cec5SDimitry Andric 
9490b57cec5SDimitry Andric void StmtPrinter::VisitOMPTaskLoopSimdDirective(
9500b57cec5SDimitry Andric     OMPTaskLoopSimdDirective *Node) {
9510b57cec5SDimitry Andric   Indent() << "#pragma omp taskloop simd";
9520b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
9530b57cec5SDimitry Andric }
9540b57cec5SDimitry Andric 
955a7dea167SDimitry Andric void StmtPrinter::VisitOMPMasterTaskLoopDirective(
956a7dea167SDimitry Andric     OMPMasterTaskLoopDirective *Node) {
957a7dea167SDimitry Andric   Indent() << "#pragma omp master taskloop";
958a7dea167SDimitry Andric   PrintOMPExecutableDirective(Node);
959a7dea167SDimitry Andric }
960a7dea167SDimitry Andric 
96181ad6265SDimitry Andric void StmtPrinter::VisitOMPMaskedTaskLoopDirective(
96281ad6265SDimitry Andric     OMPMaskedTaskLoopDirective *Node) {
96381ad6265SDimitry Andric   Indent() << "#pragma omp masked taskloop";
96481ad6265SDimitry Andric   PrintOMPExecutableDirective(Node);
96581ad6265SDimitry Andric }
96681ad6265SDimitry Andric 
967a7dea167SDimitry Andric void StmtPrinter::VisitOMPMasterTaskLoopSimdDirective(
968a7dea167SDimitry Andric     OMPMasterTaskLoopSimdDirective *Node) {
969a7dea167SDimitry Andric   Indent() << "#pragma omp master taskloop simd";
970a7dea167SDimitry Andric   PrintOMPExecutableDirective(Node);
971a7dea167SDimitry Andric }
972a7dea167SDimitry Andric 
97381ad6265SDimitry Andric void StmtPrinter::VisitOMPMaskedTaskLoopSimdDirective(
97481ad6265SDimitry Andric     OMPMaskedTaskLoopSimdDirective *Node) {
97581ad6265SDimitry Andric   Indent() << "#pragma omp masked taskloop simd";
97681ad6265SDimitry Andric   PrintOMPExecutableDirective(Node);
97781ad6265SDimitry Andric }
97881ad6265SDimitry Andric 
979a7dea167SDimitry Andric void StmtPrinter::VisitOMPParallelMasterTaskLoopDirective(
980a7dea167SDimitry Andric     OMPParallelMasterTaskLoopDirective *Node) {
981a7dea167SDimitry Andric   Indent() << "#pragma omp parallel master taskloop";
982a7dea167SDimitry Andric   PrintOMPExecutableDirective(Node);
983a7dea167SDimitry Andric }
984a7dea167SDimitry Andric 
98581ad6265SDimitry Andric void StmtPrinter::VisitOMPParallelMaskedTaskLoopDirective(
98681ad6265SDimitry Andric     OMPParallelMaskedTaskLoopDirective *Node) {
98781ad6265SDimitry Andric   Indent() << "#pragma omp parallel masked taskloop";
98881ad6265SDimitry Andric   PrintOMPExecutableDirective(Node);
98981ad6265SDimitry Andric }
99081ad6265SDimitry Andric 
991480093f4SDimitry Andric void StmtPrinter::VisitOMPParallelMasterTaskLoopSimdDirective(
992480093f4SDimitry Andric     OMPParallelMasterTaskLoopSimdDirective *Node) {
993480093f4SDimitry Andric   Indent() << "#pragma omp parallel master taskloop simd";
994480093f4SDimitry Andric   PrintOMPExecutableDirective(Node);
995480093f4SDimitry Andric }
996480093f4SDimitry Andric 
99781ad6265SDimitry Andric void StmtPrinter::VisitOMPParallelMaskedTaskLoopSimdDirective(
99881ad6265SDimitry Andric     OMPParallelMaskedTaskLoopSimdDirective *Node) {
99981ad6265SDimitry Andric   Indent() << "#pragma omp parallel masked taskloop simd";
100081ad6265SDimitry Andric   PrintOMPExecutableDirective(Node);
100181ad6265SDimitry Andric }
100281ad6265SDimitry Andric 
10030b57cec5SDimitry Andric void StmtPrinter::VisitOMPDistributeDirective(OMPDistributeDirective *Node) {
10040b57cec5SDimitry Andric   Indent() << "#pragma omp distribute";
10050b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
10060b57cec5SDimitry Andric }
10070b57cec5SDimitry Andric 
10080b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetUpdateDirective(
10090b57cec5SDimitry Andric     OMPTargetUpdateDirective *Node) {
10100b57cec5SDimitry Andric   Indent() << "#pragma omp target update";
10110b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
10120b57cec5SDimitry Andric }
10130b57cec5SDimitry Andric 
10140b57cec5SDimitry Andric void StmtPrinter::VisitOMPDistributeParallelForDirective(
10150b57cec5SDimitry Andric     OMPDistributeParallelForDirective *Node) {
10160b57cec5SDimitry Andric   Indent() << "#pragma omp distribute parallel for";
10170b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
10180b57cec5SDimitry Andric }
10190b57cec5SDimitry Andric 
10200b57cec5SDimitry Andric void StmtPrinter::VisitOMPDistributeParallelForSimdDirective(
10210b57cec5SDimitry Andric     OMPDistributeParallelForSimdDirective *Node) {
10220b57cec5SDimitry Andric   Indent() << "#pragma omp distribute parallel for simd";
10230b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
10240b57cec5SDimitry Andric }
10250b57cec5SDimitry Andric 
10260b57cec5SDimitry Andric void StmtPrinter::VisitOMPDistributeSimdDirective(
10270b57cec5SDimitry Andric     OMPDistributeSimdDirective *Node) {
10280b57cec5SDimitry Andric   Indent() << "#pragma omp distribute simd";
10290b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
10300b57cec5SDimitry Andric }
10310b57cec5SDimitry Andric 
10320b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetParallelForSimdDirective(
10330b57cec5SDimitry Andric     OMPTargetParallelForSimdDirective *Node) {
10340b57cec5SDimitry Andric   Indent() << "#pragma omp target parallel for simd";
10350b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
10360b57cec5SDimitry Andric }
10370b57cec5SDimitry Andric 
10380b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *Node) {
10390b57cec5SDimitry Andric   Indent() << "#pragma omp target simd";
10400b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
10410b57cec5SDimitry Andric }
10420b57cec5SDimitry Andric 
10430b57cec5SDimitry Andric void StmtPrinter::VisitOMPTeamsDistributeDirective(
10440b57cec5SDimitry Andric     OMPTeamsDistributeDirective *Node) {
10450b57cec5SDimitry Andric   Indent() << "#pragma omp teams distribute";
10460b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
10470b57cec5SDimitry Andric }
10480b57cec5SDimitry Andric 
10490b57cec5SDimitry Andric void StmtPrinter::VisitOMPTeamsDistributeSimdDirective(
10500b57cec5SDimitry Andric     OMPTeamsDistributeSimdDirective *Node) {
10510b57cec5SDimitry Andric   Indent() << "#pragma omp teams distribute simd";
10520b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
10530b57cec5SDimitry Andric }
10540b57cec5SDimitry Andric 
10550b57cec5SDimitry Andric void StmtPrinter::VisitOMPTeamsDistributeParallelForSimdDirective(
10560b57cec5SDimitry Andric     OMPTeamsDistributeParallelForSimdDirective *Node) {
10570b57cec5SDimitry Andric   Indent() << "#pragma omp teams distribute parallel for simd";
10580b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
10590b57cec5SDimitry Andric }
10600b57cec5SDimitry Andric 
10610b57cec5SDimitry Andric void StmtPrinter::VisitOMPTeamsDistributeParallelForDirective(
10620b57cec5SDimitry Andric     OMPTeamsDistributeParallelForDirective *Node) {
10630b57cec5SDimitry Andric   Indent() << "#pragma omp teams distribute parallel for";
10640b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
10650b57cec5SDimitry Andric }
10660b57cec5SDimitry Andric 
10670b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *Node) {
10680b57cec5SDimitry Andric   Indent() << "#pragma omp target teams";
10690b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
10700b57cec5SDimitry Andric }
10710b57cec5SDimitry Andric 
10720b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetTeamsDistributeDirective(
10730b57cec5SDimitry Andric     OMPTargetTeamsDistributeDirective *Node) {
10740b57cec5SDimitry Andric   Indent() << "#pragma omp target teams distribute";
10750b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
10760b57cec5SDimitry Andric }
10770b57cec5SDimitry Andric 
10780b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForDirective(
10790b57cec5SDimitry Andric     OMPTargetTeamsDistributeParallelForDirective *Node) {
10800b57cec5SDimitry Andric   Indent() << "#pragma omp target teams distribute parallel for";
10810b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
10820b57cec5SDimitry Andric }
10830b57cec5SDimitry Andric 
10840b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
10850b57cec5SDimitry Andric     OMPTargetTeamsDistributeParallelForSimdDirective *Node) {
10860b57cec5SDimitry Andric   Indent() << "#pragma omp target teams distribute parallel for simd";
10870b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
10880b57cec5SDimitry Andric }
10890b57cec5SDimitry Andric 
10900b57cec5SDimitry Andric void StmtPrinter::VisitOMPTargetTeamsDistributeSimdDirective(
10910b57cec5SDimitry Andric     OMPTargetTeamsDistributeSimdDirective *Node) {
10920b57cec5SDimitry Andric   Indent() << "#pragma omp target teams distribute simd";
10930b57cec5SDimitry Andric   PrintOMPExecutableDirective(Node);
10940b57cec5SDimitry Andric }
10950b57cec5SDimitry Andric 
1096fe6060f1SDimitry Andric void StmtPrinter::VisitOMPInteropDirective(OMPInteropDirective *Node) {
1097fe6060f1SDimitry Andric   Indent() << "#pragma omp interop";
1098fe6060f1SDimitry Andric   PrintOMPExecutableDirective(Node);
1099fe6060f1SDimitry Andric }
1100fe6060f1SDimitry Andric 
1101fe6060f1SDimitry Andric void StmtPrinter::VisitOMPDispatchDirective(OMPDispatchDirective *Node) {
1102fe6060f1SDimitry Andric   Indent() << "#pragma omp dispatch";
1103fe6060f1SDimitry Andric   PrintOMPExecutableDirective(Node);
1104fe6060f1SDimitry Andric }
1105fe6060f1SDimitry Andric 
1106fe6060f1SDimitry Andric void StmtPrinter::VisitOMPMaskedDirective(OMPMaskedDirective *Node) {
1107fe6060f1SDimitry Andric   Indent() << "#pragma omp masked";
1108fe6060f1SDimitry Andric   PrintOMPExecutableDirective(Node);
1109fe6060f1SDimitry Andric }
1110fe6060f1SDimitry Andric 
1111349cc55cSDimitry Andric void StmtPrinter::VisitOMPGenericLoopDirective(OMPGenericLoopDirective *Node) {
1112349cc55cSDimitry Andric   Indent() << "#pragma omp loop";
1113349cc55cSDimitry Andric   PrintOMPExecutableDirective(Node);
1114349cc55cSDimitry Andric }
1115349cc55cSDimitry Andric 
111681ad6265SDimitry Andric void StmtPrinter::VisitOMPTeamsGenericLoopDirective(
111781ad6265SDimitry Andric     OMPTeamsGenericLoopDirective *Node) {
111881ad6265SDimitry Andric   Indent() << "#pragma omp teams loop";
111981ad6265SDimitry Andric   PrintOMPExecutableDirective(Node);
112081ad6265SDimitry Andric }
112181ad6265SDimitry Andric 
112281ad6265SDimitry Andric void StmtPrinter::VisitOMPTargetTeamsGenericLoopDirective(
112381ad6265SDimitry Andric     OMPTargetTeamsGenericLoopDirective *Node) {
112481ad6265SDimitry Andric   Indent() << "#pragma omp target teams loop";
112581ad6265SDimitry Andric   PrintOMPExecutableDirective(Node);
112681ad6265SDimitry Andric }
112781ad6265SDimitry Andric 
112881ad6265SDimitry Andric void StmtPrinter::VisitOMPParallelGenericLoopDirective(
112981ad6265SDimitry Andric     OMPParallelGenericLoopDirective *Node) {
113081ad6265SDimitry Andric   Indent() << "#pragma omp parallel loop";
113181ad6265SDimitry Andric   PrintOMPExecutableDirective(Node);
113281ad6265SDimitry Andric }
113381ad6265SDimitry Andric 
113481ad6265SDimitry Andric void StmtPrinter::VisitOMPTargetParallelGenericLoopDirective(
113581ad6265SDimitry Andric     OMPTargetParallelGenericLoopDirective *Node) {
113681ad6265SDimitry Andric   Indent() << "#pragma omp target parallel loop";
113781ad6265SDimitry Andric   PrintOMPExecutableDirective(Node);
113881ad6265SDimitry Andric }
113981ad6265SDimitry Andric 
11400b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
11410b57cec5SDimitry Andric //  Expr printing methods.
11420b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
11430b57cec5SDimitry Andric 
11440b57cec5SDimitry Andric void StmtPrinter::VisitSourceLocExpr(SourceLocExpr *Node) {
11450b57cec5SDimitry Andric   OS << Node->getBuiltinStr() << "()";
11460b57cec5SDimitry Andric }
11470b57cec5SDimitry Andric 
11480b57cec5SDimitry Andric void StmtPrinter::VisitConstantExpr(ConstantExpr *Node) {
11490b57cec5SDimitry Andric   PrintExpr(Node->getSubExpr());
11500b57cec5SDimitry Andric }
11510b57cec5SDimitry Andric 
11520b57cec5SDimitry Andric void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
11530b57cec5SDimitry Andric   if (const auto *OCED = dyn_cast<OMPCapturedExprDecl>(Node->getDecl())) {
11540b57cec5SDimitry Andric     OCED->getInit()->IgnoreImpCasts()->printPretty(OS, nullptr, Policy);
11550b57cec5SDimitry Andric     return;
11560b57cec5SDimitry Andric   }
1157e8d8bef9SDimitry Andric   if (const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(Node->getDecl())) {
115881ad6265SDimitry Andric     TPOD->printAsExpr(OS, Policy);
1159e8d8bef9SDimitry Andric     return;
1160e8d8bef9SDimitry Andric   }
11610b57cec5SDimitry Andric   if (NestedNameSpecifier *Qualifier = Node->getQualifier())
11620b57cec5SDimitry Andric     Qualifier->print(OS, Policy);
11630b57cec5SDimitry Andric   if (Node->hasTemplateKeyword())
11640b57cec5SDimitry Andric     OS << "template ";
116504eeddc0SDimitry Andric   if (Policy.CleanUglifiedParameters &&
116604eeddc0SDimitry Andric       isa<ParmVarDecl, NonTypeTemplateParmDecl>(Node->getDecl()) &&
116704eeddc0SDimitry Andric       Node->getDecl()->getIdentifier())
116804eeddc0SDimitry Andric     OS << Node->getDecl()->getIdentifier()->deuglifiedName();
116904eeddc0SDimitry Andric   else
117004eeddc0SDimitry Andric     Node->getNameInfo().printName(OS, Policy);
1171fe6060f1SDimitry Andric   if (Node->hasExplicitTemplateArgs()) {
1172fe6060f1SDimitry Andric     const TemplateParameterList *TPL = nullptr;
1173fe6060f1SDimitry Andric     if (!Node->hadMultipleCandidates())
1174fe6060f1SDimitry Andric       if (auto *TD = dyn_cast<TemplateDecl>(Node->getDecl()))
1175fe6060f1SDimitry Andric         TPL = TD->getTemplateParameters();
1176fe6060f1SDimitry Andric     printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
1177fe6060f1SDimitry Andric   }
11780b57cec5SDimitry Andric }
11790b57cec5SDimitry Andric 
11800b57cec5SDimitry Andric void StmtPrinter::VisitDependentScopeDeclRefExpr(
11810b57cec5SDimitry Andric                                            DependentScopeDeclRefExpr *Node) {
11820b57cec5SDimitry Andric   if (NestedNameSpecifier *Qualifier = Node->getQualifier())
11830b57cec5SDimitry Andric     Qualifier->print(OS, Policy);
11840b57cec5SDimitry Andric   if (Node->hasTemplateKeyword())
11850b57cec5SDimitry Andric     OS << "template ";
11860b57cec5SDimitry Andric   OS << Node->getNameInfo();
11870b57cec5SDimitry Andric   if (Node->hasExplicitTemplateArgs())
11880b57cec5SDimitry Andric     printTemplateArgumentList(OS, Node->template_arguments(), Policy);
11890b57cec5SDimitry Andric }
11900b57cec5SDimitry Andric 
11910b57cec5SDimitry Andric void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
11920b57cec5SDimitry Andric   if (Node->getQualifier())
11930b57cec5SDimitry Andric     Node->getQualifier()->print(OS, Policy);
11940b57cec5SDimitry Andric   if (Node->hasTemplateKeyword())
11950b57cec5SDimitry Andric     OS << "template ";
11960b57cec5SDimitry Andric   OS << Node->getNameInfo();
11970b57cec5SDimitry Andric   if (Node->hasExplicitTemplateArgs())
11980b57cec5SDimitry Andric     printTemplateArgumentList(OS, Node->template_arguments(), Policy);
11990b57cec5SDimitry Andric }
12000b57cec5SDimitry Andric 
12010b57cec5SDimitry Andric static bool isImplicitSelf(const Expr *E) {
12020b57cec5SDimitry Andric   if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
12030b57cec5SDimitry Andric     if (const auto *PD = dyn_cast<ImplicitParamDecl>(DRE->getDecl())) {
1204*5f757f3fSDimitry Andric       if (PD->getParameterKind() == ImplicitParamKind::ObjCSelf &&
12050b57cec5SDimitry Andric           DRE->getBeginLoc().isInvalid())
12060b57cec5SDimitry Andric         return true;
12070b57cec5SDimitry Andric     }
12080b57cec5SDimitry Andric   }
12090b57cec5SDimitry Andric   return false;
12100b57cec5SDimitry Andric }
12110b57cec5SDimitry Andric 
12120b57cec5SDimitry Andric void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
12130b57cec5SDimitry Andric   if (Node->getBase()) {
12140b57cec5SDimitry Andric     if (!Policy.SuppressImplicitBase ||
12150b57cec5SDimitry Andric         !isImplicitSelf(Node->getBase()->IgnoreImpCasts())) {
12160b57cec5SDimitry Andric       PrintExpr(Node->getBase());
12170b57cec5SDimitry Andric       OS << (Node->isArrow() ? "->" : ".");
12180b57cec5SDimitry Andric     }
12190b57cec5SDimitry Andric   }
12200b57cec5SDimitry Andric   OS << *Node->getDecl();
12210b57cec5SDimitry Andric }
12220b57cec5SDimitry Andric 
12230b57cec5SDimitry Andric void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
12240b57cec5SDimitry Andric   if (Node->isSuperReceiver())
12250b57cec5SDimitry Andric     OS << "super.";
12260b57cec5SDimitry Andric   else if (Node->isObjectReceiver() && Node->getBase()) {
12270b57cec5SDimitry Andric     PrintExpr(Node->getBase());
12280b57cec5SDimitry Andric     OS << ".";
12290b57cec5SDimitry Andric   } else if (Node->isClassReceiver() && Node->getClassReceiver()) {
12300b57cec5SDimitry Andric     OS << Node->getClassReceiver()->getName() << ".";
12310b57cec5SDimitry Andric   }
12320b57cec5SDimitry Andric 
12330b57cec5SDimitry Andric   if (Node->isImplicitProperty()) {
12340b57cec5SDimitry Andric     if (const auto *Getter = Node->getImplicitPropertyGetter())
12350b57cec5SDimitry Andric       Getter->getSelector().print(OS);
12360b57cec5SDimitry Andric     else
12370b57cec5SDimitry Andric       OS << SelectorTable::getPropertyNameFromSetterSelector(
12380b57cec5SDimitry Andric           Node->getImplicitPropertySetter()->getSelector());
12390b57cec5SDimitry Andric   } else
12400b57cec5SDimitry Andric     OS << Node->getExplicitProperty()->getName();
12410b57cec5SDimitry Andric }
12420b57cec5SDimitry Andric 
12430b57cec5SDimitry Andric void StmtPrinter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node) {
12440b57cec5SDimitry Andric   PrintExpr(Node->getBaseExpr());
12450b57cec5SDimitry Andric   OS << "[";
12460b57cec5SDimitry Andric   PrintExpr(Node->getKeyExpr());
12470b57cec5SDimitry Andric   OS << "]";
12480b57cec5SDimitry Andric }
12490b57cec5SDimitry Andric 
1250fe6060f1SDimitry Andric void StmtPrinter::VisitSYCLUniqueStableNameExpr(
1251fe6060f1SDimitry Andric     SYCLUniqueStableNameExpr *Node) {
1252fe6060f1SDimitry Andric   OS << "__builtin_sycl_unique_stable_name(";
1253fe6060f1SDimitry Andric   Node->getTypeSourceInfo()->getType().print(OS, Policy);
1254fe6060f1SDimitry Andric   OS << ")";
1255fe6060f1SDimitry Andric }
1256fe6060f1SDimitry Andric 
12570b57cec5SDimitry Andric void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
12580b57cec5SDimitry Andric   OS << PredefinedExpr::getIdentKindName(Node->getIdentKind());
12590b57cec5SDimitry Andric }
12600b57cec5SDimitry Andric 
12610b57cec5SDimitry Andric void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
1262fe6060f1SDimitry Andric   CharacterLiteral::print(Node->getValue(), Node->getKind(), OS);
12630b57cec5SDimitry Andric }
12640b57cec5SDimitry Andric 
12650b57cec5SDimitry Andric /// Prints the given expression using the original source text. Returns true on
12660b57cec5SDimitry Andric /// success, false otherwise.
12670b57cec5SDimitry Andric static bool printExprAsWritten(raw_ostream &OS, Expr *E,
12680b57cec5SDimitry Andric                                const ASTContext *Context) {
12690b57cec5SDimitry Andric   if (!Context)
12700b57cec5SDimitry Andric     return false;
12710b57cec5SDimitry Andric   bool Invalid = false;
12720b57cec5SDimitry Andric   StringRef Source = Lexer::getSourceText(
12730b57cec5SDimitry Andric       CharSourceRange::getTokenRange(E->getSourceRange()),
12740b57cec5SDimitry Andric       Context->getSourceManager(), Context->getLangOpts(), &Invalid);
12750b57cec5SDimitry Andric   if (!Invalid) {
12760b57cec5SDimitry Andric     OS << Source;
12770b57cec5SDimitry Andric     return true;
12780b57cec5SDimitry Andric   }
12790b57cec5SDimitry Andric   return false;
12800b57cec5SDimitry Andric }
12810b57cec5SDimitry Andric 
12820b57cec5SDimitry Andric void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
12830b57cec5SDimitry Andric   if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
12840b57cec5SDimitry Andric     return;
12850b57cec5SDimitry Andric   bool isSigned = Node->getType()->isSignedIntegerType();
1286fe6060f1SDimitry Andric   OS << toString(Node->getValue(), 10, isSigned);
12870b57cec5SDimitry Andric 
128881ad6265SDimitry Andric   if (isa<BitIntType>(Node->getType())) {
128981ad6265SDimitry Andric     OS << (isSigned ? "wb" : "uwb");
129081ad6265SDimitry Andric     return;
129181ad6265SDimitry Andric   }
129281ad6265SDimitry Andric 
12930b57cec5SDimitry Andric   // Emit suffixes.  Integer literals are always a builtin integer type.
1294a7dea167SDimitry Andric   switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
12950b57cec5SDimitry Andric   default: llvm_unreachable("Unexpected type for integer literal!");
12960b57cec5SDimitry Andric   case BuiltinType::Char_S:
12970b57cec5SDimitry Andric   case BuiltinType::Char_U:    OS << "i8"; break;
12980b57cec5SDimitry Andric   case BuiltinType::UChar:     OS << "Ui8"; break;
1299bdd1243dSDimitry Andric   case BuiltinType::SChar:     OS << "i8"; break;
13000b57cec5SDimitry Andric   case BuiltinType::Short:     OS << "i16"; break;
13010b57cec5SDimitry Andric   case BuiltinType::UShort:    OS << "Ui16"; break;
13020b57cec5SDimitry Andric   case BuiltinType::Int:       break; // no suffix.
13030b57cec5SDimitry Andric   case BuiltinType::UInt:      OS << 'U'; break;
13040b57cec5SDimitry Andric   case BuiltinType::Long:      OS << 'L'; break;
13050b57cec5SDimitry Andric   case BuiltinType::ULong:     OS << "UL"; break;
13060b57cec5SDimitry Andric   case BuiltinType::LongLong:  OS << "LL"; break;
13070b57cec5SDimitry Andric   case BuiltinType::ULongLong: OS << "ULL"; break;
1308fe6060f1SDimitry Andric   case BuiltinType::Int128:
1309fe6060f1SDimitry Andric     break; // no suffix.
1310fe6060f1SDimitry Andric   case BuiltinType::UInt128:
1311fe6060f1SDimitry Andric     break; // no suffix.
1312bdd1243dSDimitry Andric   case BuiltinType::WChar_S:
1313bdd1243dSDimitry Andric   case BuiltinType::WChar_U:
1314bdd1243dSDimitry Andric     break; // no suffix
13150b57cec5SDimitry Andric   }
13160b57cec5SDimitry Andric }
13170b57cec5SDimitry Andric 
13180b57cec5SDimitry Andric void StmtPrinter::VisitFixedPointLiteral(FixedPointLiteral *Node) {
13190b57cec5SDimitry Andric   if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
13200b57cec5SDimitry Andric     return;
13210b57cec5SDimitry Andric   OS << Node->getValueAsString(/*Radix=*/10);
13220b57cec5SDimitry Andric 
1323a7dea167SDimitry Andric   switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
13240b57cec5SDimitry Andric     default: llvm_unreachable("Unexpected type for fixed point literal!");
13250b57cec5SDimitry Andric     case BuiltinType::ShortFract:   OS << "hr"; break;
13260b57cec5SDimitry Andric     case BuiltinType::ShortAccum:   OS << "hk"; break;
13270b57cec5SDimitry Andric     case BuiltinType::UShortFract:  OS << "uhr"; break;
13280b57cec5SDimitry Andric     case BuiltinType::UShortAccum:  OS << "uhk"; break;
13290b57cec5SDimitry Andric     case BuiltinType::Fract:        OS << "r"; break;
13300b57cec5SDimitry Andric     case BuiltinType::Accum:        OS << "k"; break;
13310b57cec5SDimitry Andric     case BuiltinType::UFract:       OS << "ur"; break;
13320b57cec5SDimitry Andric     case BuiltinType::UAccum:       OS << "uk"; break;
13330b57cec5SDimitry Andric     case BuiltinType::LongFract:    OS << "lr"; break;
13340b57cec5SDimitry Andric     case BuiltinType::LongAccum:    OS << "lk"; break;
13350b57cec5SDimitry Andric     case BuiltinType::ULongFract:   OS << "ulr"; break;
13360b57cec5SDimitry Andric     case BuiltinType::ULongAccum:   OS << "ulk"; break;
13370b57cec5SDimitry Andric   }
13380b57cec5SDimitry Andric }
13390b57cec5SDimitry Andric 
13400b57cec5SDimitry Andric static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node,
13410b57cec5SDimitry Andric                                  bool PrintSuffix) {
13420b57cec5SDimitry Andric   SmallString<16> Str;
13430b57cec5SDimitry Andric   Node->getValue().toString(Str);
13440b57cec5SDimitry Andric   OS << Str;
13450b57cec5SDimitry Andric   if (Str.find_first_not_of("-0123456789") == StringRef::npos)
13460b57cec5SDimitry Andric     OS << '.'; // Trailing dot in order to separate from ints.
13470b57cec5SDimitry Andric 
13480b57cec5SDimitry Andric   if (!PrintSuffix)
13490b57cec5SDimitry Andric     return;
13500b57cec5SDimitry Andric 
13510b57cec5SDimitry Andric   // Emit suffixes.  Float literals are always a builtin float type.
1352a7dea167SDimitry Andric   switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
13530b57cec5SDimitry Andric   default: llvm_unreachable("Unexpected type for float literal!");
13540b57cec5SDimitry Andric   case BuiltinType::Half:       break; // FIXME: suffix?
1355349cc55cSDimitry Andric   case BuiltinType::Ibm128:     break; // FIXME: No suffix for ibm128 literal
13560b57cec5SDimitry Andric   case BuiltinType::Double:     break; // no suffix.
13570b57cec5SDimitry Andric   case BuiltinType::Float16:    OS << "F16"; break;
13580b57cec5SDimitry Andric   case BuiltinType::Float:      OS << 'F'; break;
13590b57cec5SDimitry Andric   case BuiltinType::LongDouble: OS << 'L'; break;
13600b57cec5SDimitry Andric   case BuiltinType::Float128:   OS << 'Q'; break;
13610b57cec5SDimitry Andric   }
13620b57cec5SDimitry Andric }
13630b57cec5SDimitry Andric 
13640b57cec5SDimitry Andric void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
13650b57cec5SDimitry Andric   if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
13660b57cec5SDimitry Andric     return;
13670b57cec5SDimitry Andric   PrintFloatingLiteral(OS, Node, /*PrintSuffix=*/true);
13680b57cec5SDimitry Andric }
13690b57cec5SDimitry Andric 
13700b57cec5SDimitry Andric void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
13710b57cec5SDimitry Andric   PrintExpr(Node->getSubExpr());
13720b57cec5SDimitry Andric   OS << "i";
13730b57cec5SDimitry Andric }
13740b57cec5SDimitry Andric 
13750b57cec5SDimitry Andric void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
13760b57cec5SDimitry Andric   Str->outputString(OS);
13770b57cec5SDimitry Andric }
13780b57cec5SDimitry Andric 
13790b57cec5SDimitry Andric void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
13800b57cec5SDimitry Andric   OS << "(";
13810b57cec5SDimitry Andric   PrintExpr(Node->getSubExpr());
13820b57cec5SDimitry Andric   OS << ")";
13830b57cec5SDimitry Andric }
13840b57cec5SDimitry Andric 
13850b57cec5SDimitry Andric void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
13860b57cec5SDimitry Andric   if (!Node->isPostfix()) {
13870b57cec5SDimitry Andric     OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
13880b57cec5SDimitry Andric 
13890b57cec5SDimitry Andric     // Print a space if this is an "identifier operator" like __real, or if
13900b57cec5SDimitry Andric     // it might be concatenated incorrectly like '+'.
13910b57cec5SDimitry Andric     switch (Node->getOpcode()) {
13920b57cec5SDimitry Andric     default: break;
13930b57cec5SDimitry Andric     case UO_Real:
13940b57cec5SDimitry Andric     case UO_Imag:
13950b57cec5SDimitry Andric     case UO_Extension:
13960b57cec5SDimitry Andric       OS << ' ';
13970b57cec5SDimitry Andric       break;
13980b57cec5SDimitry Andric     case UO_Plus:
13990b57cec5SDimitry Andric     case UO_Minus:
14000b57cec5SDimitry Andric       if (isa<UnaryOperator>(Node->getSubExpr()))
14010b57cec5SDimitry Andric         OS << ' ';
14020b57cec5SDimitry Andric       break;
14030b57cec5SDimitry Andric     }
14040b57cec5SDimitry Andric   }
14050b57cec5SDimitry Andric   PrintExpr(Node->getSubExpr());
14060b57cec5SDimitry Andric 
14070b57cec5SDimitry Andric   if (Node->isPostfix())
14080b57cec5SDimitry Andric     OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
14090b57cec5SDimitry Andric }
14100b57cec5SDimitry Andric 
14110b57cec5SDimitry Andric void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {
14120b57cec5SDimitry Andric   OS << "__builtin_offsetof(";
14130b57cec5SDimitry Andric   Node->getTypeSourceInfo()->getType().print(OS, Policy);
14140b57cec5SDimitry Andric   OS << ", ";
14150b57cec5SDimitry Andric   bool PrintedSomething = false;
14160b57cec5SDimitry Andric   for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) {
14170b57cec5SDimitry Andric     OffsetOfNode ON = Node->getComponent(i);
14180b57cec5SDimitry Andric     if (ON.getKind() == OffsetOfNode::Array) {
14190b57cec5SDimitry Andric       // Array node
14200b57cec5SDimitry Andric       OS << "[";
14210b57cec5SDimitry Andric       PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex()));
14220b57cec5SDimitry Andric       OS << "]";
14230b57cec5SDimitry Andric       PrintedSomething = true;
14240b57cec5SDimitry Andric       continue;
14250b57cec5SDimitry Andric     }
14260b57cec5SDimitry Andric 
14270b57cec5SDimitry Andric     // Skip implicit base indirections.
14280b57cec5SDimitry Andric     if (ON.getKind() == OffsetOfNode::Base)
14290b57cec5SDimitry Andric       continue;
14300b57cec5SDimitry Andric 
14310b57cec5SDimitry Andric     // Field or identifier node.
14320b57cec5SDimitry Andric     IdentifierInfo *Id = ON.getFieldName();
14330b57cec5SDimitry Andric     if (!Id)
14340b57cec5SDimitry Andric       continue;
14350b57cec5SDimitry Andric 
14360b57cec5SDimitry Andric     if (PrintedSomething)
14370b57cec5SDimitry Andric       OS << ".";
14380b57cec5SDimitry Andric     else
14390b57cec5SDimitry Andric       PrintedSomething = true;
14400b57cec5SDimitry Andric     OS << Id->getName();
14410b57cec5SDimitry Andric   }
14420b57cec5SDimitry Andric   OS << ")";
14430b57cec5SDimitry Andric }
14440b57cec5SDimitry Andric 
14455ffd83dbSDimitry Andric void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(
14465ffd83dbSDimitry Andric     UnaryExprOrTypeTraitExpr *Node) {
14475ffd83dbSDimitry Andric   const char *Spelling = getTraitSpelling(Node->getKind());
14485ffd83dbSDimitry Andric   if (Node->getKind() == UETT_AlignOf) {
14490b57cec5SDimitry Andric     if (Policy.Alignof)
14505ffd83dbSDimitry Andric       Spelling = "alignof";
14510b57cec5SDimitry Andric     else if (Policy.UnderscoreAlignof)
14525ffd83dbSDimitry Andric       Spelling = "_Alignof";
14530b57cec5SDimitry Andric     else
14545ffd83dbSDimitry Andric       Spelling = "__alignof";
14550b57cec5SDimitry Andric   }
14565ffd83dbSDimitry Andric 
14575ffd83dbSDimitry Andric   OS << Spelling;
14585ffd83dbSDimitry Andric 
14590b57cec5SDimitry Andric   if (Node->isArgumentType()) {
14600b57cec5SDimitry Andric     OS << '(';
14610b57cec5SDimitry Andric     Node->getArgumentType().print(OS, Policy);
14620b57cec5SDimitry Andric     OS << ')';
14630b57cec5SDimitry Andric   } else {
14640b57cec5SDimitry Andric     OS << " ";
14650b57cec5SDimitry Andric     PrintExpr(Node->getArgumentExpr());
14660b57cec5SDimitry Andric   }
14670b57cec5SDimitry Andric }
14680b57cec5SDimitry Andric 
14690b57cec5SDimitry Andric void StmtPrinter::VisitGenericSelectionExpr(GenericSelectionExpr *Node) {
14700b57cec5SDimitry Andric   OS << "_Generic(";
147106c3fb27SDimitry Andric   if (Node->isExprPredicate())
14720b57cec5SDimitry Andric     PrintExpr(Node->getControllingExpr());
147306c3fb27SDimitry Andric   else
147406c3fb27SDimitry Andric     Node->getControllingType()->getType().print(OS, Policy);
147506c3fb27SDimitry Andric 
147606c3fb27SDimitry Andric   for (const GenericSelectionExpr::Association &Assoc : Node->associations()) {
14770b57cec5SDimitry Andric     OS << ", ";
14780b57cec5SDimitry Andric     QualType T = Assoc.getType();
14790b57cec5SDimitry Andric     if (T.isNull())
14800b57cec5SDimitry Andric       OS << "default";
14810b57cec5SDimitry Andric     else
14820b57cec5SDimitry Andric       T.print(OS, Policy);
14830b57cec5SDimitry Andric     OS << ": ";
14840b57cec5SDimitry Andric     PrintExpr(Assoc.getAssociationExpr());
14850b57cec5SDimitry Andric   }
14860b57cec5SDimitry Andric   OS << ")";
14870b57cec5SDimitry Andric }
14880b57cec5SDimitry Andric 
14890b57cec5SDimitry Andric void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
14900b57cec5SDimitry Andric   PrintExpr(Node->getLHS());
14910b57cec5SDimitry Andric   OS << "[";
14920b57cec5SDimitry Andric   PrintExpr(Node->getRHS());
14930b57cec5SDimitry Andric   OS << "]";
14940b57cec5SDimitry Andric }
14950b57cec5SDimitry Andric 
14965ffd83dbSDimitry Andric void StmtPrinter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *Node) {
14975ffd83dbSDimitry Andric   PrintExpr(Node->getBase());
14985ffd83dbSDimitry Andric   OS << "[";
14995ffd83dbSDimitry Andric   PrintExpr(Node->getRowIdx());
15005ffd83dbSDimitry Andric   OS << "]";
15015ffd83dbSDimitry Andric   OS << "[";
15025ffd83dbSDimitry Andric   PrintExpr(Node->getColumnIdx());
15035ffd83dbSDimitry Andric   OS << "]";
15045ffd83dbSDimitry Andric }
15055ffd83dbSDimitry Andric 
15060b57cec5SDimitry Andric void StmtPrinter::VisitOMPArraySectionExpr(OMPArraySectionExpr *Node) {
15070b57cec5SDimitry Andric   PrintExpr(Node->getBase());
15080b57cec5SDimitry Andric   OS << "[";
15090b57cec5SDimitry Andric   if (Node->getLowerBound())
15100b57cec5SDimitry Andric     PrintExpr(Node->getLowerBound());
15115ffd83dbSDimitry Andric   if (Node->getColonLocFirst().isValid()) {
15120b57cec5SDimitry Andric     OS << ":";
15130b57cec5SDimitry Andric     if (Node->getLength())
15140b57cec5SDimitry Andric       PrintExpr(Node->getLength());
15150b57cec5SDimitry Andric   }
15165ffd83dbSDimitry Andric   if (Node->getColonLocSecond().isValid()) {
15175ffd83dbSDimitry Andric     OS << ":";
15185ffd83dbSDimitry Andric     if (Node->getStride())
15195ffd83dbSDimitry Andric       PrintExpr(Node->getStride());
15205ffd83dbSDimitry Andric   }
15210b57cec5SDimitry Andric   OS << "]";
15220b57cec5SDimitry Andric }
15230b57cec5SDimitry Andric 
15245ffd83dbSDimitry Andric void StmtPrinter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *Node) {
15255ffd83dbSDimitry Andric   OS << "(";
15265ffd83dbSDimitry Andric   for (Expr *E : Node->getDimensions()) {
15275ffd83dbSDimitry Andric     OS << "[";
15285ffd83dbSDimitry Andric     PrintExpr(E);
15295ffd83dbSDimitry Andric     OS << "]";
15305ffd83dbSDimitry Andric   }
15315ffd83dbSDimitry Andric   OS << ")";
15325ffd83dbSDimitry Andric   PrintExpr(Node->getBase());
15335ffd83dbSDimitry Andric }
15345ffd83dbSDimitry Andric 
15355ffd83dbSDimitry Andric void StmtPrinter::VisitOMPIteratorExpr(OMPIteratorExpr *Node) {
15365ffd83dbSDimitry Andric   OS << "iterator(";
15375ffd83dbSDimitry Andric   for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) {
15385ffd83dbSDimitry Andric     auto *VD = cast<ValueDecl>(Node->getIteratorDecl(I));
15395ffd83dbSDimitry Andric     VD->getType().print(OS, Policy);
15405ffd83dbSDimitry Andric     const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I);
15415ffd83dbSDimitry Andric     OS << " " << VD->getName() << " = ";
15425ffd83dbSDimitry Andric     PrintExpr(Range.Begin);
15435ffd83dbSDimitry Andric     OS << ":";
15445ffd83dbSDimitry Andric     PrintExpr(Range.End);
15455ffd83dbSDimitry Andric     if (Range.Step) {
15465ffd83dbSDimitry Andric       OS << ":";
15475ffd83dbSDimitry Andric       PrintExpr(Range.Step);
15485ffd83dbSDimitry Andric     }
15495ffd83dbSDimitry Andric     if (I < E - 1)
15505ffd83dbSDimitry Andric       OS << ", ";
15515ffd83dbSDimitry Andric   }
15525ffd83dbSDimitry Andric   OS << ")";
15535ffd83dbSDimitry Andric }
15545ffd83dbSDimitry Andric 
15550b57cec5SDimitry Andric void StmtPrinter::PrintCallArgs(CallExpr *Call) {
15560b57cec5SDimitry Andric   for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
15570b57cec5SDimitry Andric     if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
15580b57cec5SDimitry Andric       // Don't print any defaulted arguments
15590b57cec5SDimitry Andric       break;
15600b57cec5SDimitry Andric     }
15610b57cec5SDimitry Andric 
15620b57cec5SDimitry Andric     if (i) OS << ", ";
15630b57cec5SDimitry Andric     PrintExpr(Call->getArg(i));
15640b57cec5SDimitry Andric   }
15650b57cec5SDimitry Andric }
15660b57cec5SDimitry Andric 
15670b57cec5SDimitry Andric void StmtPrinter::VisitCallExpr(CallExpr *Call) {
15680b57cec5SDimitry Andric   PrintExpr(Call->getCallee());
15690b57cec5SDimitry Andric   OS << "(";
15700b57cec5SDimitry Andric   PrintCallArgs(Call);
15710b57cec5SDimitry Andric   OS << ")";
15720b57cec5SDimitry Andric }
15730b57cec5SDimitry Andric 
15740b57cec5SDimitry Andric static bool isImplicitThis(const Expr *E) {
15750b57cec5SDimitry Andric   if (const auto *TE = dyn_cast<CXXThisExpr>(E))
15760b57cec5SDimitry Andric     return TE->isImplicit();
15770b57cec5SDimitry Andric   return false;
15780b57cec5SDimitry Andric }
15790b57cec5SDimitry Andric 
15800b57cec5SDimitry Andric void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
15810b57cec5SDimitry Andric   if (!Policy.SuppressImplicitBase || !isImplicitThis(Node->getBase())) {
15820b57cec5SDimitry Andric     PrintExpr(Node->getBase());
15830b57cec5SDimitry Andric 
15840b57cec5SDimitry Andric     auto *ParentMember = dyn_cast<MemberExpr>(Node->getBase());
15850b57cec5SDimitry Andric     FieldDecl *ParentDecl =
15860b57cec5SDimitry Andric         ParentMember ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl())
15870b57cec5SDimitry Andric                      : nullptr;
15880b57cec5SDimitry Andric 
15890b57cec5SDimitry Andric     if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion())
15900b57cec5SDimitry Andric       OS << (Node->isArrow() ? "->" : ".");
15910b57cec5SDimitry Andric   }
15920b57cec5SDimitry Andric 
15930b57cec5SDimitry Andric   if (auto *FD = dyn_cast<FieldDecl>(Node->getMemberDecl()))
15940b57cec5SDimitry Andric     if (FD->isAnonymousStructOrUnion())
15950b57cec5SDimitry Andric       return;
15960b57cec5SDimitry Andric 
15970b57cec5SDimitry Andric   if (NestedNameSpecifier *Qualifier = Node->getQualifier())
15980b57cec5SDimitry Andric     Qualifier->print(OS, Policy);
15990b57cec5SDimitry Andric   if (Node->hasTemplateKeyword())
16000b57cec5SDimitry Andric     OS << "template ";
16010b57cec5SDimitry Andric   OS << Node->getMemberNameInfo();
1602fe6060f1SDimitry Andric   const TemplateParameterList *TPL = nullptr;
1603fe6060f1SDimitry Andric   if (auto *FD = dyn_cast<FunctionDecl>(Node->getMemberDecl())) {
1604fe6060f1SDimitry Andric     if (!Node->hadMultipleCandidates())
1605fe6060f1SDimitry Andric       if (auto *FTD = FD->getPrimaryTemplate())
1606fe6060f1SDimitry Andric         TPL = FTD->getTemplateParameters();
1607fe6060f1SDimitry Andric   } else if (auto *VTSD =
1608fe6060f1SDimitry Andric                  dyn_cast<VarTemplateSpecializationDecl>(Node->getMemberDecl()))
1609fe6060f1SDimitry Andric     TPL = VTSD->getSpecializedTemplate()->getTemplateParameters();
16100b57cec5SDimitry Andric   if (Node->hasExplicitTemplateArgs())
1611fe6060f1SDimitry Andric     printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
16120b57cec5SDimitry Andric }
16130b57cec5SDimitry Andric 
16140b57cec5SDimitry Andric void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
16150b57cec5SDimitry Andric   PrintExpr(Node->getBase());
16160b57cec5SDimitry Andric   OS << (Node->isArrow() ? "->isa" : ".isa");
16170b57cec5SDimitry Andric }
16180b57cec5SDimitry Andric 
16190b57cec5SDimitry Andric void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
16200b57cec5SDimitry Andric   PrintExpr(Node->getBase());
16210b57cec5SDimitry Andric   OS << ".";
16220b57cec5SDimitry Andric   OS << Node->getAccessor().getName();
16230b57cec5SDimitry Andric }
16240b57cec5SDimitry Andric 
16250b57cec5SDimitry Andric void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
16260b57cec5SDimitry Andric   OS << '(';
16270b57cec5SDimitry Andric   Node->getTypeAsWritten().print(OS, Policy);
16280b57cec5SDimitry Andric   OS << ')';
16290b57cec5SDimitry Andric   PrintExpr(Node->getSubExpr());
16300b57cec5SDimitry Andric }
16310b57cec5SDimitry Andric 
16320b57cec5SDimitry Andric void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
16330b57cec5SDimitry Andric   OS << '(';
16340b57cec5SDimitry Andric   Node->getType().print(OS, Policy);
16350b57cec5SDimitry Andric   OS << ')';
16360b57cec5SDimitry Andric   PrintExpr(Node->getInitializer());
16370b57cec5SDimitry Andric }
16380b57cec5SDimitry Andric 
16390b57cec5SDimitry Andric void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
16400b57cec5SDimitry Andric   // No need to print anything, simply forward to the subexpression.
16410b57cec5SDimitry Andric   PrintExpr(Node->getSubExpr());
16420b57cec5SDimitry Andric }
16430b57cec5SDimitry Andric 
16440b57cec5SDimitry Andric void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
16450b57cec5SDimitry Andric   PrintExpr(Node->getLHS());
16460b57cec5SDimitry Andric   OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
16470b57cec5SDimitry Andric   PrintExpr(Node->getRHS());
16480b57cec5SDimitry Andric }
16490b57cec5SDimitry Andric 
16500b57cec5SDimitry Andric void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
16510b57cec5SDimitry Andric   PrintExpr(Node->getLHS());
16520b57cec5SDimitry Andric   OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
16530b57cec5SDimitry Andric   PrintExpr(Node->getRHS());
16540b57cec5SDimitry Andric }
16550b57cec5SDimitry Andric 
16560b57cec5SDimitry Andric void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
16570b57cec5SDimitry Andric   PrintExpr(Node->getCond());
16580b57cec5SDimitry Andric   OS << " ? ";
16590b57cec5SDimitry Andric   PrintExpr(Node->getLHS());
16600b57cec5SDimitry Andric   OS << " : ";
16610b57cec5SDimitry Andric   PrintExpr(Node->getRHS());
16620b57cec5SDimitry Andric }
16630b57cec5SDimitry Andric 
16640b57cec5SDimitry Andric // GNU extensions.
16650b57cec5SDimitry Andric 
16660b57cec5SDimitry Andric void
16670b57cec5SDimitry Andric StmtPrinter::VisitBinaryConditionalOperator(BinaryConditionalOperator *Node) {
16680b57cec5SDimitry Andric   PrintExpr(Node->getCommon());
16690b57cec5SDimitry Andric   OS << " ?: ";
16700b57cec5SDimitry Andric   PrintExpr(Node->getFalseExpr());
16710b57cec5SDimitry Andric }
16720b57cec5SDimitry Andric 
16730b57cec5SDimitry Andric void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
16740b57cec5SDimitry Andric   OS << "&&" << Node->getLabel()->getName();
16750b57cec5SDimitry Andric }
16760b57cec5SDimitry Andric 
16770b57cec5SDimitry Andric void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
16780b57cec5SDimitry Andric   OS << "(";
16790b57cec5SDimitry Andric   PrintRawCompoundStmt(E->getSubStmt());
16800b57cec5SDimitry Andric   OS << ")";
16810b57cec5SDimitry Andric }
16820b57cec5SDimitry Andric 
16830b57cec5SDimitry Andric void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
16840b57cec5SDimitry Andric   OS << "__builtin_choose_expr(";
16850b57cec5SDimitry Andric   PrintExpr(Node->getCond());
16860b57cec5SDimitry Andric   OS << ", ";
16870b57cec5SDimitry Andric   PrintExpr(Node->getLHS());
16880b57cec5SDimitry Andric   OS << ", ";
16890b57cec5SDimitry Andric   PrintExpr(Node->getRHS());
16900b57cec5SDimitry Andric   OS << ")";
16910b57cec5SDimitry Andric }
16920b57cec5SDimitry Andric 
16930b57cec5SDimitry Andric void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
16940b57cec5SDimitry Andric   OS << "__null";
16950b57cec5SDimitry Andric }
16960b57cec5SDimitry Andric 
16970b57cec5SDimitry Andric void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
16980b57cec5SDimitry Andric   OS << "__builtin_shufflevector(";
16990b57cec5SDimitry Andric   for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
17000b57cec5SDimitry Andric     if (i) OS << ", ";
17010b57cec5SDimitry Andric     PrintExpr(Node->getExpr(i));
17020b57cec5SDimitry Andric   }
17030b57cec5SDimitry Andric   OS << ")";
17040b57cec5SDimitry Andric }
17050b57cec5SDimitry Andric 
17060b57cec5SDimitry Andric void StmtPrinter::VisitConvertVectorExpr(ConvertVectorExpr *Node) {
17070b57cec5SDimitry Andric   OS << "__builtin_convertvector(";
17080b57cec5SDimitry Andric   PrintExpr(Node->getSrcExpr());
17090b57cec5SDimitry Andric   OS << ", ";
17100b57cec5SDimitry Andric   Node->getType().print(OS, Policy);
17110b57cec5SDimitry Andric   OS << ")";
17120b57cec5SDimitry Andric }
17130b57cec5SDimitry Andric 
17140b57cec5SDimitry Andric void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
17150b57cec5SDimitry Andric   if (Node->getSyntacticForm()) {
17160b57cec5SDimitry Andric     Visit(Node->getSyntacticForm());
17170b57cec5SDimitry Andric     return;
17180b57cec5SDimitry Andric   }
17190b57cec5SDimitry Andric 
17200b57cec5SDimitry Andric   OS << "{";
17210b57cec5SDimitry Andric   for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
17220b57cec5SDimitry Andric     if (i) OS << ", ";
17230b57cec5SDimitry Andric     if (Node->getInit(i))
17240b57cec5SDimitry Andric       PrintExpr(Node->getInit(i));
17250b57cec5SDimitry Andric     else
17260b57cec5SDimitry Andric       OS << "{}";
17270b57cec5SDimitry Andric   }
17280b57cec5SDimitry Andric   OS << "}";
17290b57cec5SDimitry Andric }
17300b57cec5SDimitry Andric 
17310b57cec5SDimitry Andric void StmtPrinter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *Node) {
17320b57cec5SDimitry Andric   // There's no way to express this expression in any of our supported
17330b57cec5SDimitry Andric   // languages, so just emit something terse and (hopefully) clear.
17340b57cec5SDimitry Andric   OS << "{";
17350b57cec5SDimitry Andric   PrintExpr(Node->getSubExpr());
17360b57cec5SDimitry Andric   OS << "}";
17370b57cec5SDimitry Andric }
17380b57cec5SDimitry Andric 
17390b57cec5SDimitry Andric void StmtPrinter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *Node) {
17400b57cec5SDimitry Andric   OS << "*";
17410b57cec5SDimitry Andric }
17420b57cec5SDimitry Andric 
17430b57cec5SDimitry Andric void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
17440b57cec5SDimitry Andric   OS << "(";
17450b57cec5SDimitry Andric   for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {
17460b57cec5SDimitry Andric     if (i) OS << ", ";
17470b57cec5SDimitry Andric     PrintExpr(Node->getExpr(i));
17480b57cec5SDimitry Andric   }
17490b57cec5SDimitry Andric   OS << ")";
17500b57cec5SDimitry Andric }
17510b57cec5SDimitry Andric 
17520b57cec5SDimitry Andric void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
17530b57cec5SDimitry Andric   bool NeedsEquals = true;
17540b57cec5SDimitry Andric   for (const DesignatedInitExpr::Designator &D : Node->designators()) {
17550b57cec5SDimitry Andric     if (D.isFieldDesignator()) {
17560b57cec5SDimitry Andric       if (D.getDotLoc().isInvalid()) {
175706c3fb27SDimitry Andric         if (const IdentifierInfo *II = D.getFieldName()) {
17580b57cec5SDimitry Andric           OS << II->getName() << ":";
17590b57cec5SDimitry Andric           NeedsEquals = false;
17600b57cec5SDimitry Andric         }
17610b57cec5SDimitry Andric       } else {
17620b57cec5SDimitry Andric         OS << "." << D.getFieldName()->getName();
17630b57cec5SDimitry Andric       }
17640b57cec5SDimitry Andric     } else {
17650b57cec5SDimitry Andric       OS << "[";
17660b57cec5SDimitry Andric       if (D.isArrayDesignator()) {
17670b57cec5SDimitry Andric         PrintExpr(Node->getArrayIndex(D));
17680b57cec5SDimitry Andric       } else {
17690b57cec5SDimitry Andric         PrintExpr(Node->getArrayRangeStart(D));
17700b57cec5SDimitry Andric         OS << " ... ";
17710b57cec5SDimitry Andric         PrintExpr(Node->getArrayRangeEnd(D));
17720b57cec5SDimitry Andric       }
17730b57cec5SDimitry Andric       OS << "]";
17740b57cec5SDimitry Andric     }
17750b57cec5SDimitry Andric   }
17760b57cec5SDimitry Andric 
17770b57cec5SDimitry Andric   if (NeedsEquals)
17780b57cec5SDimitry Andric     OS << " = ";
17790b57cec5SDimitry Andric   else
17800b57cec5SDimitry Andric     OS << " ";
17810b57cec5SDimitry Andric   PrintExpr(Node->getInit());
17820b57cec5SDimitry Andric }
17830b57cec5SDimitry Andric 
17840b57cec5SDimitry Andric void StmtPrinter::VisitDesignatedInitUpdateExpr(
17850b57cec5SDimitry Andric     DesignatedInitUpdateExpr *Node) {
17860b57cec5SDimitry Andric   OS << "{";
17870b57cec5SDimitry Andric   OS << "/*base*/";
17880b57cec5SDimitry Andric   PrintExpr(Node->getBase());
17890b57cec5SDimitry Andric   OS << ", ";
17900b57cec5SDimitry Andric 
17910b57cec5SDimitry Andric   OS << "/*updater*/";
17920b57cec5SDimitry Andric   PrintExpr(Node->getUpdater());
17930b57cec5SDimitry Andric   OS << "}";
17940b57cec5SDimitry Andric }
17950b57cec5SDimitry Andric 
17960b57cec5SDimitry Andric void StmtPrinter::VisitNoInitExpr(NoInitExpr *Node) {
17970b57cec5SDimitry Andric   OS << "/*no init*/";
17980b57cec5SDimitry Andric }
17990b57cec5SDimitry Andric 
18000b57cec5SDimitry Andric void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
18010b57cec5SDimitry Andric   if (Node->getType()->getAsCXXRecordDecl()) {
18020b57cec5SDimitry Andric     OS << "/*implicit*/";
18030b57cec5SDimitry Andric     Node->getType().print(OS, Policy);
18040b57cec5SDimitry Andric     OS << "()";
18050b57cec5SDimitry Andric   } else {
18060b57cec5SDimitry Andric     OS << "/*implicit*/(";
18070b57cec5SDimitry Andric     Node->getType().print(OS, Policy);
18080b57cec5SDimitry Andric     OS << ')';
18090b57cec5SDimitry Andric     if (Node->getType()->isRecordType())
18100b57cec5SDimitry Andric       OS << "{}";
18110b57cec5SDimitry Andric     else
18120b57cec5SDimitry Andric       OS << 0;
18130b57cec5SDimitry Andric   }
18140b57cec5SDimitry Andric }
18150b57cec5SDimitry Andric 
18160b57cec5SDimitry Andric void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
18170b57cec5SDimitry Andric   OS << "__builtin_va_arg(";
18180b57cec5SDimitry Andric   PrintExpr(Node->getSubExpr());
18190b57cec5SDimitry Andric   OS << ", ";
18200b57cec5SDimitry Andric   Node->getType().print(OS, Policy);
18210b57cec5SDimitry Andric   OS << ")";
18220b57cec5SDimitry Andric }
18230b57cec5SDimitry Andric 
18240b57cec5SDimitry Andric void StmtPrinter::VisitPseudoObjectExpr(PseudoObjectExpr *Node) {
18250b57cec5SDimitry Andric   PrintExpr(Node->getSyntacticForm());
18260b57cec5SDimitry Andric }
18270b57cec5SDimitry Andric 
18280b57cec5SDimitry Andric void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) {
18290b57cec5SDimitry Andric   const char *Name = nullptr;
18300b57cec5SDimitry Andric   switch (Node->getOp()) {
18310b57cec5SDimitry Andric #define BUILTIN(ID, TYPE, ATTRS)
18320b57cec5SDimitry Andric #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
18330b57cec5SDimitry Andric   case AtomicExpr::AO ## ID: \
18340b57cec5SDimitry Andric     Name = #ID "("; \
18350b57cec5SDimitry Andric     break;
18360b57cec5SDimitry Andric #include "clang/Basic/Builtins.def"
18370b57cec5SDimitry Andric   }
18380b57cec5SDimitry Andric   OS << Name;
18390b57cec5SDimitry Andric 
18400b57cec5SDimitry Andric   // AtomicExpr stores its subexpressions in a permuted order.
18410b57cec5SDimitry Andric   PrintExpr(Node->getPtr());
18420b57cec5SDimitry Andric   if (Node->getOp() != AtomicExpr::AO__c11_atomic_load &&
18430b57cec5SDimitry Andric       Node->getOp() != AtomicExpr::AO__atomic_load_n &&
1844*5f757f3fSDimitry Andric       Node->getOp() != AtomicExpr::AO__scoped_atomic_load_n &&
18454824e7fdSDimitry Andric       Node->getOp() != AtomicExpr::AO__opencl_atomic_load &&
18464824e7fdSDimitry Andric       Node->getOp() != AtomicExpr::AO__hip_atomic_load) {
18470b57cec5SDimitry Andric     OS << ", ";
18480b57cec5SDimitry Andric     PrintExpr(Node->getVal1());
18490b57cec5SDimitry Andric   }
18500b57cec5SDimitry Andric   if (Node->getOp() == AtomicExpr::AO__atomic_exchange ||
18510b57cec5SDimitry Andric       Node->isCmpXChg()) {
18520b57cec5SDimitry Andric     OS << ", ";
18530b57cec5SDimitry Andric     PrintExpr(Node->getVal2());
18540b57cec5SDimitry Andric   }
18550b57cec5SDimitry Andric   if (Node->getOp() == AtomicExpr::AO__atomic_compare_exchange ||
18560b57cec5SDimitry Andric       Node->getOp() == AtomicExpr::AO__atomic_compare_exchange_n) {
18570b57cec5SDimitry Andric     OS << ", ";
18580b57cec5SDimitry Andric     PrintExpr(Node->getWeak());
18590b57cec5SDimitry Andric   }
18600b57cec5SDimitry Andric   if (Node->getOp() != AtomicExpr::AO__c11_atomic_init &&
18610b57cec5SDimitry Andric       Node->getOp() != AtomicExpr::AO__opencl_atomic_init) {
18620b57cec5SDimitry Andric     OS << ", ";
18630b57cec5SDimitry Andric     PrintExpr(Node->getOrder());
18640b57cec5SDimitry Andric   }
18650b57cec5SDimitry Andric   if (Node->isCmpXChg()) {
18660b57cec5SDimitry Andric     OS << ", ";
18670b57cec5SDimitry Andric     PrintExpr(Node->getOrderFail());
18680b57cec5SDimitry Andric   }
18690b57cec5SDimitry Andric   OS << ")";
18700b57cec5SDimitry Andric }
18710b57cec5SDimitry Andric 
18720b57cec5SDimitry Andric // C++
18730b57cec5SDimitry Andric void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
18740b57cec5SDimitry Andric   OverloadedOperatorKind Kind = Node->getOperator();
18750b57cec5SDimitry Andric   if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
18760b57cec5SDimitry Andric     if (Node->getNumArgs() == 1) {
18770b57cec5SDimitry Andric       OS << getOperatorSpelling(Kind) << ' ';
18780b57cec5SDimitry Andric       PrintExpr(Node->getArg(0));
18790b57cec5SDimitry Andric     } else {
18800b57cec5SDimitry Andric       PrintExpr(Node->getArg(0));
18810b57cec5SDimitry Andric       OS << ' ' << getOperatorSpelling(Kind);
18820b57cec5SDimitry Andric     }
18830b57cec5SDimitry Andric   } else if (Kind == OO_Arrow) {
18840b57cec5SDimitry Andric     PrintExpr(Node->getArg(0));
188581ad6265SDimitry Andric   } else if (Kind == OO_Call || Kind == OO_Subscript) {
18860b57cec5SDimitry Andric     PrintExpr(Node->getArg(0));
188781ad6265SDimitry Andric     OS << (Kind == OO_Call ? '(' : '[');
18880b57cec5SDimitry Andric     for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) {
18890b57cec5SDimitry Andric       if (ArgIdx > 1)
18900b57cec5SDimitry Andric         OS << ", ";
18910b57cec5SDimitry Andric       if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx)))
18920b57cec5SDimitry Andric         PrintExpr(Node->getArg(ArgIdx));
18930b57cec5SDimitry Andric     }
189481ad6265SDimitry Andric     OS << (Kind == OO_Call ? ')' : ']');
18950b57cec5SDimitry Andric   } else if (Node->getNumArgs() == 1) {
18960b57cec5SDimitry Andric     OS << getOperatorSpelling(Kind) << ' ';
18970b57cec5SDimitry Andric     PrintExpr(Node->getArg(0));
18980b57cec5SDimitry Andric   } else if (Node->getNumArgs() == 2) {
18990b57cec5SDimitry Andric     PrintExpr(Node->getArg(0));
19000b57cec5SDimitry Andric     OS << ' ' << getOperatorSpelling(Kind) << ' ';
19010b57cec5SDimitry Andric     PrintExpr(Node->getArg(1));
19020b57cec5SDimitry Andric   } else {
19030b57cec5SDimitry Andric     llvm_unreachable("unknown overloaded operator");
19040b57cec5SDimitry Andric   }
19050b57cec5SDimitry Andric }
19060b57cec5SDimitry Andric 
19070b57cec5SDimitry Andric void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
19080b57cec5SDimitry Andric   // If we have a conversion operator call only print the argument.
19090b57cec5SDimitry Andric   CXXMethodDecl *MD = Node->getMethodDecl();
19100b57cec5SDimitry Andric   if (MD && isa<CXXConversionDecl>(MD)) {
19110b57cec5SDimitry Andric     PrintExpr(Node->getImplicitObjectArgument());
19120b57cec5SDimitry Andric     return;
19130b57cec5SDimitry Andric   }
19140b57cec5SDimitry Andric   VisitCallExpr(cast<CallExpr>(Node));
19150b57cec5SDimitry Andric }
19160b57cec5SDimitry Andric 
19170b57cec5SDimitry Andric void StmtPrinter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *Node) {
19180b57cec5SDimitry Andric   PrintExpr(Node->getCallee());
19190b57cec5SDimitry Andric   OS << "<<<";
19200b57cec5SDimitry Andric   PrintCallArgs(Node->getConfig());
19210b57cec5SDimitry Andric   OS << ">>>(";
19220b57cec5SDimitry Andric   PrintCallArgs(Node);
19230b57cec5SDimitry Andric   OS << ")";
19240b57cec5SDimitry Andric }
19250b57cec5SDimitry Andric 
1926a7dea167SDimitry Andric void StmtPrinter::VisitCXXRewrittenBinaryOperator(
1927a7dea167SDimitry Andric     CXXRewrittenBinaryOperator *Node) {
1928a7dea167SDimitry Andric   CXXRewrittenBinaryOperator::DecomposedForm Decomposed =
1929a7dea167SDimitry Andric       Node->getDecomposedForm();
1930a7dea167SDimitry Andric   PrintExpr(const_cast<Expr*>(Decomposed.LHS));
1931a7dea167SDimitry Andric   OS << ' ' << BinaryOperator::getOpcodeStr(Decomposed.Opcode) << ' ';
1932a7dea167SDimitry Andric   PrintExpr(const_cast<Expr*>(Decomposed.RHS));
1933a7dea167SDimitry Andric }
1934a7dea167SDimitry Andric 
19350b57cec5SDimitry Andric void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
19360b57cec5SDimitry Andric   OS << Node->getCastName() << '<';
19370b57cec5SDimitry Andric   Node->getTypeAsWritten().print(OS, Policy);
19380b57cec5SDimitry Andric   OS << ">(";
19390b57cec5SDimitry Andric   PrintExpr(Node->getSubExpr());
19400b57cec5SDimitry Andric   OS << ")";
19410b57cec5SDimitry Andric }
19420b57cec5SDimitry Andric 
19430b57cec5SDimitry Andric void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {
19440b57cec5SDimitry Andric   VisitCXXNamedCastExpr(Node);
19450b57cec5SDimitry Andric }
19460b57cec5SDimitry Andric 
19470b57cec5SDimitry Andric void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {
19480b57cec5SDimitry Andric   VisitCXXNamedCastExpr(Node);
19490b57cec5SDimitry Andric }
19500b57cec5SDimitry Andric 
19510b57cec5SDimitry Andric void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {
19520b57cec5SDimitry Andric   VisitCXXNamedCastExpr(Node);
19530b57cec5SDimitry Andric }
19540b57cec5SDimitry Andric 
19550b57cec5SDimitry Andric void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
19560b57cec5SDimitry Andric   VisitCXXNamedCastExpr(Node);
19570b57cec5SDimitry Andric }
19580b57cec5SDimitry Andric 
19590b57cec5SDimitry Andric void StmtPrinter::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *Node) {
19600b57cec5SDimitry Andric   OS << "__builtin_bit_cast(";
19610b57cec5SDimitry Andric   Node->getTypeInfoAsWritten()->getType().print(OS, Policy);
19620b57cec5SDimitry Andric   OS << ", ";
19630b57cec5SDimitry Andric   PrintExpr(Node->getSubExpr());
19640b57cec5SDimitry Andric   OS << ")";
19650b57cec5SDimitry Andric }
19660b57cec5SDimitry Andric 
19675ffd83dbSDimitry Andric void StmtPrinter::VisitCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *Node) {
19685ffd83dbSDimitry Andric   VisitCXXNamedCastExpr(Node);
19695ffd83dbSDimitry Andric }
19705ffd83dbSDimitry Andric 
19710b57cec5SDimitry Andric void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
19720b57cec5SDimitry Andric   OS << "typeid(";
19730b57cec5SDimitry Andric   if (Node->isTypeOperand()) {
19740b57cec5SDimitry Andric     Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
19750b57cec5SDimitry Andric   } else {
19760b57cec5SDimitry Andric     PrintExpr(Node->getExprOperand());
19770b57cec5SDimitry Andric   }
19780b57cec5SDimitry Andric   OS << ")";
19790b57cec5SDimitry Andric }
19800b57cec5SDimitry Andric 
19810b57cec5SDimitry Andric void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) {
19820b57cec5SDimitry Andric   OS << "__uuidof(";
19830b57cec5SDimitry Andric   if (Node->isTypeOperand()) {
19840b57cec5SDimitry Andric     Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
19850b57cec5SDimitry Andric   } else {
19860b57cec5SDimitry Andric     PrintExpr(Node->getExprOperand());
19870b57cec5SDimitry Andric   }
19880b57cec5SDimitry Andric   OS << ")";
19890b57cec5SDimitry Andric }
19900b57cec5SDimitry Andric 
19910b57cec5SDimitry Andric void StmtPrinter::VisitMSPropertyRefExpr(MSPropertyRefExpr *Node) {
19920b57cec5SDimitry Andric   PrintExpr(Node->getBaseExpr());
19930b57cec5SDimitry Andric   if (Node->isArrow())
19940b57cec5SDimitry Andric     OS << "->";
19950b57cec5SDimitry Andric   else
19960b57cec5SDimitry Andric     OS << ".";
19970b57cec5SDimitry Andric   if (NestedNameSpecifier *Qualifier =
19980b57cec5SDimitry Andric       Node->getQualifierLoc().getNestedNameSpecifier())
19990b57cec5SDimitry Andric     Qualifier->print(OS, Policy);
20000b57cec5SDimitry Andric   OS << Node->getPropertyDecl()->getDeclName();
20010b57cec5SDimitry Andric }
20020b57cec5SDimitry Andric 
20030b57cec5SDimitry Andric void StmtPrinter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *Node) {
20040b57cec5SDimitry Andric   PrintExpr(Node->getBase());
20050b57cec5SDimitry Andric   OS << "[";
20060b57cec5SDimitry Andric   PrintExpr(Node->getIdx());
20070b57cec5SDimitry Andric   OS << "]";
20080b57cec5SDimitry Andric }
20090b57cec5SDimitry Andric 
20100b57cec5SDimitry Andric void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) {
20110b57cec5SDimitry Andric   switch (Node->getLiteralOperatorKind()) {
20120b57cec5SDimitry Andric   case UserDefinedLiteral::LOK_Raw:
20130b57cec5SDimitry Andric     OS << cast<StringLiteral>(Node->getArg(0)->IgnoreImpCasts())->getString();
20140b57cec5SDimitry Andric     break;
20150b57cec5SDimitry Andric   case UserDefinedLiteral::LOK_Template: {
20160b57cec5SDimitry Andric     const auto *DRE = cast<DeclRefExpr>(Node->getCallee()->IgnoreImpCasts());
20170b57cec5SDimitry Andric     const TemplateArgumentList *Args =
20180b57cec5SDimitry Andric       cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs();
20190b57cec5SDimitry Andric     assert(Args);
20200b57cec5SDimitry Andric 
20216246ae0bSDimitry Andric     if (Args->size() != 1 || Args->get(0).getKind() != TemplateArgument::Pack) {
2022fe6060f1SDimitry Andric       const TemplateParameterList *TPL = nullptr;
2023fe6060f1SDimitry Andric       if (!DRE->hadMultipleCandidates())
2024fe6060f1SDimitry Andric         if (const auto *TD = dyn_cast<TemplateDecl>(DRE->getDecl()))
2025fe6060f1SDimitry Andric           TPL = TD->getTemplateParameters();
20260b57cec5SDimitry Andric       OS << "operator\"\"" << Node->getUDSuffix()->getName();
2027fe6060f1SDimitry Andric       printTemplateArgumentList(OS, Args->asArray(), Policy, TPL);
20280b57cec5SDimitry Andric       OS << "()";
20290b57cec5SDimitry Andric       return;
20300b57cec5SDimitry Andric     }
20310b57cec5SDimitry Andric 
20320b57cec5SDimitry Andric     const TemplateArgument &Pack = Args->get(0);
20330b57cec5SDimitry Andric     for (const auto &P : Pack.pack_elements()) {
20340b57cec5SDimitry Andric       char C = (char)P.getAsIntegral().getZExtValue();
20350b57cec5SDimitry Andric       OS << C;
20360b57cec5SDimitry Andric     }
20370b57cec5SDimitry Andric     break;
20380b57cec5SDimitry Andric   }
20390b57cec5SDimitry Andric   case UserDefinedLiteral::LOK_Integer: {
20400b57cec5SDimitry Andric     // Print integer literal without suffix.
20410b57cec5SDimitry Andric     const auto *Int = cast<IntegerLiteral>(Node->getCookedLiteral());
2042fe6060f1SDimitry Andric     OS << toString(Int->getValue(), 10, /*isSigned*/false);
20430b57cec5SDimitry Andric     break;
20440b57cec5SDimitry Andric   }
20450b57cec5SDimitry Andric   case UserDefinedLiteral::LOK_Floating: {
20460b57cec5SDimitry Andric     // Print floating literal without suffix.
20470b57cec5SDimitry Andric     auto *Float = cast<FloatingLiteral>(Node->getCookedLiteral());
20480b57cec5SDimitry Andric     PrintFloatingLiteral(OS, Float, /*PrintSuffix=*/false);
20490b57cec5SDimitry Andric     break;
20500b57cec5SDimitry Andric   }
20510b57cec5SDimitry Andric   case UserDefinedLiteral::LOK_String:
20520b57cec5SDimitry Andric   case UserDefinedLiteral::LOK_Character:
20530b57cec5SDimitry Andric     PrintExpr(Node->getCookedLiteral());
20540b57cec5SDimitry Andric     break;
20550b57cec5SDimitry Andric   }
20560b57cec5SDimitry Andric   OS << Node->getUDSuffix()->getName();
20570b57cec5SDimitry Andric }
20580b57cec5SDimitry Andric 
20590b57cec5SDimitry Andric void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
20600b57cec5SDimitry Andric   OS << (Node->getValue() ? "true" : "false");
20610b57cec5SDimitry Andric }
20620b57cec5SDimitry Andric 
20630b57cec5SDimitry Andric void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
20640b57cec5SDimitry Andric   OS << "nullptr";
20650b57cec5SDimitry Andric }
20660b57cec5SDimitry Andric 
20670b57cec5SDimitry Andric void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
20680b57cec5SDimitry Andric   OS << "this";
20690b57cec5SDimitry Andric }
20700b57cec5SDimitry Andric 
20710b57cec5SDimitry Andric void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
20720b57cec5SDimitry Andric   if (!Node->getSubExpr())
20730b57cec5SDimitry Andric     OS << "throw";
20740b57cec5SDimitry Andric   else {
20750b57cec5SDimitry Andric     OS << "throw ";
20760b57cec5SDimitry Andric     PrintExpr(Node->getSubExpr());
20770b57cec5SDimitry Andric   }
20780b57cec5SDimitry Andric }
20790b57cec5SDimitry Andric 
20800b57cec5SDimitry Andric void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
20810b57cec5SDimitry Andric   // Nothing to print: we picked up the default argument.
20820b57cec5SDimitry Andric }
20830b57cec5SDimitry Andric 
20840b57cec5SDimitry Andric void StmtPrinter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Node) {
20850b57cec5SDimitry Andric   // Nothing to print: we picked up the default initializer.
20860b57cec5SDimitry Andric }
20870b57cec5SDimitry Andric 
20880b57cec5SDimitry Andric void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
208981ad6265SDimitry Andric   auto TargetType = Node->getType();
209081ad6265SDimitry Andric   auto *Auto = TargetType->getContainedDeducedType();
209181ad6265SDimitry Andric   bool Bare = Auto && Auto->isDeduced();
209281ad6265SDimitry Andric 
209381ad6265SDimitry Andric   // Parenthesize deduced casts.
209481ad6265SDimitry Andric   if (Bare)
209581ad6265SDimitry Andric     OS << '(';
209681ad6265SDimitry Andric   TargetType.print(OS, Policy);
209781ad6265SDimitry Andric   if (Bare)
209881ad6265SDimitry Andric     OS << ')';
209981ad6265SDimitry Andric 
210081ad6265SDimitry Andric   // No extra braces surrounding the inner construct.
210181ad6265SDimitry Andric   if (!Node->isListInitialization())
210281ad6265SDimitry Andric     OS << '(';
21030b57cec5SDimitry Andric   PrintExpr(Node->getSubExpr());
210481ad6265SDimitry Andric   if (!Node->isListInitialization())
210581ad6265SDimitry Andric     OS << ')';
21060b57cec5SDimitry Andric }
21070b57cec5SDimitry Andric 
21080b57cec5SDimitry Andric void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
21090b57cec5SDimitry Andric   PrintExpr(Node->getSubExpr());
21100b57cec5SDimitry Andric }
21110b57cec5SDimitry Andric 
21120b57cec5SDimitry Andric void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
21130b57cec5SDimitry Andric   Node->getType().print(OS, Policy);
21140b57cec5SDimitry Andric   if (Node->isStdInitListInitialization())
21150b57cec5SDimitry Andric     /* Nothing to do; braces are part of creating the std::initializer_list. */;
21160b57cec5SDimitry Andric   else if (Node->isListInitialization())
21170b57cec5SDimitry Andric     OS << "{";
21180b57cec5SDimitry Andric   else
21190b57cec5SDimitry Andric     OS << "(";
21200b57cec5SDimitry Andric   for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),
21210b57cec5SDimitry Andric                                          ArgEnd = Node->arg_end();
21220b57cec5SDimitry Andric        Arg != ArgEnd; ++Arg) {
21230b57cec5SDimitry Andric     if ((*Arg)->isDefaultArgument())
21240b57cec5SDimitry Andric       break;
21250b57cec5SDimitry Andric     if (Arg != Node->arg_begin())
21260b57cec5SDimitry Andric       OS << ", ";
21270b57cec5SDimitry Andric     PrintExpr(*Arg);
21280b57cec5SDimitry Andric   }
21290b57cec5SDimitry Andric   if (Node->isStdInitListInitialization())
21300b57cec5SDimitry Andric     /* See above. */;
21310b57cec5SDimitry Andric   else if (Node->isListInitialization())
21320b57cec5SDimitry Andric     OS << "}";
21330b57cec5SDimitry Andric   else
21340b57cec5SDimitry Andric     OS << ")";
21350b57cec5SDimitry Andric }
21360b57cec5SDimitry Andric 
21370b57cec5SDimitry Andric void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {
21380b57cec5SDimitry Andric   OS << '[';
21390b57cec5SDimitry Andric   bool NeedComma = false;
21400b57cec5SDimitry Andric   switch (Node->getCaptureDefault()) {
21410b57cec5SDimitry Andric   case LCD_None:
21420b57cec5SDimitry Andric     break;
21430b57cec5SDimitry Andric 
21440b57cec5SDimitry Andric   case LCD_ByCopy:
21450b57cec5SDimitry Andric     OS << '=';
21460b57cec5SDimitry Andric     NeedComma = true;
21470b57cec5SDimitry Andric     break;
21480b57cec5SDimitry Andric 
21490b57cec5SDimitry Andric   case LCD_ByRef:
21500b57cec5SDimitry Andric     OS << '&';
21510b57cec5SDimitry Andric     NeedComma = true;
21520b57cec5SDimitry Andric     break;
21530b57cec5SDimitry Andric   }
21540b57cec5SDimitry Andric   for (LambdaExpr::capture_iterator C = Node->explicit_capture_begin(),
21550b57cec5SDimitry Andric                                  CEnd = Node->explicit_capture_end();
21560b57cec5SDimitry Andric        C != CEnd;
21570b57cec5SDimitry Andric        ++C) {
21580b57cec5SDimitry Andric     if (C->capturesVLAType())
21590b57cec5SDimitry Andric       continue;
21600b57cec5SDimitry Andric 
21610b57cec5SDimitry Andric     if (NeedComma)
21620b57cec5SDimitry Andric       OS << ", ";
21630b57cec5SDimitry Andric     NeedComma = true;
21640b57cec5SDimitry Andric 
21650b57cec5SDimitry Andric     switch (C->getCaptureKind()) {
21660b57cec5SDimitry Andric     case LCK_This:
21670b57cec5SDimitry Andric       OS << "this";
21680b57cec5SDimitry Andric       break;
21690b57cec5SDimitry Andric 
21700b57cec5SDimitry Andric     case LCK_StarThis:
21710b57cec5SDimitry Andric       OS << "*this";
21720b57cec5SDimitry Andric       break;
21730b57cec5SDimitry Andric 
21740b57cec5SDimitry Andric     case LCK_ByRef:
21750b57cec5SDimitry Andric       if (Node->getCaptureDefault() != LCD_ByRef || Node->isInitCapture(C))
21760b57cec5SDimitry Andric         OS << '&';
21770b57cec5SDimitry Andric       OS << C->getCapturedVar()->getName();
21780b57cec5SDimitry Andric       break;
21790b57cec5SDimitry Andric 
21800b57cec5SDimitry Andric     case LCK_ByCopy:
21810b57cec5SDimitry Andric       OS << C->getCapturedVar()->getName();
21820b57cec5SDimitry Andric       break;
21830b57cec5SDimitry Andric 
21840b57cec5SDimitry Andric     case LCK_VLAType:
21850b57cec5SDimitry Andric       llvm_unreachable("VLA type in explicit captures.");
21860b57cec5SDimitry Andric     }
21870b57cec5SDimitry Andric 
21880b57cec5SDimitry Andric     if (C->isPackExpansion())
21890b57cec5SDimitry Andric       OS << "...";
21900b57cec5SDimitry Andric 
2191e8d8bef9SDimitry Andric     if (Node->isInitCapture(C)) {
2192bdd1243dSDimitry Andric       // Init captures are always VarDecl.
2193bdd1243dSDimitry Andric       auto *D = cast<VarDecl>(C->getCapturedVar());
2194e8d8bef9SDimitry Andric 
2195e8d8bef9SDimitry Andric       llvm::StringRef Pre;
2196e8d8bef9SDimitry Andric       llvm::StringRef Post;
2197e8d8bef9SDimitry Andric       if (D->getInitStyle() == VarDecl::CallInit &&
2198e8d8bef9SDimitry Andric           !isa<ParenListExpr>(D->getInit())) {
2199e8d8bef9SDimitry Andric         Pre = "(";
2200e8d8bef9SDimitry Andric         Post = ")";
2201e8d8bef9SDimitry Andric       } else if (D->getInitStyle() == VarDecl::CInit) {
2202e8d8bef9SDimitry Andric         Pre = " = ";
2203e8d8bef9SDimitry Andric       }
2204e8d8bef9SDimitry Andric 
2205e8d8bef9SDimitry Andric       OS << Pre;
2206e8d8bef9SDimitry Andric       PrintExpr(D->getInit());
2207e8d8bef9SDimitry Andric       OS << Post;
2208e8d8bef9SDimitry Andric     }
22090b57cec5SDimitry Andric   }
22100b57cec5SDimitry Andric   OS << ']';
22110b57cec5SDimitry Andric 
22120b57cec5SDimitry Andric   if (!Node->getExplicitTemplateParameters().empty()) {
22130b57cec5SDimitry Andric     Node->getTemplateParameterList()->print(
22140b57cec5SDimitry Andric         OS, Node->getLambdaClass()->getASTContext(),
22150b57cec5SDimitry Andric         /*OmitTemplateKW*/true);
22160b57cec5SDimitry Andric   }
22170b57cec5SDimitry Andric 
22180b57cec5SDimitry Andric   if (Node->hasExplicitParameters()) {
22190b57cec5SDimitry Andric     OS << '(';
22200b57cec5SDimitry Andric     CXXMethodDecl *Method = Node->getCallOperator();
22210b57cec5SDimitry Andric     NeedComma = false;
22220b57cec5SDimitry Andric     for (const auto *P : Method->parameters()) {
22230b57cec5SDimitry Andric       if (NeedComma) {
22240b57cec5SDimitry Andric         OS << ", ";
22250b57cec5SDimitry Andric       } else {
22260b57cec5SDimitry Andric         NeedComma = true;
22270b57cec5SDimitry Andric       }
222804eeddc0SDimitry Andric       std::string ParamStr =
222904eeddc0SDimitry Andric           (Policy.CleanUglifiedParameters && P->getIdentifier())
223004eeddc0SDimitry Andric               ? P->getIdentifier()->deuglifiedName().str()
223104eeddc0SDimitry Andric               : P->getNameAsString();
22320b57cec5SDimitry Andric       P->getOriginalType().print(OS, Policy, ParamStr);
22330b57cec5SDimitry Andric     }
22340b57cec5SDimitry Andric     if (Method->isVariadic()) {
22350b57cec5SDimitry Andric       if (NeedComma)
22360b57cec5SDimitry Andric         OS << ", ";
22370b57cec5SDimitry Andric       OS << "...";
22380b57cec5SDimitry Andric     }
22390b57cec5SDimitry Andric     OS << ')';
22400b57cec5SDimitry Andric 
22410b57cec5SDimitry Andric     if (Node->isMutable())
22420b57cec5SDimitry Andric       OS << " mutable";
22430b57cec5SDimitry Andric 
2244a7dea167SDimitry Andric     auto *Proto = Method->getType()->castAs<FunctionProtoType>();
22450b57cec5SDimitry Andric     Proto->printExceptionSpecification(OS, Policy);
22460b57cec5SDimitry Andric 
22470b57cec5SDimitry Andric     // FIXME: Attributes
22480b57cec5SDimitry Andric 
22490b57cec5SDimitry Andric     // Print the trailing return type if it was specified in the source.
22500b57cec5SDimitry Andric     if (Node->hasExplicitResultType()) {
22510b57cec5SDimitry Andric       OS << " -> ";
22520b57cec5SDimitry Andric       Proto->getReturnType().print(OS, Policy);
22530b57cec5SDimitry Andric     }
22540b57cec5SDimitry Andric   }
22550b57cec5SDimitry Andric 
22560b57cec5SDimitry Andric   // Print the body.
22570b57cec5SDimitry Andric   OS << ' ';
22580b57cec5SDimitry Andric   if (Policy.TerseOutput)
22590b57cec5SDimitry Andric     OS << "{}";
22600b57cec5SDimitry Andric   else
22615ffd83dbSDimitry Andric     PrintRawCompoundStmt(Node->getCompoundStmtBody());
22620b57cec5SDimitry Andric }
22630b57cec5SDimitry Andric 
22640b57cec5SDimitry Andric void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) {
22650b57cec5SDimitry Andric   if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo())
22660b57cec5SDimitry Andric     TSInfo->getType().print(OS, Policy);
22670b57cec5SDimitry Andric   else
22680b57cec5SDimitry Andric     Node->getType().print(OS, Policy);
22690b57cec5SDimitry Andric   OS << "()";
22700b57cec5SDimitry Andric }
22710b57cec5SDimitry Andric 
22720b57cec5SDimitry Andric void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
22730b57cec5SDimitry Andric   if (E->isGlobalNew())
22740b57cec5SDimitry Andric     OS << "::";
22750b57cec5SDimitry Andric   OS << "new ";
22760b57cec5SDimitry Andric   unsigned NumPlace = E->getNumPlacementArgs();
22770b57cec5SDimitry Andric   if (NumPlace > 0 && !isa<CXXDefaultArgExpr>(E->getPlacementArg(0))) {
22780b57cec5SDimitry Andric     OS << "(";
22790b57cec5SDimitry Andric     PrintExpr(E->getPlacementArg(0));
22800b57cec5SDimitry Andric     for (unsigned i = 1; i < NumPlace; ++i) {
22810b57cec5SDimitry Andric       if (isa<CXXDefaultArgExpr>(E->getPlacementArg(i)))
22820b57cec5SDimitry Andric         break;
22830b57cec5SDimitry Andric       OS << ", ";
22840b57cec5SDimitry Andric       PrintExpr(E->getPlacementArg(i));
22850b57cec5SDimitry Andric     }
22860b57cec5SDimitry Andric     OS << ") ";
22870b57cec5SDimitry Andric   }
22880b57cec5SDimitry Andric   if (E->isParenTypeId())
22890b57cec5SDimitry Andric     OS << "(";
22900b57cec5SDimitry Andric   std::string TypeS;
229181ad6265SDimitry Andric   if (E->isArray()) {
22920b57cec5SDimitry Andric     llvm::raw_string_ostream s(TypeS);
22930b57cec5SDimitry Andric     s << '[';
2294bdd1243dSDimitry Andric     if (std::optional<Expr *> Size = E->getArraySize())
22950b57cec5SDimitry Andric       (*Size)->printPretty(s, Helper, Policy);
22960b57cec5SDimitry Andric     s << ']';
22970b57cec5SDimitry Andric   }
22980b57cec5SDimitry Andric   E->getAllocatedType().print(OS, Policy, TypeS);
22990b57cec5SDimitry Andric   if (E->isParenTypeId())
23000b57cec5SDimitry Andric     OS << ")";
23010b57cec5SDimitry Andric 
2302*5f757f3fSDimitry Andric   CXXNewInitializationStyle InitStyle = E->getInitializationStyle();
2303*5f757f3fSDimitry Andric   if (InitStyle != CXXNewInitializationStyle::None &&
2304*5f757f3fSDimitry Andric       InitStyle != CXXNewInitializationStyle::Implicit) {
2305*5f757f3fSDimitry Andric     bool Bare = InitStyle == CXXNewInitializationStyle::Call &&
230681ad6265SDimitry Andric                 !isa<ParenListExpr>(E->getInitializer());
230781ad6265SDimitry Andric     if (Bare)
23080b57cec5SDimitry Andric       OS << "(";
23090b57cec5SDimitry Andric     PrintExpr(E->getInitializer());
231081ad6265SDimitry Andric     if (Bare)
23110b57cec5SDimitry Andric       OS << ")";
23120b57cec5SDimitry Andric   }
23130b57cec5SDimitry Andric }
23140b57cec5SDimitry Andric 
23150b57cec5SDimitry Andric void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
23160b57cec5SDimitry Andric   if (E->isGlobalDelete())
23170b57cec5SDimitry Andric     OS << "::";
23180b57cec5SDimitry Andric   OS << "delete ";
23190b57cec5SDimitry Andric   if (E->isArrayForm())
23200b57cec5SDimitry Andric     OS << "[] ";
23210b57cec5SDimitry Andric   PrintExpr(E->getArgument());
23220b57cec5SDimitry Andric }
23230b57cec5SDimitry Andric 
23240b57cec5SDimitry Andric void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
23250b57cec5SDimitry Andric   PrintExpr(E->getBase());
23260b57cec5SDimitry Andric   if (E->isArrow())
23270b57cec5SDimitry Andric     OS << "->";
23280b57cec5SDimitry Andric   else
23290b57cec5SDimitry Andric     OS << '.';
23300b57cec5SDimitry Andric   if (E->getQualifier())
23310b57cec5SDimitry Andric     E->getQualifier()->print(OS, Policy);
23320b57cec5SDimitry Andric   OS << "~";
23330b57cec5SDimitry Andric 
23340b57cec5SDimitry Andric   if (IdentifierInfo *II = E->getDestroyedTypeIdentifier())
23350b57cec5SDimitry Andric     OS << II->getName();
23360b57cec5SDimitry Andric   else
23370b57cec5SDimitry Andric     E->getDestroyedType().print(OS, Policy);
23380b57cec5SDimitry Andric }
23390b57cec5SDimitry Andric 
23400b57cec5SDimitry Andric void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
23410b57cec5SDimitry Andric   if (E->isListInitialization() && !E->isStdInitListInitialization())
23420b57cec5SDimitry Andric     OS << "{";
23430b57cec5SDimitry Andric 
23440b57cec5SDimitry Andric   for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
23450b57cec5SDimitry Andric     if (isa<CXXDefaultArgExpr>(E->getArg(i))) {
23460b57cec5SDimitry Andric       // Don't print any defaulted arguments
23470b57cec5SDimitry Andric       break;
23480b57cec5SDimitry Andric     }
23490b57cec5SDimitry Andric 
23500b57cec5SDimitry Andric     if (i) OS << ", ";
23510b57cec5SDimitry Andric     PrintExpr(E->getArg(i));
23520b57cec5SDimitry Andric   }
23530b57cec5SDimitry Andric 
23540b57cec5SDimitry Andric   if (E->isListInitialization() && !E->isStdInitListInitialization())
23550b57cec5SDimitry Andric     OS << "}";
23560b57cec5SDimitry Andric }
23570b57cec5SDimitry Andric 
23580b57cec5SDimitry Andric void StmtPrinter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {
23590b57cec5SDimitry Andric   // Parens are printed by the surrounding context.
23600b57cec5SDimitry Andric   OS << "<forwarded>";
23610b57cec5SDimitry Andric }
23620b57cec5SDimitry Andric 
23630b57cec5SDimitry Andric void StmtPrinter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
23640b57cec5SDimitry Andric   PrintExpr(E->getSubExpr());
23650b57cec5SDimitry Andric }
23660b57cec5SDimitry Andric 
23670b57cec5SDimitry Andric void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) {
23680b57cec5SDimitry Andric   // Just forward to the subexpression.
23690b57cec5SDimitry Andric   PrintExpr(E->getSubExpr());
23700b57cec5SDimitry Andric }
23710b57cec5SDimitry Andric 
237281ad6265SDimitry Andric void StmtPrinter::VisitCXXUnresolvedConstructExpr(
23730b57cec5SDimitry Andric     CXXUnresolvedConstructExpr *Node) {
23740b57cec5SDimitry Andric   Node->getTypeAsWritten().print(OS, Policy);
237581ad6265SDimitry Andric   if (!Node->isListInitialization())
237681ad6265SDimitry Andric     OS << '(';
237781ad6265SDimitry Andric   for (auto Arg = Node->arg_begin(), ArgEnd = Node->arg_end(); Arg != ArgEnd;
237881ad6265SDimitry Andric        ++Arg) {
23790b57cec5SDimitry Andric     if (Arg != Node->arg_begin())
23800b57cec5SDimitry Andric       OS << ", ";
23810b57cec5SDimitry Andric     PrintExpr(*Arg);
23820b57cec5SDimitry Andric   }
238381ad6265SDimitry Andric   if (!Node->isListInitialization())
238481ad6265SDimitry Andric     OS << ')';
23850b57cec5SDimitry Andric }
23860b57cec5SDimitry Andric 
23870b57cec5SDimitry Andric void StmtPrinter::VisitCXXDependentScopeMemberExpr(
23880b57cec5SDimitry Andric                                          CXXDependentScopeMemberExpr *Node) {
23890b57cec5SDimitry Andric   if (!Node->isImplicitAccess()) {
23900b57cec5SDimitry Andric     PrintExpr(Node->getBase());
23910b57cec5SDimitry Andric     OS << (Node->isArrow() ? "->" : ".");
23920b57cec5SDimitry Andric   }
23930b57cec5SDimitry Andric   if (NestedNameSpecifier *Qualifier = Node->getQualifier())
23940b57cec5SDimitry Andric     Qualifier->print(OS, Policy);
23950b57cec5SDimitry Andric   if (Node->hasTemplateKeyword())
23960b57cec5SDimitry Andric     OS << "template ";
23970b57cec5SDimitry Andric   OS << Node->getMemberNameInfo();
23980b57cec5SDimitry Andric   if (Node->hasExplicitTemplateArgs())
23990b57cec5SDimitry Andric     printTemplateArgumentList(OS, Node->template_arguments(), Policy);
24000b57cec5SDimitry Andric }
24010b57cec5SDimitry Andric 
24020b57cec5SDimitry Andric void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
24030b57cec5SDimitry Andric   if (!Node->isImplicitAccess()) {
24040b57cec5SDimitry Andric     PrintExpr(Node->getBase());
24050b57cec5SDimitry Andric     OS << (Node->isArrow() ? "->" : ".");
24060b57cec5SDimitry Andric   }
24070b57cec5SDimitry Andric   if (NestedNameSpecifier *Qualifier = Node->getQualifier())
24080b57cec5SDimitry Andric     Qualifier->print(OS, Policy);
24090b57cec5SDimitry Andric   if (Node->hasTemplateKeyword())
24100b57cec5SDimitry Andric     OS << "template ";
24110b57cec5SDimitry Andric   OS << Node->getMemberNameInfo();
24120b57cec5SDimitry Andric   if (Node->hasExplicitTemplateArgs())
24130b57cec5SDimitry Andric     printTemplateArgumentList(OS, Node->template_arguments(), Policy);
24140b57cec5SDimitry Andric }
24150b57cec5SDimitry Andric 
24160b57cec5SDimitry Andric void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) {
24175ffd83dbSDimitry Andric   OS << getTraitSpelling(E->getTrait()) << "(";
24180b57cec5SDimitry Andric   for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
24190b57cec5SDimitry Andric     if (I > 0)
24200b57cec5SDimitry Andric       OS << ", ";
24210b57cec5SDimitry Andric     E->getArg(I)->getType().print(OS, Policy);
24220b57cec5SDimitry Andric   }
24230b57cec5SDimitry Andric   OS << ")";
24240b57cec5SDimitry Andric }
24250b57cec5SDimitry Andric 
24260b57cec5SDimitry Andric void StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
24275ffd83dbSDimitry Andric   OS << getTraitSpelling(E->getTrait()) << '(';
24280b57cec5SDimitry Andric   E->getQueriedType().print(OS, Policy);
24290b57cec5SDimitry Andric   OS << ')';
24300b57cec5SDimitry Andric }
24310b57cec5SDimitry Andric 
24320b57cec5SDimitry Andric void StmtPrinter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
24335ffd83dbSDimitry Andric   OS << getTraitSpelling(E->getTrait()) << '(';
24340b57cec5SDimitry Andric   PrintExpr(E->getQueriedExpression());
24350b57cec5SDimitry Andric   OS << ')';
24360b57cec5SDimitry Andric }
24370b57cec5SDimitry Andric 
24380b57cec5SDimitry Andric void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
24390b57cec5SDimitry Andric   OS << "noexcept(";
24400b57cec5SDimitry Andric   PrintExpr(E->getOperand());
24410b57cec5SDimitry Andric   OS << ")";
24420b57cec5SDimitry Andric }
24430b57cec5SDimitry Andric 
24440b57cec5SDimitry Andric void StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) {
24450b57cec5SDimitry Andric   PrintExpr(E->getPattern());
24460b57cec5SDimitry Andric   OS << "...";
24470b57cec5SDimitry Andric }
24480b57cec5SDimitry Andric 
24490b57cec5SDimitry Andric void StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
24500b57cec5SDimitry Andric   OS << "sizeof...(" << *E->getPack() << ")";
24510b57cec5SDimitry Andric }
24520b57cec5SDimitry Andric 
24530b57cec5SDimitry Andric void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr(
24540b57cec5SDimitry Andric                                        SubstNonTypeTemplateParmPackExpr *Node) {
24550b57cec5SDimitry Andric   OS << *Node->getParameterPack();
24560b57cec5SDimitry Andric }
24570b57cec5SDimitry Andric 
24580b57cec5SDimitry Andric void StmtPrinter::VisitSubstNonTypeTemplateParmExpr(
24590b57cec5SDimitry Andric                                        SubstNonTypeTemplateParmExpr *Node) {
24600b57cec5SDimitry Andric   Visit(Node->getReplacement());
24610b57cec5SDimitry Andric }
24620b57cec5SDimitry Andric 
24630b57cec5SDimitry Andric void StmtPrinter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
24640b57cec5SDimitry Andric   OS << *E->getParameterPack();
24650b57cec5SDimitry Andric }
24660b57cec5SDimitry Andric 
24670b57cec5SDimitry Andric void StmtPrinter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *Node){
2468480093f4SDimitry Andric   PrintExpr(Node->getSubExpr());
24690b57cec5SDimitry Andric }
24700b57cec5SDimitry Andric 
24710b57cec5SDimitry Andric void StmtPrinter::VisitCXXFoldExpr(CXXFoldExpr *E) {
24720b57cec5SDimitry Andric   OS << "(";
24730b57cec5SDimitry Andric   if (E->getLHS()) {
24740b57cec5SDimitry Andric     PrintExpr(E->getLHS());
24750b57cec5SDimitry Andric     OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
24760b57cec5SDimitry Andric   }
24770b57cec5SDimitry Andric   OS << "...";
24780b57cec5SDimitry Andric   if (E->getRHS()) {
24790b57cec5SDimitry Andric     OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
24800b57cec5SDimitry Andric     PrintExpr(E->getRHS());
24810b57cec5SDimitry Andric   }
24820b57cec5SDimitry Andric   OS << ")";
24830b57cec5SDimitry Andric }
24840b57cec5SDimitry Andric 
2485bdd1243dSDimitry Andric void StmtPrinter::VisitCXXParenListInitExpr(CXXParenListInitExpr *Node) {
2486bdd1243dSDimitry Andric   OS << "(";
2487bdd1243dSDimitry Andric   llvm::interleaveComma(Node->getInitExprs(), OS,
2488bdd1243dSDimitry Andric                         [&](Expr *E) { PrintExpr(E); });
2489bdd1243dSDimitry Andric   OS << ")";
2490bdd1243dSDimitry Andric }
2491bdd1243dSDimitry Andric 
2492a7dea167SDimitry Andric void StmtPrinter::VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) {
2493a7dea167SDimitry Andric   NestedNameSpecifierLoc NNS = E->getNestedNameSpecifierLoc();
2494a7dea167SDimitry Andric   if (NNS)
2495a7dea167SDimitry Andric     NNS.getNestedNameSpecifier()->print(OS, Policy);
2496a7dea167SDimitry Andric   if (E->getTemplateKWLoc().isValid())
2497a7dea167SDimitry Andric     OS << "template ";
2498a7dea167SDimitry Andric   OS << E->getFoundDecl()->getName();
2499a7dea167SDimitry Andric   printTemplateArgumentList(OS, E->getTemplateArgsAsWritten()->arguments(),
2500fe6060f1SDimitry Andric                             Policy,
2501fe6060f1SDimitry Andric                             E->getNamedConcept()->getTemplateParameters());
2502a7dea167SDimitry Andric }
2503a7dea167SDimitry Andric 
250455e4f9d5SDimitry Andric void StmtPrinter::VisitRequiresExpr(RequiresExpr *E) {
250555e4f9d5SDimitry Andric   OS << "requires ";
250655e4f9d5SDimitry Andric   auto LocalParameters = E->getLocalParameters();
250755e4f9d5SDimitry Andric   if (!LocalParameters.empty()) {
250855e4f9d5SDimitry Andric     OS << "(";
250955e4f9d5SDimitry Andric     for (ParmVarDecl *LocalParam : LocalParameters) {
251055e4f9d5SDimitry Andric       PrintRawDecl(LocalParam);
251155e4f9d5SDimitry Andric       if (LocalParam != LocalParameters.back())
251255e4f9d5SDimitry Andric         OS << ", ";
251355e4f9d5SDimitry Andric     }
251455e4f9d5SDimitry Andric 
251555e4f9d5SDimitry Andric     OS << ") ";
251655e4f9d5SDimitry Andric   }
251755e4f9d5SDimitry Andric   OS << "{ ";
251855e4f9d5SDimitry Andric   auto Requirements = E->getRequirements();
251955e4f9d5SDimitry Andric   for (concepts::Requirement *Req : Requirements) {
252055e4f9d5SDimitry Andric     if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
252155e4f9d5SDimitry Andric       if (TypeReq->isSubstitutionFailure())
252255e4f9d5SDimitry Andric         OS << "<<error-type>>";
252355e4f9d5SDimitry Andric       else
252455e4f9d5SDimitry Andric         TypeReq->getType()->getType().print(OS, Policy);
252555e4f9d5SDimitry Andric     } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
252655e4f9d5SDimitry Andric       if (ExprReq->isCompound())
252755e4f9d5SDimitry Andric         OS << "{ ";
252855e4f9d5SDimitry Andric       if (ExprReq->isExprSubstitutionFailure())
252955e4f9d5SDimitry Andric         OS << "<<error-expression>>";
253055e4f9d5SDimitry Andric       else
253155e4f9d5SDimitry Andric         PrintExpr(ExprReq->getExpr());
253255e4f9d5SDimitry Andric       if (ExprReq->isCompound()) {
253355e4f9d5SDimitry Andric         OS << " }";
253455e4f9d5SDimitry Andric         if (ExprReq->getNoexceptLoc().isValid())
253555e4f9d5SDimitry Andric           OS << " noexcept";
253655e4f9d5SDimitry Andric         const auto &RetReq = ExprReq->getReturnTypeRequirement();
253755e4f9d5SDimitry Andric         if (!RetReq.isEmpty()) {
253855e4f9d5SDimitry Andric           OS << " -> ";
253955e4f9d5SDimitry Andric           if (RetReq.isSubstitutionFailure())
254055e4f9d5SDimitry Andric             OS << "<<error-type>>";
254155e4f9d5SDimitry Andric           else if (RetReq.isTypeConstraint())
254255e4f9d5SDimitry Andric             RetReq.getTypeConstraint()->print(OS, Policy);
254355e4f9d5SDimitry Andric         }
254455e4f9d5SDimitry Andric       }
254555e4f9d5SDimitry Andric     } else {
254655e4f9d5SDimitry Andric       auto *NestedReq = cast<concepts::NestedRequirement>(Req);
254755e4f9d5SDimitry Andric       OS << "requires ";
2548bdd1243dSDimitry Andric       if (NestedReq->hasInvalidConstraint())
254955e4f9d5SDimitry Andric         OS << "<<error-expression>>";
255055e4f9d5SDimitry Andric       else
255155e4f9d5SDimitry Andric         PrintExpr(NestedReq->getConstraintExpr());
255255e4f9d5SDimitry Andric     }
255355e4f9d5SDimitry Andric     OS << "; ";
255455e4f9d5SDimitry Andric   }
255555e4f9d5SDimitry Andric   OS << "}";
255655e4f9d5SDimitry Andric }
255755e4f9d5SDimitry Andric 
255806c3fb27SDimitry Andric // C++ Coroutines
25590b57cec5SDimitry Andric 
25600b57cec5SDimitry Andric void StmtPrinter::VisitCoroutineBodyStmt(CoroutineBodyStmt *S) {
25610b57cec5SDimitry Andric   Visit(S->getBody());
25620b57cec5SDimitry Andric }
25630b57cec5SDimitry Andric 
25640b57cec5SDimitry Andric void StmtPrinter::VisitCoreturnStmt(CoreturnStmt *S) {
25650b57cec5SDimitry Andric   OS << "co_return";
25660b57cec5SDimitry Andric   if (S->getOperand()) {
25670b57cec5SDimitry Andric     OS << " ";
25680b57cec5SDimitry Andric     Visit(S->getOperand());
25690b57cec5SDimitry Andric   }
25700b57cec5SDimitry Andric   OS << ";";
25710b57cec5SDimitry Andric }
25720b57cec5SDimitry Andric 
25730b57cec5SDimitry Andric void StmtPrinter::VisitCoawaitExpr(CoawaitExpr *S) {
25740b57cec5SDimitry Andric   OS << "co_await ";
25750b57cec5SDimitry Andric   PrintExpr(S->getOperand());
25760b57cec5SDimitry Andric }
25770b57cec5SDimitry Andric 
25780b57cec5SDimitry Andric void StmtPrinter::VisitDependentCoawaitExpr(DependentCoawaitExpr *S) {
25790b57cec5SDimitry Andric   OS << "co_await ";
25800b57cec5SDimitry Andric   PrintExpr(S->getOperand());
25810b57cec5SDimitry Andric }
25820b57cec5SDimitry Andric 
25830b57cec5SDimitry Andric void StmtPrinter::VisitCoyieldExpr(CoyieldExpr *S) {
25840b57cec5SDimitry Andric   OS << "co_yield ";
25850b57cec5SDimitry Andric   PrintExpr(S->getOperand());
25860b57cec5SDimitry Andric }
25870b57cec5SDimitry Andric 
25880b57cec5SDimitry Andric // Obj-C
25890b57cec5SDimitry Andric 
25900b57cec5SDimitry Andric void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
25910b57cec5SDimitry Andric   OS << "@";
25920b57cec5SDimitry Andric   VisitStringLiteral(Node->getString());
25930b57cec5SDimitry Andric }
25940b57cec5SDimitry Andric 
25950b57cec5SDimitry Andric void StmtPrinter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
25960b57cec5SDimitry Andric   OS << "@";
25970b57cec5SDimitry Andric   Visit(E->getSubExpr());
25980b57cec5SDimitry Andric }
25990b57cec5SDimitry Andric 
26000b57cec5SDimitry Andric void StmtPrinter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
26010b57cec5SDimitry Andric   OS << "@[ ";
26020b57cec5SDimitry Andric   ObjCArrayLiteral::child_range Ch = E->children();
26030b57cec5SDimitry Andric   for (auto I = Ch.begin(), E = Ch.end(); I != E; ++I) {
26040b57cec5SDimitry Andric     if (I != Ch.begin())
26050b57cec5SDimitry Andric       OS << ", ";
26060b57cec5SDimitry Andric     Visit(*I);
26070b57cec5SDimitry Andric   }
26080b57cec5SDimitry Andric   OS << " ]";
26090b57cec5SDimitry Andric }
26100b57cec5SDimitry Andric 
26110b57cec5SDimitry Andric void StmtPrinter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
26120b57cec5SDimitry Andric   OS << "@{ ";
26130b57cec5SDimitry Andric   for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
26140b57cec5SDimitry Andric     if (I > 0)
26150b57cec5SDimitry Andric       OS << ", ";
26160b57cec5SDimitry Andric 
26170b57cec5SDimitry Andric     ObjCDictionaryElement Element = E->getKeyValueElement(I);
26180b57cec5SDimitry Andric     Visit(Element.Key);
26190b57cec5SDimitry Andric     OS << " : ";
26200b57cec5SDimitry Andric     Visit(Element.Value);
26210b57cec5SDimitry Andric     if (Element.isPackExpansion())
26220b57cec5SDimitry Andric       OS << "...";
26230b57cec5SDimitry Andric   }
26240b57cec5SDimitry Andric   OS << " }";
26250b57cec5SDimitry Andric }
26260b57cec5SDimitry Andric 
26270b57cec5SDimitry Andric void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
26280b57cec5SDimitry Andric   OS << "@encode(";
26290b57cec5SDimitry Andric   Node->getEncodedType().print(OS, Policy);
26300b57cec5SDimitry Andric   OS << ')';
26310b57cec5SDimitry Andric }
26320b57cec5SDimitry Andric 
26330b57cec5SDimitry Andric void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
26340b57cec5SDimitry Andric   OS << "@selector(";
26350b57cec5SDimitry Andric   Node->getSelector().print(OS);
26360b57cec5SDimitry Andric   OS << ')';
26370b57cec5SDimitry Andric }
26380b57cec5SDimitry Andric 
26390b57cec5SDimitry Andric void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
26400b57cec5SDimitry Andric   OS << "@protocol(" << *Node->getProtocol() << ')';
26410b57cec5SDimitry Andric }
26420b57cec5SDimitry Andric 
26430b57cec5SDimitry Andric void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
26440b57cec5SDimitry Andric   OS << "[";
26450b57cec5SDimitry Andric   switch (Mess->getReceiverKind()) {
26460b57cec5SDimitry Andric   case ObjCMessageExpr::Instance:
26470b57cec5SDimitry Andric     PrintExpr(Mess->getInstanceReceiver());
26480b57cec5SDimitry Andric     break;
26490b57cec5SDimitry Andric 
26500b57cec5SDimitry Andric   case ObjCMessageExpr::Class:
26510b57cec5SDimitry Andric     Mess->getClassReceiver().print(OS, Policy);
26520b57cec5SDimitry Andric     break;
26530b57cec5SDimitry Andric 
26540b57cec5SDimitry Andric   case ObjCMessageExpr::SuperInstance:
26550b57cec5SDimitry Andric   case ObjCMessageExpr::SuperClass:
26560b57cec5SDimitry Andric     OS << "Super";
26570b57cec5SDimitry Andric     break;
26580b57cec5SDimitry Andric   }
26590b57cec5SDimitry Andric 
26600b57cec5SDimitry Andric   OS << ' ';
26610b57cec5SDimitry Andric   Selector selector = Mess->getSelector();
26620b57cec5SDimitry Andric   if (selector.isUnarySelector()) {
26630b57cec5SDimitry Andric     OS << selector.getNameForSlot(0);
26640b57cec5SDimitry Andric   } else {
26650b57cec5SDimitry Andric     for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
26660b57cec5SDimitry Andric       if (i < selector.getNumArgs()) {
26670b57cec5SDimitry Andric         if (i > 0) OS << ' ';
26680b57cec5SDimitry Andric         if (selector.getIdentifierInfoForSlot(i))
26690b57cec5SDimitry Andric           OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';
26700b57cec5SDimitry Andric         else
26710b57cec5SDimitry Andric            OS << ":";
26720b57cec5SDimitry Andric       }
26730b57cec5SDimitry Andric       else OS << ", "; // Handle variadic methods.
26740b57cec5SDimitry Andric 
26750b57cec5SDimitry Andric       PrintExpr(Mess->getArg(i));
26760b57cec5SDimitry Andric     }
26770b57cec5SDimitry Andric   }
26780b57cec5SDimitry Andric   OS << "]";
26790b57cec5SDimitry Andric }
26800b57cec5SDimitry Andric 
26810b57cec5SDimitry Andric void StmtPrinter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) {
26820b57cec5SDimitry Andric   OS << (Node->getValue() ? "__objc_yes" : "__objc_no");
26830b57cec5SDimitry Andric }
26840b57cec5SDimitry Andric 
26850b57cec5SDimitry Andric void
26860b57cec5SDimitry Andric StmtPrinter::VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
26870b57cec5SDimitry Andric   PrintExpr(E->getSubExpr());
26880b57cec5SDimitry Andric }
26890b57cec5SDimitry Andric 
26900b57cec5SDimitry Andric void
26910b57cec5SDimitry Andric StmtPrinter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
26920b57cec5SDimitry Andric   OS << '(' << E->getBridgeKindName();
26930b57cec5SDimitry Andric   E->getType().print(OS, Policy);
26940b57cec5SDimitry Andric   OS << ')';
26950b57cec5SDimitry Andric   PrintExpr(E->getSubExpr());
26960b57cec5SDimitry Andric }
26970b57cec5SDimitry Andric 
26980b57cec5SDimitry Andric void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
26990b57cec5SDimitry Andric   BlockDecl *BD = Node->getBlockDecl();
27000b57cec5SDimitry Andric   OS << "^";
27010b57cec5SDimitry Andric 
27020b57cec5SDimitry Andric   const FunctionType *AFT = Node->getFunctionType();
27030b57cec5SDimitry Andric 
27040b57cec5SDimitry Andric   if (isa<FunctionNoProtoType>(AFT)) {
27050b57cec5SDimitry Andric     OS << "()";
27060b57cec5SDimitry Andric   } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
27070b57cec5SDimitry Andric     OS << '(';
27080b57cec5SDimitry Andric     for (BlockDecl::param_iterator AI = BD->param_begin(),
27090b57cec5SDimitry Andric          E = BD->param_end(); AI != E; ++AI) {
27100b57cec5SDimitry Andric       if (AI != BD->param_begin()) OS << ", ";
27110b57cec5SDimitry Andric       std::string ParamStr = (*AI)->getNameAsString();
27120b57cec5SDimitry Andric       (*AI)->getType().print(OS, Policy, ParamStr);
27130b57cec5SDimitry Andric     }
27140b57cec5SDimitry Andric 
27150b57cec5SDimitry Andric     const auto *FT = cast<FunctionProtoType>(AFT);
27160b57cec5SDimitry Andric     if (FT->isVariadic()) {
27170b57cec5SDimitry Andric       if (!BD->param_empty()) OS << ", ";
27180b57cec5SDimitry Andric       OS << "...";
27190b57cec5SDimitry Andric     }
27200b57cec5SDimitry Andric     OS << ')';
27210b57cec5SDimitry Andric   }
27220b57cec5SDimitry Andric   OS << "{ }";
27230b57cec5SDimitry Andric }
27240b57cec5SDimitry Andric 
27250b57cec5SDimitry Andric void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {
27260b57cec5SDimitry Andric   PrintExpr(Node->getSourceExpr());
27270b57cec5SDimitry Andric }
27280b57cec5SDimitry Andric 
27290b57cec5SDimitry Andric void StmtPrinter::VisitTypoExpr(TypoExpr *Node) {
27300b57cec5SDimitry Andric   // TODO: Print something reasonable for a TypoExpr, if necessary.
27310b57cec5SDimitry Andric   llvm_unreachable("Cannot print TypoExpr nodes");
27320b57cec5SDimitry Andric }
27330b57cec5SDimitry Andric 
27345ffd83dbSDimitry Andric void StmtPrinter::VisitRecoveryExpr(RecoveryExpr *Node) {
27355ffd83dbSDimitry Andric   OS << "<recovery-expr>(";
27365ffd83dbSDimitry Andric   const char *Sep = "";
27375ffd83dbSDimitry Andric   for (Expr *E : Node->subExpressions()) {
27385ffd83dbSDimitry Andric     OS << Sep;
27395ffd83dbSDimitry Andric     PrintExpr(E);
27405ffd83dbSDimitry Andric     Sep = ", ";
27415ffd83dbSDimitry Andric   }
27425ffd83dbSDimitry Andric   OS << ')';
27435ffd83dbSDimitry Andric }
27445ffd83dbSDimitry Andric 
27450b57cec5SDimitry Andric void StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) {
27460b57cec5SDimitry Andric   OS << "__builtin_astype(";
27470b57cec5SDimitry Andric   PrintExpr(Node->getSrcExpr());
27480b57cec5SDimitry Andric   OS << ", ";
27490b57cec5SDimitry Andric   Node->getType().print(OS, Policy);
27500b57cec5SDimitry Andric   OS << ")";
27510b57cec5SDimitry Andric }
27520b57cec5SDimitry Andric 
27530b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
27540b57cec5SDimitry Andric // Stmt method implementations
27550b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
27560b57cec5SDimitry Andric 
27570b57cec5SDimitry Andric void Stmt::dumpPretty(const ASTContext &Context) const {
27580b57cec5SDimitry Andric   printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts()));
27590b57cec5SDimitry Andric }
27600b57cec5SDimitry Andric 
27610b57cec5SDimitry Andric void Stmt::printPretty(raw_ostream &Out, PrinterHelper *Helper,
27620b57cec5SDimitry Andric                        const PrintingPolicy &Policy, unsigned Indentation,
27630b57cec5SDimitry Andric                        StringRef NL, const ASTContext *Context) const {
27640b57cec5SDimitry Andric   StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);
27650b57cec5SDimitry Andric   P.Visit(const_cast<Stmt *>(this));
27660b57cec5SDimitry Andric }
27670b57cec5SDimitry Andric 
2768349cc55cSDimitry Andric void Stmt::printPrettyControlled(raw_ostream &Out, PrinterHelper *Helper,
2769349cc55cSDimitry Andric                                  const PrintingPolicy &Policy,
2770349cc55cSDimitry Andric                                  unsigned Indentation, StringRef NL,
2771349cc55cSDimitry Andric                                  const ASTContext *Context) const {
2772349cc55cSDimitry Andric   StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);
2773349cc55cSDimitry Andric   P.PrintControlledStmt(const_cast<Stmt *>(this));
2774349cc55cSDimitry Andric }
2775349cc55cSDimitry Andric 
27760b57cec5SDimitry Andric void Stmt::printJson(raw_ostream &Out, PrinterHelper *Helper,
27770b57cec5SDimitry Andric                      const PrintingPolicy &Policy, bool AddQuotes) const {
27780b57cec5SDimitry Andric   std::string Buf;
27790b57cec5SDimitry Andric   llvm::raw_string_ostream TempOut(Buf);
27800b57cec5SDimitry Andric 
27810b57cec5SDimitry Andric   printPretty(TempOut, Helper, Policy);
27820b57cec5SDimitry Andric 
27830b57cec5SDimitry Andric   Out << JsonFormat(TempOut.str(), AddQuotes);
27840b57cec5SDimitry Andric }
27850b57cec5SDimitry Andric 
27860b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
27870b57cec5SDimitry Andric // PrinterHelper
27880b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
27890b57cec5SDimitry Andric 
27900b57cec5SDimitry Andric // Implement virtual destructor.
27910b57cec5SDimitry Andric PrinterHelper::~PrinterHelper() = default;
2792