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