xref: /netbsd-src/external/apache2/llvm/dist/clang/lib/AST/StmtPrinter.cpp (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
17330f729Sjoerg //===- StmtPrinter.cpp - Printing implementation for Stmt ASTs ------------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This file implements the Stmt::dumpPretty/Stmt::printPretty methods, which
107330f729Sjoerg // pretty print the AST back out to C code.
117330f729Sjoerg //
127330f729Sjoerg //===----------------------------------------------------------------------===//
137330f729Sjoerg 
147330f729Sjoerg #include "clang/AST/ASTContext.h"
157330f729Sjoerg #include "clang/AST/Attr.h"
167330f729Sjoerg #include "clang/AST/Decl.h"
177330f729Sjoerg #include "clang/AST/DeclBase.h"
187330f729Sjoerg #include "clang/AST/DeclCXX.h"
197330f729Sjoerg #include "clang/AST/DeclObjC.h"
207330f729Sjoerg #include "clang/AST/DeclOpenMP.h"
217330f729Sjoerg #include "clang/AST/DeclTemplate.h"
227330f729Sjoerg #include "clang/AST/Expr.h"
237330f729Sjoerg #include "clang/AST/ExprCXX.h"
247330f729Sjoerg #include "clang/AST/ExprObjC.h"
257330f729Sjoerg #include "clang/AST/ExprOpenMP.h"
267330f729Sjoerg #include "clang/AST/NestedNameSpecifier.h"
277330f729Sjoerg #include "clang/AST/OpenMPClause.h"
287330f729Sjoerg #include "clang/AST/PrettyPrinter.h"
297330f729Sjoerg #include "clang/AST/Stmt.h"
307330f729Sjoerg #include "clang/AST/StmtCXX.h"
317330f729Sjoerg #include "clang/AST/StmtObjC.h"
327330f729Sjoerg #include "clang/AST/StmtOpenMP.h"
337330f729Sjoerg #include "clang/AST/StmtVisitor.h"
347330f729Sjoerg #include "clang/AST/TemplateBase.h"
357330f729Sjoerg #include "clang/AST/Type.h"
367330f729Sjoerg #include "clang/Basic/CharInfo.h"
377330f729Sjoerg #include "clang/Basic/ExpressionTraits.h"
387330f729Sjoerg #include "clang/Basic/IdentifierTable.h"
397330f729Sjoerg #include "clang/Basic/JsonSupport.h"
407330f729Sjoerg #include "clang/Basic/LLVM.h"
417330f729Sjoerg #include "clang/Basic/Lambda.h"
427330f729Sjoerg #include "clang/Basic/OpenMPKinds.h"
437330f729Sjoerg #include "clang/Basic/OperatorKinds.h"
447330f729Sjoerg #include "clang/Basic/SourceLocation.h"
457330f729Sjoerg #include "clang/Basic/TypeTraits.h"
467330f729Sjoerg #include "clang/Lex/Lexer.h"
477330f729Sjoerg #include "llvm/ADT/ArrayRef.h"
487330f729Sjoerg #include "llvm/ADT/SmallString.h"
497330f729Sjoerg #include "llvm/ADT/SmallVector.h"
507330f729Sjoerg #include "llvm/ADT/StringRef.h"
517330f729Sjoerg #include "llvm/Support/Casting.h"
527330f729Sjoerg #include "llvm/Support/Compiler.h"
537330f729Sjoerg #include "llvm/Support/ErrorHandling.h"
547330f729Sjoerg #include "llvm/Support/raw_ostream.h"
557330f729Sjoerg #include <cassert>
567330f729Sjoerg #include <string>
577330f729Sjoerg 
587330f729Sjoerg using namespace clang;
597330f729Sjoerg 
607330f729Sjoerg //===----------------------------------------------------------------------===//
617330f729Sjoerg // StmtPrinter Visitor
627330f729Sjoerg //===----------------------------------------------------------------------===//
637330f729Sjoerg 
647330f729Sjoerg namespace {
657330f729Sjoerg 
667330f729Sjoerg   class StmtPrinter : public StmtVisitor<StmtPrinter> {
677330f729Sjoerg     raw_ostream &OS;
687330f729Sjoerg     unsigned IndentLevel;
697330f729Sjoerg     PrinterHelper* Helper;
707330f729Sjoerg     PrintingPolicy Policy;
717330f729Sjoerg     std::string NL;
727330f729Sjoerg     const ASTContext *Context;
737330f729Sjoerg 
747330f729Sjoerg   public:
StmtPrinter(raw_ostream & os,PrinterHelper * helper,const PrintingPolicy & Policy,unsigned Indentation=0,StringRef NL="\\n",const ASTContext * Context=nullptr)757330f729Sjoerg     StmtPrinter(raw_ostream &os, PrinterHelper *helper,
767330f729Sjoerg                 const PrintingPolicy &Policy, unsigned Indentation = 0,
77*e038c9c4Sjoerg                 StringRef NL = "\n", const ASTContext *Context = nullptr)
787330f729Sjoerg         : OS(os), IndentLevel(Indentation), Helper(helper), Policy(Policy),
797330f729Sjoerg           NL(NL), Context(Context) {}
807330f729Sjoerg 
PrintStmt(Stmt * S)81*e038c9c4Sjoerg     void PrintStmt(Stmt *S) { PrintStmt(S, Policy.Indentation); }
827330f729Sjoerg 
PrintStmt(Stmt * S,int SubIndent)837330f729Sjoerg     void PrintStmt(Stmt *S, int SubIndent) {
847330f729Sjoerg       IndentLevel += SubIndent;
857330f729Sjoerg       if (S && isa<Expr>(S)) {
867330f729Sjoerg         // If this is an expr used in a stmt context, indent and newline it.
877330f729Sjoerg         Indent();
887330f729Sjoerg         Visit(S);
897330f729Sjoerg         OS << ";" << NL;
907330f729Sjoerg       } else if (S) {
917330f729Sjoerg         Visit(S);
927330f729Sjoerg       } else {
937330f729Sjoerg         Indent() << "<<<NULL STATEMENT>>>" << NL;
947330f729Sjoerg       }
957330f729Sjoerg       IndentLevel -= SubIndent;
967330f729Sjoerg     }
977330f729Sjoerg 
PrintInitStmt(Stmt * S,unsigned PrefixWidth)987330f729Sjoerg     void PrintInitStmt(Stmt *S, unsigned PrefixWidth) {
997330f729Sjoerg       // FIXME: Cope better with odd prefix widths.
1007330f729Sjoerg       IndentLevel += (PrefixWidth + 1) / 2;
1017330f729Sjoerg       if (auto *DS = dyn_cast<DeclStmt>(S))
1027330f729Sjoerg         PrintRawDeclStmt(DS);
1037330f729Sjoerg       else
1047330f729Sjoerg         PrintExpr(cast<Expr>(S));
1057330f729Sjoerg       OS << "; ";
1067330f729Sjoerg       IndentLevel -= (PrefixWidth + 1) / 2;
1077330f729Sjoerg     }
1087330f729Sjoerg 
PrintControlledStmt(Stmt * S)1097330f729Sjoerg     void PrintControlledStmt(Stmt *S) {
1107330f729Sjoerg       if (auto *CS = dyn_cast<CompoundStmt>(S)) {
1117330f729Sjoerg         OS << " ";
1127330f729Sjoerg         PrintRawCompoundStmt(CS);
1137330f729Sjoerg         OS << NL;
1147330f729Sjoerg       } else {
1157330f729Sjoerg         OS << NL;
1167330f729Sjoerg         PrintStmt(S);
1177330f729Sjoerg       }
1187330f729Sjoerg     }
1197330f729Sjoerg 
1207330f729Sjoerg     void PrintRawCompoundStmt(CompoundStmt *S);
1217330f729Sjoerg     void PrintRawDecl(Decl *D);
1227330f729Sjoerg     void PrintRawDeclStmt(const DeclStmt *S);
1237330f729Sjoerg     void PrintRawIfStmt(IfStmt *If);
1247330f729Sjoerg     void PrintRawCXXCatchStmt(CXXCatchStmt *Catch);
1257330f729Sjoerg     void PrintCallArgs(CallExpr *E);
1267330f729Sjoerg     void PrintRawSEHExceptHandler(SEHExceptStmt *S);
1277330f729Sjoerg     void PrintRawSEHFinallyStmt(SEHFinallyStmt *S);
1287330f729Sjoerg     void PrintOMPExecutableDirective(OMPExecutableDirective *S,
1297330f729Sjoerg                                      bool ForceNoStmt = false);
1307330f729Sjoerg 
PrintExpr(Expr * E)1317330f729Sjoerg     void PrintExpr(Expr *E) {
1327330f729Sjoerg       if (E)
1337330f729Sjoerg         Visit(E);
1347330f729Sjoerg       else
1357330f729Sjoerg         OS << "<null expr>";
1367330f729Sjoerg     }
1377330f729Sjoerg 
Indent(int Delta=0)1387330f729Sjoerg     raw_ostream &Indent(int Delta = 0) {
1397330f729Sjoerg       for (int i = 0, e = IndentLevel+Delta; i < e; ++i)
1407330f729Sjoerg         OS << "  ";
1417330f729Sjoerg       return OS;
1427330f729Sjoerg     }
1437330f729Sjoerg 
Visit(Stmt * S)1447330f729Sjoerg     void Visit(Stmt* S) {
1457330f729Sjoerg       if (Helper && Helper->handledStmt(S,OS))
1467330f729Sjoerg           return;
1477330f729Sjoerg       else StmtVisitor<StmtPrinter>::Visit(S);
1487330f729Sjoerg     }
1497330f729Sjoerg 
VisitStmt(Stmt * Node)1507330f729Sjoerg     void VisitStmt(Stmt *Node) LLVM_ATTRIBUTE_UNUSED {
1517330f729Sjoerg       Indent() << "<<unknown stmt type>>" << NL;
1527330f729Sjoerg     }
1537330f729Sjoerg 
VisitExpr(Expr * Node)1547330f729Sjoerg     void VisitExpr(Expr *Node) LLVM_ATTRIBUTE_UNUSED {
1557330f729Sjoerg       OS << "<<unknown expr type>>";
1567330f729Sjoerg     }
1577330f729Sjoerg 
1587330f729Sjoerg     void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node);
1597330f729Sjoerg 
1607330f729Sjoerg #define ABSTRACT_STMT(CLASS)
1617330f729Sjoerg #define STMT(CLASS, PARENT) \
1627330f729Sjoerg     void Visit##CLASS(CLASS *Node);
1637330f729Sjoerg #include "clang/AST/StmtNodes.inc"
1647330f729Sjoerg   };
1657330f729Sjoerg 
1667330f729Sjoerg } // namespace
1677330f729Sjoerg 
1687330f729Sjoerg //===----------------------------------------------------------------------===//
1697330f729Sjoerg //  Stmt printing methods.
1707330f729Sjoerg //===----------------------------------------------------------------------===//
1717330f729Sjoerg 
1727330f729Sjoerg /// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and
1737330f729Sjoerg /// with no newline after the }.
PrintRawCompoundStmt(CompoundStmt * Node)1747330f729Sjoerg void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
1757330f729Sjoerg   OS << "{" << NL;
1767330f729Sjoerg   for (auto *I : Node->body())
1777330f729Sjoerg     PrintStmt(I);
1787330f729Sjoerg 
1797330f729Sjoerg   Indent() << "}";
1807330f729Sjoerg }
1817330f729Sjoerg 
PrintRawDecl(Decl * D)1827330f729Sjoerg void StmtPrinter::PrintRawDecl(Decl *D) {
1837330f729Sjoerg   D->print(OS, Policy, IndentLevel);
1847330f729Sjoerg }
1857330f729Sjoerg 
PrintRawDeclStmt(const DeclStmt * S)1867330f729Sjoerg void StmtPrinter::PrintRawDeclStmt(const DeclStmt *S) {
1877330f729Sjoerg   SmallVector<Decl *, 2> Decls(S->decls());
1887330f729Sjoerg   Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel);
1897330f729Sjoerg }
1907330f729Sjoerg 
VisitNullStmt(NullStmt * Node)1917330f729Sjoerg void StmtPrinter::VisitNullStmt(NullStmt *Node) {
1927330f729Sjoerg   Indent() << ";" << NL;
1937330f729Sjoerg }
1947330f729Sjoerg 
VisitDeclStmt(DeclStmt * Node)1957330f729Sjoerg void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
1967330f729Sjoerg   Indent();
1977330f729Sjoerg   PrintRawDeclStmt(Node);
1987330f729Sjoerg   OS << ";" << NL;
1997330f729Sjoerg }
2007330f729Sjoerg 
VisitCompoundStmt(CompoundStmt * Node)2017330f729Sjoerg void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
2027330f729Sjoerg   Indent();
2037330f729Sjoerg   PrintRawCompoundStmt(Node);
2047330f729Sjoerg   OS << "" << NL;
2057330f729Sjoerg }
2067330f729Sjoerg 
VisitCaseStmt(CaseStmt * Node)2077330f729Sjoerg void StmtPrinter::VisitCaseStmt(CaseStmt *Node) {
2087330f729Sjoerg   Indent(-1) << "case ";
2097330f729Sjoerg   PrintExpr(Node->getLHS());
2107330f729Sjoerg   if (Node->getRHS()) {
2117330f729Sjoerg     OS << " ... ";
2127330f729Sjoerg     PrintExpr(Node->getRHS());
2137330f729Sjoerg   }
2147330f729Sjoerg   OS << ":" << NL;
2157330f729Sjoerg 
2167330f729Sjoerg   PrintStmt(Node->getSubStmt(), 0);
2177330f729Sjoerg }
2187330f729Sjoerg 
VisitDefaultStmt(DefaultStmt * Node)2197330f729Sjoerg void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) {
2207330f729Sjoerg   Indent(-1) << "default:" << NL;
2217330f729Sjoerg   PrintStmt(Node->getSubStmt(), 0);
2227330f729Sjoerg }
2237330f729Sjoerg 
VisitLabelStmt(LabelStmt * Node)2247330f729Sjoerg void StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
2257330f729Sjoerg   Indent(-1) << Node->getName() << ":" << NL;
2267330f729Sjoerg   PrintStmt(Node->getSubStmt(), 0);
2277330f729Sjoerg }
2287330f729Sjoerg 
VisitAttributedStmt(AttributedStmt * Node)2297330f729Sjoerg void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) {
2307330f729Sjoerg   for (const auto *Attr : Node->getAttrs()) {
2317330f729Sjoerg     Attr->printPretty(OS, Policy);
2327330f729Sjoerg   }
2337330f729Sjoerg 
2347330f729Sjoerg   PrintStmt(Node->getSubStmt(), 0);
2357330f729Sjoerg }
2367330f729Sjoerg 
PrintRawIfStmt(IfStmt * If)2377330f729Sjoerg void StmtPrinter::PrintRawIfStmt(IfStmt *If) {
2387330f729Sjoerg   OS << "if (";
2397330f729Sjoerg   if (If->getInit())
2407330f729Sjoerg     PrintInitStmt(If->getInit(), 4);
2417330f729Sjoerg   if (const DeclStmt *DS = If->getConditionVariableDeclStmt())
2427330f729Sjoerg     PrintRawDeclStmt(DS);
2437330f729Sjoerg   else
2447330f729Sjoerg     PrintExpr(If->getCond());
2457330f729Sjoerg   OS << ')';
2467330f729Sjoerg 
2477330f729Sjoerg   if (auto *CS = dyn_cast<CompoundStmt>(If->getThen())) {
2487330f729Sjoerg     OS << ' ';
2497330f729Sjoerg     PrintRawCompoundStmt(CS);
2507330f729Sjoerg     OS << (If->getElse() ? " " : NL);
2517330f729Sjoerg   } else {
2527330f729Sjoerg     OS << NL;
2537330f729Sjoerg     PrintStmt(If->getThen());
2547330f729Sjoerg     if (If->getElse()) Indent();
2557330f729Sjoerg   }
2567330f729Sjoerg 
2577330f729Sjoerg   if (Stmt *Else = If->getElse()) {
2587330f729Sjoerg     OS << "else";
2597330f729Sjoerg 
2607330f729Sjoerg     if (auto *CS = dyn_cast<CompoundStmt>(Else)) {
2617330f729Sjoerg       OS << ' ';
2627330f729Sjoerg       PrintRawCompoundStmt(CS);
2637330f729Sjoerg       OS << NL;
2647330f729Sjoerg     } else if (auto *ElseIf = dyn_cast<IfStmt>(Else)) {
2657330f729Sjoerg       OS << ' ';
2667330f729Sjoerg       PrintRawIfStmt(ElseIf);
2677330f729Sjoerg     } else {
2687330f729Sjoerg       OS << NL;
2697330f729Sjoerg       PrintStmt(If->getElse());
2707330f729Sjoerg     }
2717330f729Sjoerg   }
2727330f729Sjoerg }
2737330f729Sjoerg 
VisitIfStmt(IfStmt * If)2747330f729Sjoerg void StmtPrinter::VisitIfStmt(IfStmt *If) {
2757330f729Sjoerg   Indent();
2767330f729Sjoerg   PrintRawIfStmt(If);
2777330f729Sjoerg }
2787330f729Sjoerg 
VisitSwitchStmt(SwitchStmt * Node)2797330f729Sjoerg void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) {
2807330f729Sjoerg   Indent() << "switch (";
2817330f729Sjoerg   if (Node->getInit())
2827330f729Sjoerg     PrintInitStmt(Node->getInit(), 8);
2837330f729Sjoerg   if (const DeclStmt *DS = Node->getConditionVariableDeclStmt())
2847330f729Sjoerg     PrintRawDeclStmt(DS);
2857330f729Sjoerg   else
2867330f729Sjoerg     PrintExpr(Node->getCond());
2877330f729Sjoerg   OS << ")";
2887330f729Sjoerg   PrintControlledStmt(Node->getBody());
2897330f729Sjoerg }
2907330f729Sjoerg 
VisitWhileStmt(WhileStmt * Node)2917330f729Sjoerg void StmtPrinter::VisitWhileStmt(WhileStmt *Node) {
2927330f729Sjoerg   Indent() << "while (";
2937330f729Sjoerg   if (const DeclStmt *DS = Node->getConditionVariableDeclStmt())
2947330f729Sjoerg     PrintRawDeclStmt(DS);
2957330f729Sjoerg   else
2967330f729Sjoerg     PrintExpr(Node->getCond());
2977330f729Sjoerg   OS << ")" << NL;
2987330f729Sjoerg   PrintStmt(Node->getBody());
2997330f729Sjoerg }
3007330f729Sjoerg 
VisitDoStmt(DoStmt * Node)3017330f729Sjoerg void StmtPrinter::VisitDoStmt(DoStmt *Node) {
3027330f729Sjoerg   Indent() << "do ";
3037330f729Sjoerg   if (auto *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
3047330f729Sjoerg     PrintRawCompoundStmt(CS);
3057330f729Sjoerg     OS << " ";
3067330f729Sjoerg   } else {
3077330f729Sjoerg     OS << NL;
3087330f729Sjoerg     PrintStmt(Node->getBody());
3097330f729Sjoerg     Indent();
3107330f729Sjoerg   }
3117330f729Sjoerg 
3127330f729Sjoerg   OS << "while (";
3137330f729Sjoerg   PrintExpr(Node->getCond());
3147330f729Sjoerg   OS << ");" << NL;
3157330f729Sjoerg }
3167330f729Sjoerg 
VisitForStmt(ForStmt * Node)3177330f729Sjoerg void StmtPrinter::VisitForStmt(ForStmt *Node) {
3187330f729Sjoerg   Indent() << "for (";
3197330f729Sjoerg   if (Node->getInit())
3207330f729Sjoerg     PrintInitStmt(Node->getInit(), 5);
3217330f729Sjoerg   else
3227330f729Sjoerg     OS << (Node->getCond() ? "; " : ";");
3237330f729Sjoerg   if (Node->getCond())
3247330f729Sjoerg     PrintExpr(Node->getCond());
3257330f729Sjoerg   OS << ";";
3267330f729Sjoerg   if (Node->getInc()) {
3277330f729Sjoerg     OS << " ";
3287330f729Sjoerg     PrintExpr(Node->getInc());
3297330f729Sjoerg   }
3307330f729Sjoerg   OS << ")";
3317330f729Sjoerg   PrintControlledStmt(Node->getBody());
3327330f729Sjoerg }
3337330f729Sjoerg 
VisitObjCForCollectionStmt(ObjCForCollectionStmt * Node)3347330f729Sjoerg void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) {
3357330f729Sjoerg   Indent() << "for (";
3367330f729Sjoerg   if (auto *DS = dyn_cast<DeclStmt>(Node->getElement()))
3377330f729Sjoerg     PrintRawDeclStmt(DS);
3387330f729Sjoerg   else
3397330f729Sjoerg     PrintExpr(cast<Expr>(Node->getElement()));
3407330f729Sjoerg   OS << " in ";
3417330f729Sjoerg   PrintExpr(Node->getCollection());
3427330f729Sjoerg   OS << ")";
3437330f729Sjoerg   PrintControlledStmt(Node->getBody());
3447330f729Sjoerg }
3457330f729Sjoerg 
VisitCXXForRangeStmt(CXXForRangeStmt * Node)3467330f729Sjoerg void StmtPrinter::VisitCXXForRangeStmt(CXXForRangeStmt *Node) {
3477330f729Sjoerg   Indent() << "for (";
3487330f729Sjoerg   if (Node->getInit())
3497330f729Sjoerg     PrintInitStmt(Node->getInit(), 5);
3507330f729Sjoerg   PrintingPolicy SubPolicy(Policy);
3517330f729Sjoerg   SubPolicy.SuppressInitializers = true;
3527330f729Sjoerg   Node->getLoopVariable()->print(OS, SubPolicy, IndentLevel);
3537330f729Sjoerg   OS << " : ";
3547330f729Sjoerg   PrintExpr(Node->getRangeInit());
3557330f729Sjoerg   OS << ")";
3567330f729Sjoerg   PrintControlledStmt(Node->getBody());
3577330f729Sjoerg }
3587330f729Sjoerg 
VisitMSDependentExistsStmt(MSDependentExistsStmt * Node)3597330f729Sjoerg void StmtPrinter::VisitMSDependentExistsStmt(MSDependentExistsStmt *Node) {
3607330f729Sjoerg   Indent();
3617330f729Sjoerg   if (Node->isIfExists())
3627330f729Sjoerg     OS << "__if_exists (";
3637330f729Sjoerg   else
3647330f729Sjoerg     OS << "__if_not_exists (";
3657330f729Sjoerg 
3667330f729Sjoerg   if (NestedNameSpecifier *Qualifier
3677330f729Sjoerg         = Node->getQualifierLoc().getNestedNameSpecifier())
3687330f729Sjoerg     Qualifier->print(OS, Policy);
3697330f729Sjoerg 
3707330f729Sjoerg   OS << Node->getNameInfo() << ") ";
3717330f729Sjoerg 
3727330f729Sjoerg   PrintRawCompoundStmt(Node->getSubStmt());
3737330f729Sjoerg }
3747330f729Sjoerg 
VisitGotoStmt(GotoStmt * Node)3757330f729Sjoerg void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
3767330f729Sjoerg   Indent() << "goto " << Node->getLabel()->getName() << ";";
3777330f729Sjoerg   if (Policy.IncludeNewlines) OS << NL;
3787330f729Sjoerg }
3797330f729Sjoerg 
VisitIndirectGotoStmt(IndirectGotoStmt * Node)3807330f729Sjoerg void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
3817330f729Sjoerg   Indent() << "goto *";
3827330f729Sjoerg   PrintExpr(Node->getTarget());
3837330f729Sjoerg   OS << ";";
3847330f729Sjoerg   if (Policy.IncludeNewlines) OS << NL;
3857330f729Sjoerg }
3867330f729Sjoerg 
VisitContinueStmt(ContinueStmt * Node)3877330f729Sjoerg void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
3887330f729Sjoerg   Indent() << "continue;";
3897330f729Sjoerg   if (Policy.IncludeNewlines) OS << NL;
3907330f729Sjoerg }
3917330f729Sjoerg 
VisitBreakStmt(BreakStmt * Node)3927330f729Sjoerg void StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
3937330f729Sjoerg   Indent() << "break;";
3947330f729Sjoerg   if (Policy.IncludeNewlines) OS << NL;
3957330f729Sjoerg }
3967330f729Sjoerg 
VisitReturnStmt(ReturnStmt * Node)3977330f729Sjoerg void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
3987330f729Sjoerg   Indent() << "return";
3997330f729Sjoerg   if (Node->getRetValue()) {
4007330f729Sjoerg     OS << " ";
4017330f729Sjoerg     PrintExpr(Node->getRetValue());
4027330f729Sjoerg   }
4037330f729Sjoerg   OS << ";";
4047330f729Sjoerg   if (Policy.IncludeNewlines) OS << NL;
4057330f729Sjoerg }
4067330f729Sjoerg 
VisitGCCAsmStmt(GCCAsmStmt * Node)4077330f729Sjoerg void StmtPrinter::VisitGCCAsmStmt(GCCAsmStmt *Node) {
4087330f729Sjoerg   Indent() << "asm ";
4097330f729Sjoerg 
4107330f729Sjoerg   if (Node->isVolatile())
4117330f729Sjoerg     OS << "volatile ";
4127330f729Sjoerg 
4137330f729Sjoerg   if (Node->isAsmGoto())
4147330f729Sjoerg     OS << "goto ";
4157330f729Sjoerg 
4167330f729Sjoerg   OS << "(";
4177330f729Sjoerg   VisitStringLiteral(Node->getAsmString());
4187330f729Sjoerg 
4197330f729Sjoerg   // Outputs
4207330f729Sjoerg   if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 ||
4217330f729Sjoerg       Node->getNumClobbers() != 0 || Node->getNumLabels() != 0)
4227330f729Sjoerg     OS << " : ";
4237330f729Sjoerg 
4247330f729Sjoerg   for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) {
4257330f729Sjoerg     if (i != 0)
4267330f729Sjoerg       OS << ", ";
4277330f729Sjoerg 
4287330f729Sjoerg     if (!Node->getOutputName(i).empty()) {
4297330f729Sjoerg       OS << '[';
4307330f729Sjoerg       OS << Node->getOutputName(i);
4317330f729Sjoerg       OS << "] ";
4327330f729Sjoerg     }
4337330f729Sjoerg 
4347330f729Sjoerg     VisitStringLiteral(Node->getOutputConstraintLiteral(i));
4357330f729Sjoerg     OS << " (";
4367330f729Sjoerg     Visit(Node->getOutputExpr(i));
4377330f729Sjoerg     OS << ")";
4387330f729Sjoerg   }
4397330f729Sjoerg 
4407330f729Sjoerg   // Inputs
4417330f729Sjoerg   if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0 ||
4427330f729Sjoerg       Node->getNumLabels() != 0)
4437330f729Sjoerg     OS << " : ";
4447330f729Sjoerg 
4457330f729Sjoerg   for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) {
4467330f729Sjoerg     if (i != 0)
4477330f729Sjoerg       OS << ", ";
4487330f729Sjoerg 
4497330f729Sjoerg     if (!Node->getInputName(i).empty()) {
4507330f729Sjoerg       OS << '[';
4517330f729Sjoerg       OS << Node->getInputName(i);
4527330f729Sjoerg       OS << "] ";
4537330f729Sjoerg     }
4547330f729Sjoerg 
4557330f729Sjoerg     VisitStringLiteral(Node->getInputConstraintLiteral(i));
4567330f729Sjoerg     OS << " (";
4577330f729Sjoerg     Visit(Node->getInputExpr(i));
4587330f729Sjoerg     OS << ")";
4597330f729Sjoerg   }
4607330f729Sjoerg 
4617330f729Sjoerg   // Clobbers
4627330f729Sjoerg   if (Node->getNumClobbers() != 0 || Node->getNumLabels())
4637330f729Sjoerg     OS << " : ";
4647330f729Sjoerg 
4657330f729Sjoerg   for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) {
4667330f729Sjoerg     if (i != 0)
4677330f729Sjoerg       OS << ", ";
4687330f729Sjoerg 
4697330f729Sjoerg     VisitStringLiteral(Node->getClobberStringLiteral(i));
4707330f729Sjoerg   }
4717330f729Sjoerg 
4727330f729Sjoerg   // Labels
4737330f729Sjoerg   if (Node->getNumLabels() != 0)
4747330f729Sjoerg     OS << " : ";
4757330f729Sjoerg 
4767330f729Sjoerg   for (unsigned i = 0, e = Node->getNumLabels(); i != e; ++i) {
4777330f729Sjoerg     if (i != 0)
4787330f729Sjoerg       OS << ", ";
4797330f729Sjoerg     OS << Node->getLabelName(i);
4807330f729Sjoerg   }
4817330f729Sjoerg 
4827330f729Sjoerg   OS << ");";
4837330f729Sjoerg   if (Policy.IncludeNewlines) OS << NL;
4847330f729Sjoerg }
4857330f729Sjoerg 
VisitMSAsmStmt(MSAsmStmt * Node)4867330f729Sjoerg void StmtPrinter::VisitMSAsmStmt(MSAsmStmt *Node) {
4877330f729Sjoerg   // FIXME: Implement MS style inline asm statement printer.
4887330f729Sjoerg   Indent() << "__asm ";
4897330f729Sjoerg   if (Node->hasBraces())
4907330f729Sjoerg     OS << "{" << NL;
4917330f729Sjoerg   OS << Node->getAsmString() << NL;
4927330f729Sjoerg   if (Node->hasBraces())
4937330f729Sjoerg     Indent() << "}" << NL;
4947330f729Sjoerg }
4957330f729Sjoerg 
VisitCapturedStmt(CapturedStmt * Node)4967330f729Sjoerg void StmtPrinter::VisitCapturedStmt(CapturedStmt *Node) {
4977330f729Sjoerg   PrintStmt(Node->getCapturedDecl()->getBody());
4987330f729Sjoerg }
4997330f729Sjoerg 
VisitObjCAtTryStmt(ObjCAtTryStmt * Node)5007330f729Sjoerg void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) {
5017330f729Sjoerg   Indent() << "@try";
5027330f729Sjoerg   if (auto *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) {
5037330f729Sjoerg     PrintRawCompoundStmt(TS);
5047330f729Sjoerg     OS << NL;
5057330f729Sjoerg   }
5067330f729Sjoerg 
5077330f729Sjoerg   for (unsigned I = 0, N = Node->getNumCatchStmts(); I != N; ++I) {
5087330f729Sjoerg     ObjCAtCatchStmt *catchStmt = Node->getCatchStmt(I);
5097330f729Sjoerg     Indent() << "@catch(";
5107330f729Sjoerg     if (catchStmt->getCatchParamDecl()) {
5117330f729Sjoerg       if (Decl *DS = catchStmt->getCatchParamDecl())
5127330f729Sjoerg         PrintRawDecl(DS);
5137330f729Sjoerg     }
5147330f729Sjoerg     OS << ")";
5157330f729Sjoerg     if (auto *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) {
5167330f729Sjoerg       PrintRawCompoundStmt(CS);
5177330f729Sjoerg       OS << NL;
5187330f729Sjoerg     }
5197330f729Sjoerg   }
5207330f729Sjoerg 
5217330f729Sjoerg   if (auto *FS = static_cast<ObjCAtFinallyStmt *>(Node->getFinallyStmt())) {
5227330f729Sjoerg     Indent() << "@finally";
5237330f729Sjoerg     PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody()));
5247330f729Sjoerg     OS << NL;
5257330f729Sjoerg   }
5267330f729Sjoerg }
5277330f729Sjoerg 
VisitObjCAtFinallyStmt(ObjCAtFinallyStmt * Node)5287330f729Sjoerg void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) {
5297330f729Sjoerg }
5307330f729Sjoerg 
VisitObjCAtCatchStmt(ObjCAtCatchStmt * Node)5317330f729Sjoerg void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) {
5327330f729Sjoerg   Indent() << "@catch (...) { /* todo */ } " << NL;
5337330f729Sjoerg }
5347330f729Sjoerg 
VisitObjCAtThrowStmt(ObjCAtThrowStmt * Node)5357330f729Sjoerg void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) {
5367330f729Sjoerg   Indent() << "@throw";
5377330f729Sjoerg   if (Node->getThrowExpr()) {
5387330f729Sjoerg     OS << " ";
5397330f729Sjoerg     PrintExpr(Node->getThrowExpr());
5407330f729Sjoerg   }
5417330f729Sjoerg   OS << ";" << NL;
5427330f729Sjoerg }
5437330f729Sjoerg 
VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr * Node)5447330f729Sjoerg void StmtPrinter::VisitObjCAvailabilityCheckExpr(
5457330f729Sjoerg     ObjCAvailabilityCheckExpr *Node) {
5467330f729Sjoerg   OS << "@available(...)";
5477330f729Sjoerg }
5487330f729Sjoerg 
VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt * Node)5497330f729Sjoerg void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) {
5507330f729Sjoerg   Indent() << "@synchronized (";
5517330f729Sjoerg   PrintExpr(Node->getSynchExpr());
5527330f729Sjoerg   OS << ")";
5537330f729Sjoerg   PrintRawCompoundStmt(Node->getSynchBody());
5547330f729Sjoerg   OS << NL;
5557330f729Sjoerg }
5567330f729Sjoerg 
VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt * Node)5577330f729Sjoerg void StmtPrinter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *Node) {
5587330f729Sjoerg   Indent() << "@autoreleasepool";
5597330f729Sjoerg   PrintRawCompoundStmt(dyn_cast<CompoundStmt>(Node->getSubStmt()));
5607330f729Sjoerg   OS << NL;
5617330f729Sjoerg }
5627330f729Sjoerg 
PrintRawCXXCatchStmt(CXXCatchStmt * Node)5637330f729Sjoerg void StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) {
5647330f729Sjoerg   OS << "catch (";
5657330f729Sjoerg   if (Decl *ExDecl = Node->getExceptionDecl())
5667330f729Sjoerg     PrintRawDecl(ExDecl);
5677330f729Sjoerg   else
5687330f729Sjoerg     OS << "...";
5697330f729Sjoerg   OS << ") ";
5707330f729Sjoerg   PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock()));
5717330f729Sjoerg }
5727330f729Sjoerg 
VisitCXXCatchStmt(CXXCatchStmt * Node)5737330f729Sjoerg void StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) {
5747330f729Sjoerg   Indent();
5757330f729Sjoerg   PrintRawCXXCatchStmt(Node);
5767330f729Sjoerg   OS << NL;
5777330f729Sjoerg }
5787330f729Sjoerg 
VisitCXXTryStmt(CXXTryStmt * Node)5797330f729Sjoerg void StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) {
5807330f729Sjoerg   Indent() << "try ";
5817330f729Sjoerg   PrintRawCompoundStmt(Node->getTryBlock());
5827330f729Sjoerg   for (unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) {
5837330f729Sjoerg     OS << " ";
5847330f729Sjoerg     PrintRawCXXCatchStmt(Node->getHandler(i));
5857330f729Sjoerg   }
5867330f729Sjoerg   OS << NL;
5877330f729Sjoerg }
5887330f729Sjoerg 
VisitSEHTryStmt(SEHTryStmt * Node)5897330f729Sjoerg void StmtPrinter::VisitSEHTryStmt(SEHTryStmt *Node) {
5907330f729Sjoerg   Indent() << (Node->getIsCXXTry() ? "try " : "__try ");
5917330f729Sjoerg   PrintRawCompoundStmt(Node->getTryBlock());
5927330f729Sjoerg   SEHExceptStmt *E = Node->getExceptHandler();
5937330f729Sjoerg   SEHFinallyStmt *F = Node->getFinallyHandler();
5947330f729Sjoerg   if(E)
5957330f729Sjoerg     PrintRawSEHExceptHandler(E);
5967330f729Sjoerg   else {
5977330f729Sjoerg     assert(F && "Must have a finally block...");
5987330f729Sjoerg     PrintRawSEHFinallyStmt(F);
5997330f729Sjoerg   }
6007330f729Sjoerg   OS << NL;
6017330f729Sjoerg }
6027330f729Sjoerg 
PrintRawSEHFinallyStmt(SEHFinallyStmt * Node)6037330f729Sjoerg void StmtPrinter::PrintRawSEHFinallyStmt(SEHFinallyStmt *Node) {
6047330f729Sjoerg   OS << "__finally ";
6057330f729Sjoerg   PrintRawCompoundStmt(Node->getBlock());
6067330f729Sjoerg   OS << NL;
6077330f729Sjoerg }
6087330f729Sjoerg 
PrintRawSEHExceptHandler(SEHExceptStmt * Node)6097330f729Sjoerg void StmtPrinter::PrintRawSEHExceptHandler(SEHExceptStmt *Node) {
6107330f729Sjoerg   OS << "__except (";
6117330f729Sjoerg   VisitExpr(Node->getFilterExpr());
6127330f729Sjoerg   OS << ")" << NL;
6137330f729Sjoerg   PrintRawCompoundStmt(Node->getBlock());
6147330f729Sjoerg   OS << NL;
6157330f729Sjoerg }
6167330f729Sjoerg 
VisitSEHExceptStmt(SEHExceptStmt * Node)6177330f729Sjoerg void StmtPrinter::VisitSEHExceptStmt(SEHExceptStmt *Node) {
6187330f729Sjoerg   Indent();
6197330f729Sjoerg   PrintRawSEHExceptHandler(Node);
6207330f729Sjoerg   OS << NL;
6217330f729Sjoerg }
6227330f729Sjoerg 
VisitSEHFinallyStmt(SEHFinallyStmt * Node)6237330f729Sjoerg void StmtPrinter::VisitSEHFinallyStmt(SEHFinallyStmt *Node) {
6247330f729Sjoerg   Indent();
6257330f729Sjoerg   PrintRawSEHFinallyStmt(Node);
6267330f729Sjoerg   OS << NL;
6277330f729Sjoerg }
6287330f729Sjoerg 
VisitSEHLeaveStmt(SEHLeaveStmt * Node)6297330f729Sjoerg void StmtPrinter::VisitSEHLeaveStmt(SEHLeaveStmt *Node) {
6307330f729Sjoerg   Indent() << "__leave;";
6317330f729Sjoerg   if (Policy.IncludeNewlines) OS << NL;
6327330f729Sjoerg }
6337330f729Sjoerg 
6347330f729Sjoerg //===----------------------------------------------------------------------===//
6357330f729Sjoerg //  OpenMP directives printing methods
6367330f729Sjoerg //===----------------------------------------------------------------------===//
6377330f729Sjoerg 
VisitOMPCanonicalLoop(OMPCanonicalLoop * Node)638*e038c9c4Sjoerg void StmtPrinter::VisitOMPCanonicalLoop(OMPCanonicalLoop *Node) {
639*e038c9c4Sjoerg   PrintStmt(Node->getLoopStmt());
640*e038c9c4Sjoerg }
641*e038c9c4Sjoerg 
PrintOMPExecutableDirective(OMPExecutableDirective * S,bool ForceNoStmt)6427330f729Sjoerg void StmtPrinter::PrintOMPExecutableDirective(OMPExecutableDirective *S,
6437330f729Sjoerg                                               bool ForceNoStmt) {
6447330f729Sjoerg   OMPClausePrinter Printer(OS, Policy);
6457330f729Sjoerg   ArrayRef<OMPClause *> Clauses = S->clauses();
6467330f729Sjoerg   for (auto *Clause : Clauses)
6477330f729Sjoerg     if (Clause && !Clause->isImplicit()) {
6487330f729Sjoerg       OS << ' ';
6497330f729Sjoerg       Printer.Visit(Clause);
6507330f729Sjoerg     }
6517330f729Sjoerg   OS << NL;
6527330f729Sjoerg   if (!ForceNoStmt && S->hasAssociatedStmt())
653*e038c9c4Sjoerg     PrintStmt(S->getRawStmt());
6547330f729Sjoerg }
6557330f729Sjoerg 
VisitOMPParallelDirective(OMPParallelDirective * Node)6567330f729Sjoerg void StmtPrinter::VisitOMPParallelDirective(OMPParallelDirective *Node) {
6577330f729Sjoerg   Indent() << "#pragma omp parallel";
6587330f729Sjoerg   PrintOMPExecutableDirective(Node);
6597330f729Sjoerg }
6607330f729Sjoerg 
VisitOMPSimdDirective(OMPSimdDirective * Node)6617330f729Sjoerg void StmtPrinter::VisitOMPSimdDirective(OMPSimdDirective *Node) {
6627330f729Sjoerg   Indent() << "#pragma omp simd";
6637330f729Sjoerg   PrintOMPExecutableDirective(Node);
6647330f729Sjoerg }
6657330f729Sjoerg 
VisitOMPTileDirective(OMPTileDirective * Node)666*e038c9c4Sjoerg void StmtPrinter::VisitOMPTileDirective(OMPTileDirective *Node) {
667*e038c9c4Sjoerg   Indent() << "#pragma omp tile";
668*e038c9c4Sjoerg   PrintOMPExecutableDirective(Node);
669*e038c9c4Sjoerg }
670*e038c9c4Sjoerg 
VisitOMPForDirective(OMPForDirective * Node)6717330f729Sjoerg void StmtPrinter::VisitOMPForDirective(OMPForDirective *Node) {
6727330f729Sjoerg   Indent() << "#pragma omp for";
6737330f729Sjoerg   PrintOMPExecutableDirective(Node);
6747330f729Sjoerg }
6757330f729Sjoerg 
VisitOMPForSimdDirective(OMPForSimdDirective * Node)6767330f729Sjoerg void StmtPrinter::VisitOMPForSimdDirective(OMPForSimdDirective *Node) {
6777330f729Sjoerg   Indent() << "#pragma omp for simd";
6787330f729Sjoerg   PrintOMPExecutableDirective(Node);
6797330f729Sjoerg }
6807330f729Sjoerg 
VisitOMPSectionsDirective(OMPSectionsDirective * Node)6817330f729Sjoerg void StmtPrinter::VisitOMPSectionsDirective(OMPSectionsDirective *Node) {
6827330f729Sjoerg   Indent() << "#pragma omp sections";
6837330f729Sjoerg   PrintOMPExecutableDirective(Node);
6847330f729Sjoerg }
6857330f729Sjoerg 
VisitOMPSectionDirective(OMPSectionDirective * Node)6867330f729Sjoerg void StmtPrinter::VisitOMPSectionDirective(OMPSectionDirective *Node) {
6877330f729Sjoerg   Indent() << "#pragma omp section";
6887330f729Sjoerg   PrintOMPExecutableDirective(Node);
6897330f729Sjoerg }
6907330f729Sjoerg 
VisitOMPSingleDirective(OMPSingleDirective * Node)6917330f729Sjoerg void StmtPrinter::VisitOMPSingleDirective(OMPSingleDirective *Node) {
6927330f729Sjoerg   Indent() << "#pragma omp single";
6937330f729Sjoerg   PrintOMPExecutableDirective(Node);
6947330f729Sjoerg }
6957330f729Sjoerg 
VisitOMPMasterDirective(OMPMasterDirective * Node)6967330f729Sjoerg void StmtPrinter::VisitOMPMasterDirective(OMPMasterDirective *Node) {
6977330f729Sjoerg   Indent() << "#pragma omp master";
6987330f729Sjoerg   PrintOMPExecutableDirective(Node);
6997330f729Sjoerg }
7007330f729Sjoerg 
VisitOMPCriticalDirective(OMPCriticalDirective * Node)7017330f729Sjoerg void StmtPrinter::VisitOMPCriticalDirective(OMPCriticalDirective *Node) {
7027330f729Sjoerg   Indent() << "#pragma omp critical";
7037330f729Sjoerg   if (Node->getDirectiveName().getName()) {
7047330f729Sjoerg     OS << " (";
705*e038c9c4Sjoerg     Node->getDirectiveName().printName(OS, Policy);
7067330f729Sjoerg     OS << ")";
7077330f729Sjoerg   }
7087330f729Sjoerg   PrintOMPExecutableDirective(Node);
7097330f729Sjoerg }
7107330f729Sjoerg 
VisitOMPParallelForDirective(OMPParallelForDirective * Node)7117330f729Sjoerg void StmtPrinter::VisitOMPParallelForDirective(OMPParallelForDirective *Node) {
7127330f729Sjoerg   Indent() << "#pragma omp parallel for";
7137330f729Sjoerg   PrintOMPExecutableDirective(Node);
7147330f729Sjoerg }
7157330f729Sjoerg 
VisitOMPParallelForSimdDirective(OMPParallelForSimdDirective * Node)7167330f729Sjoerg void StmtPrinter::VisitOMPParallelForSimdDirective(
7177330f729Sjoerg     OMPParallelForSimdDirective *Node) {
7187330f729Sjoerg   Indent() << "#pragma omp parallel for simd";
7197330f729Sjoerg   PrintOMPExecutableDirective(Node);
7207330f729Sjoerg }
7217330f729Sjoerg 
VisitOMPParallelMasterDirective(OMPParallelMasterDirective * Node)722*e038c9c4Sjoerg void StmtPrinter::VisitOMPParallelMasterDirective(
723*e038c9c4Sjoerg     OMPParallelMasterDirective *Node) {
724*e038c9c4Sjoerg   Indent() << "#pragma omp parallel master";
725*e038c9c4Sjoerg   PrintOMPExecutableDirective(Node);
726*e038c9c4Sjoerg }
727*e038c9c4Sjoerg 
VisitOMPParallelSectionsDirective(OMPParallelSectionsDirective * Node)7287330f729Sjoerg void StmtPrinter::VisitOMPParallelSectionsDirective(
7297330f729Sjoerg     OMPParallelSectionsDirective *Node) {
7307330f729Sjoerg   Indent() << "#pragma omp parallel sections";
7317330f729Sjoerg   PrintOMPExecutableDirective(Node);
7327330f729Sjoerg }
7337330f729Sjoerg 
VisitOMPTaskDirective(OMPTaskDirective * Node)7347330f729Sjoerg void StmtPrinter::VisitOMPTaskDirective(OMPTaskDirective *Node) {
7357330f729Sjoerg   Indent() << "#pragma omp task";
7367330f729Sjoerg   PrintOMPExecutableDirective(Node);
7377330f729Sjoerg }
7387330f729Sjoerg 
VisitOMPTaskyieldDirective(OMPTaskyieldDirective * Node)7397330f729Sjoerg void StmtPrinter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *Node) {
7407330f729Sjoerg   Indent() << "#pragma omp taskyield";
7417330f729Sjoerg   PrintOMPExecutableDirective(Node);
7427330f729Sjoerg }
7437330f729Sjoerg 
VisitOMPBarrierDirective(OMPBarrierDirective * Node)7447330f729Sjoerg void StmtPrinter::VisitOMPBarrierDirective(OMPBarrierDirective *Node) {
7457330f729Sjoerg   Indent() << "#pragma omp barrier";
7467330f729Sjoerg   PrintOMPExecutableDirective(Node);
7477330f729Sjoerg }
7487330f729Sjoerg 
VisitOMPTaskwaitDirective(OMPTaskwaitDirective * Node)7497330f729Sjoerg void StmtPrinter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *Node) {
7507330f729Sjoerg   Indent() << "#pragma omp taskwait";
7517330f729Sjoerg   PrintOMPExecutableDirective(Node);
7527330f729Sjoerg }
7537330f729Sjoerg 
VisitOMPTaskgroupDirective(OMPTaskgroupDirective * Node)7547330f729Sjoerg void StmtPrinter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *Node) {
7557330f729Sjoerg   Indent() << "#pragma omp taskgroup";
7567330f729Sjoerg   PrintOMPExecutableDirective(Node);
7577330f729Sjoerg }
7587330f729Sjoerg 
VisitOMPFlushDirective(OMPFlushDirective * Node)7597330f729Sjoerg void StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) {
7607330f729Sjoerg   Indent() << "#pragma omp flush";
7617330f729Sjoerg   PrintOMPExecutableDirective(Node);
7627330f729Sjoerg }
7637330f729Sjoerg 
VisitOMPDepobjDirective(OMPDepobjDirective * Node)764*e038c9c4Sjoerg void StmtPrinter::VisitOMPDepobjDirective(OMPDepobjDirective *Node) {
765*e038c9c4Sjoerg   Indent() << "#pragma omp depobj";
766*e038c9c4Sjoerg   PrintOMPExecutableDirective(Node);
767*e038c9c4Sjoerg }
768*e038c9c4Sjoerg 
VisitOMPScanDirective(OMPScanDirective * Node)769*e038c9c4Sjoerg void StmtPrinter::VisitOMPScanDirective(OMPScanDirective *Node) {
770*e038c9c4Sjoerg   Indent() << "#pragma omp scan";
771*e038c9c4Sjoerg   PrintOMPExecutableDirective(Node);
772*e038c9c4Sjoerg }
773*e038c9c4Sjoerg 
VisitOMPOrderedDirective(OMPOrderedDirective * Node)7747330f729Sjoerg void StmtPrinter::VisitOMPOrderedDirective(OMPOrderedDirective *Node) {
7757330f729Sjoerg   Indent() << "#pragma omp ordered";
7767330f729Sjoerg   PrintOMPExecutableDirective(Node, Node->hasClausesOfKind<OMPDependClause>());
7777330f729Sjoerg }
7787330f729Sjoerg 
VisitOMPAtomicDirective(OMPAtomicDirective * Node)7797330f729Sjoerg void StmtPrinter::VisitOMPAtomicDirective(OMPAtomicDirective *Node) {
7807330f729Sjoerg   Indent() << "#pragma omp atomic";
7817330f729Sjoerg   PrintOMPExecutableDirective(Node);
7827330f729Sjoerg }
7837330f729Sjoerg 
VisitOMPTargetDirective(OMPTargetDirective * Node)7847330f729Sjoerg void StmtPrinter::VisitOMPTargetDirective(OMPTargetDirective *Node) {
7857330f729Sjoerg   Indent() << "#pragma omp target";
7867330f729Sjoerg   PrintOMPExecutableDirective(Node);
7877330f729Sjoerg }
7887330f729Sjoerg 
VisitOMPTargetDataDirective(OMPTargetDataDirective * Node)7897330f729Sjoerg void StmtPrinter::VisitOMPTargetDataDirective(OMPTargetDataDirective *Node) {
7907330f729Sjoerg   Indent() << "#pragma omp target data";
7917330f729Sjoerg   PrintOMPExecutableDirective(Node);
7927330f729Sjoerg }
7937330f729Sjoerg 
VisitOMPTargetEnterDataDirective(OMPTargetEnterDataDirective * Node)7947330f729Sjoerg void StmtPrinter::VisitOMPTargetEnterDataDirective(
7957330f729Sjoerg     OMPTargetEnterDataDirective *Node) {
7967330f729Sjoerg   Indent() << "#pragma omp target enter data";
7977330f729Sjoerg   PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
7987330f729Sjoerg }
7997330f729Sjoerg 
VisitOMPTargetExitDataDirective(OMPTargetExitDataDirective * Node)8007330f729Sjoerg void StmtPrinter::VisitOMPTargetExitDataDirective(
8017330f729Sjoerg     OMPTargetExitDataDirective *Node) {
8027330f729Sjoerg   Indent() << "#pragma omp target exit data";
8037330f729Sjoerg   PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
8047330f729Sjoerg }
8057330f729Sjoerg 
VisitOMPTargetParallelDirective(OMPTargetParallelDirective * Node)8067330f729Sjoerg void StmtPrinter::VisitOMPTargetParallelDirective(
8077330f729Sjoerg     OMPTargetParallelDirective *Node) {
8087330f729Sjoerg   Indent() << "#pragma omp target parallel";
8097330f729Sjoerg   PrintOMPExecutableDirective(Node);
8107330f729Sjoerg }
8117330f729Sjoerg 
VisitOMPTargetParallelForDirective(OMPTargetParallelForDirective * Node)8127330f729Sjoerg void StmtPrinter::VisitOMPTargetParallelForDirective(
8137330f729Sjoerg     OMPTargetParallelForDirective *Node) {
8147330f729Sjoerg   Indent() << "#pragma omp target parallel for";
8157330f729Sjoerg   PrintOMPExecutableDirective(Node);
8167330f729Sjoerg }
8177330f729Sjoerg 
VisitOMPTeamsDirective(OMPTeamsDirective * Node)8187330f729Sjoerg void StmtPrinter::VisitOMPTeamsDirective(OMPTeamsDirective *Node) {
8197330f729Sjoerg   Indent() << "#pragma omp teams";
8207330f729Sjoerg   PrintOMPExecutableDirective(Node);
8217330f729Sjoerg }
8227330f729Sjoerg 
VisitOMPCancellationPointDirective(OMPCancellationPointDirective * Node)8237330f729Sjoerg void StmtPrinter::VisitOMPCancellationPointDirective(
8247330f729Sjoerg     OMPCancellationPointDirective *Node) {
8257330f729Sjoerg   Indent() << "#pragma omp cancellation point "
8267330f729Sjoerg            << getOpenMPDirectiveName(Node->getCancelRegion());
8277330f729Sjoerg   PrintOMPExecutableDirective(Node);
8287330f729Sjoerg }
8297330f729Sjoerg 
VisitOMPCancelDirective(OMPCancelDirective * Node)8307330f729Sjoerg void StmtPrinter::VisitOMPCancelDirective(OMPCancelDirective *Node) {
8317330f729Sjoerg   Indent() << "#pragma omp cancel "
8327330f729Sjoerg            << getOpenMPDirectiveName(Node->getCancelRegion());
8337330f729Sjoerg   PrintOMPExecutableDirective(Node);
8347330f729Sjoerg }
8357330f729Sjoerg 
VisitOMPTaskLoopDirective(OMPTaskLoopDirective * Node)8367330f729Sjoerg void StmtPrinter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *Node) {
8377330f729Sjoerg   Indent() << "#pragma omp taskloop";
8387330f729Sjoerg   PrintOMPExecutableDirective(Node);
8397330f729Sjoerg }
8407330f729Sjoerg 
VisitOMPTaskLoopSimdDirective(OMPTaskLoopSimdDirective * Node)8417330f729Sjoerg void StmtPrinter::VisitOMPTaskLoopSimdDirective(
8427330f729Sjoerg     OMPTaskLoopSimdDirective *Node) {
8437330f729Sjoerg   Indent() << "#pragma omp taskloop simd";
8447330f729Sjoerg   PrintOMPExecutableDirective(Node);
8457330f729Sjoerg }
8467330f729Sjoerg 
VisitOMPMasterTaskLoopDirective(OMPMasterTaskLoopDirective * Node)8477330f729Sjoerg void StmtPrinter::VisitOMPMasterTaskLoopDirective(
8487330f729Sjoerg     OMPMasterTaskLoopDirective *Node) {
8497330f729Sjoerg   Indent() << "#pragma omp master taskloop";
8507330f729Sjoerg   PrintOMPExecutableDirective(Node);
8517330f729Sjoerg }
8527330f729Sjoerg 
VisitOMPMasterTaskLoopSimdDirective(OMPMasterTaskLoopSimdDirective * Node)8537330f729Sjoerg void StmtPrinter::VisitOMPMasterTaskLoopSimdDirective(
8547330f729Sjoerg     OMPMasterTaskLoopSimdDirective *Node) {
8557330f729Sjoerg   Indent() << "#pragma omp master taskloop simd";
8567330f729Sjoerg   PrintOMPExecutableDirective(Node);
8577330f729Sjoerg }
8587330f729Sjoerg 
VisitOMPParallelMasterTaskLoopDirective(OMPParallelMasterTaskLoopDirective * Node)8597330f729Sjoerg void StmtPrinter::VisitOMPParallelMasterTaskLoopDirective(
8607330f729Sjoerg     OMPParallelMasterTaskLoopDirective *Node) {
8617330f729Sjoerg   Indent() << "#pragma omp parallel master taskloop";
8627330f729Sjoerg   PrintOMPExecutableDirective(Node);
8637330f729Sjoerg }
8647330f729Sjoerg 
VisitOMPParallelMasterTaskLoopSimdDirective(OMPParallelMasterTaskLoopSimdDirective * Node)865*e038c9c4Sjoerg void StmtPrinter::VisitOMPParallelMasterTaskLoopSimdDirective(
866*e038c9c4Sjoerg     OMPParallelMasterTaskLoopSimdDirective *Node) {
867*e038c9c4Sjoerg   Indent() << "#pragma omp parallel master taskloop simd";
868*e038c9c4Sjoerg   PrintOMPExecutableDirective(Node);
869*e038c9c4Sjoerg }
870*e038c9c4Sjoerg 
VisitOMPDistributeDirective(OMPDistributeDirective * Node)8717330f729Sjoerg void StmtPrinter::VisitOMPDistributeDirective(OMPDistributeDirective *Node) {
8727330f729Sjoerg   Indent() << "#pragma omp distribute";
8737330f729Sjoerg   PrintOMPExecutableDirective(Node);
8747330f729Sjoerg }
8757330f729Sjoerg 
VisitOMPTargetUpdateDirective(OMPTargetUpdateDirective * Node)8767330f729Sjoerg void StmtPrinter::VisitOMPTargetUpdateDirective(
8777330f729Sjoerg     OMPTargetUpdateDirective *Node) {
8787330f729Sjoerg   Indent() << "#pragma omp target update";
8797330f729Sjoerg   PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
8807330f729Sjoerg }
8817330f729Sjoerg 
VisitOMPDistributeParallelForDirective(OMPDistributeParallelForDirective * Node)8827330f729Sjoerg void StmtPrinter::VisitOMPDistributeParallelForDirective(
8837330f729Sjoerg     OMPDistributeParallelForDirective *Node) {
8847330f729Sjoerg   Indent() << "#pragma omp distribute parallel for";
8857330f729Sjoerg   PrintOMPExecutableDirective(Node);
8867330f729Sjoerg }
8877330f729Sjoerg 
VisitOMPDistributeParallelForSimdDirective(OMPDistributeParallelForSimdDirective * Node)8887330f729Sjoerg void StmtPrinter::VisitOMPDistributeParallelForSimdDirective(
8897330f729Sjoerg     OMPDistributeParallelForSimdDirective *Node) {
8907330f729Sjoerg   Indent() << "#pragma omp distribute parallel for simd";
8917330f729Sjoerg   PrintOMPExecutableDirective(Node);
8927330f729Sjoerg }
8937330f729Sjoerg 
VisitOMPDistributeSimdDirective(OMPDistributeSimdDirective * Node)8947330f729Sjoerg void StmtPrinter::VisitOMPDistributeSimdDirective(
8957330f729Sjoerg     OMPDistributeSimdDirective *Node) {
8967330f729Sjoerg   Indent() << "#pragma omp distribute simd";
8977330f729Sjoerg   PrintOMPExecutableDirective(Node);
8987330f729Sjoerg }
8997330f729Sjoerg 
VisitOMPTargetParallelForSimdDirective(OMPTargetParallelForSimdDirective * Node)9007330f729Sjoerg void StmtPrinter::VisitOMPTargetParallelForSimdDirective(
9017330f729Sjoerg     OMPTargetParallelForSimdDirective *Node) {
9027330f729Sjoerg   Indent() << "#pragma omp target parallel for simd";
9037330f729Sjoerg   PrintOMPExecutableDirective(Node);
9047330f729Sjoerg }
9057330f729Sjoerg 
VisitOMPTargetSimdDirective(OMPTargetSimdDirective * Node)9067330f729Sjoerg void StmtPrinter::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *Node) {
9077330f729Sjoerg   Indent() << "#pragma omp target simd";
9087330f729Sjoerg   PrintOMPExecutableDirective(Node);
9097330f729Sjoerg }
9107330f729Sjoerg 
VisitOMPTeamsDistributeDirective(OMPTeamsDistributeDirective * Node)9117330f729Sjoerg void StmtPrinter::VisitOMPTeamsDistributeDirective(
9127330f729Sjoerg     OMPTeamsDistributeDirective *Node) {
9137330f729Sjoerg   Indent() << "#pragma omp teams distribute";
9147330f729Sjoerg   PrintOMPExecutableDirective(Node);
9157330f729Sjoerg }
9167330f729Sjoerg 
VisitOMPTeamsDistributeSimdDirective(OMPTeamsDistributeSimdDirective * Node)9177330f729Sjoerg void StmtPrinter::VisitOMPTeamsDistributeSimdDirective(
9187330f729Sjoerg     OMPTeamsDistributeSimdDirective *Node) {
9197330f729Sjoerg   Indent() << "#pragma omp teams distribute simd";
9207330f729Sjoerg   PrintOMPExecutableDirective(Node);
9217330f729Sjoerg }
9227330f729Sjoerg 
VisitOMPTeamsDistributeParallelForSimdDirective(OMPTeamsDistributeParallelForSimdDirective * Node)9237330f729Sjoerg void StmtPrinter::VisitOMPTeamsDistributeParallelForSimdDirective(
9247330f729Sjoerg     OMPTeamsDistributeParallelForSimdDirective *Node) {
9257330f729Sjoerg   Indent() << "#pragma omp teams distribute parallel for simd";
9267330f729Sjoerg   PrintOMPExecutableDirective(Node);
9277330f729Sjoerg }
9287330f729Sjoerg 
VisitOMPTeamsDistributeParallelForDirective(OMPTeamsDistributeParallelForDirective * Node)9297330f729Sjoerg void StmtPrinter::VisitOMPTeamsDistributeParallelForDirective(
9307330f729Sjoerg     OMPTeamsDistributeParallelForDirective *Node) {
9317330f729Sjoerg   Indent() << "#pragma omp teams distribute parallel for";
9327330f729Sjoerg   PrintOMPExecutableDirective(Node);
9337330f729Sjoerg }
9347330f729Sjoerg 
VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective * Node)9357330f729Sjoerg void StmtPrinter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *Node) {
9367330f729Sjoerg   Indent() << "#pragma omp target teams";
9377330f729Sjoerg   PrintOMPExecutableDirective(Node);
9387330f729Sjoerg }
9397330f729Sjoerg 
VisitOMPTargetTeamsDistributeDirective(OMPTargetTeamsDistributeDirective * Node)9407330f729Sjoerg void StmtPrinter::VisitOMPTargetTeamsDistributeDirective(
9417330f729Sjoerg     OMPTargetTeamsDistributeDirective *Node) {
9427330f729Sjoerg   Indent() << "#pragma omp target teams distribute";
9437330f729Sjoerg   PrintOMPExecutableDirective(Node);
9447330f729Sjoerg }
9457330f729Sjoerg 
VisitOMPTargetTeamsDistributeParallelForDirective(OMPTargetTeamsDistributeParallelForDirective * Node)9467330f729Sjoerg void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForDirective(
9477330f729Sjoerg     OMPTargetTeamsDistributeParallelForDirective *Node) {
9487330f729Sjoerg   Indent() << "#pragma omp target teams distribute parallel for";
9497330f729Sjoerg   PrintOMPExecutableDirective(Node);
9507330f729Sjoerg }
9517330f729Sjoerg 
VisitOMPTargetTeamsDistributeParallelForSimdDirective(OMPTargetTeamsDistributeParallelForSimdDirective * Node)9527330f729Sjoerg void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
9537330f729Sjoerg     OMPTargetTeamsDistributeParallelForSimdDirective *Node) {
9547330f729Sjoerg   Indent() << "#pragma omp target teams distribute parallel for simd";
9557330f729Sjoerg   PrintOMPExecutableDirective(Node);
9567330f729Sjoerg }
9577330f729Sjoerg 
VisitOMPTargetTeamsDistributeSimdDirective(OMPTargetTeamsDistributeSimdDirective * Node)9587330f729Sjoerg void StmtPrinter::VisitOMPTargetTeamsDistributeSimdDirective(
9597330f729Sjoerg     OMPTargetTeamsDistributeSimdDirective *Node) {
9607330f729Sjoerg   Indent() << "#pragma omp target teams distribute simd";
9617330f729Sjoerg   PrintOMPExecutableDirective(Node);
9627330f729Sjoerg }
9637330f729Sjoerg 
VisitOMPInteropDirective(OMPInteropDirective * Node)964*e038c9c4Sjoerg void StmtPrinter::VisitOMPInteropDirective(OMPInteropDirective *Node) {
965*e038c9c4Sjoerg   Indent() << "#pragma omp interop";
966*e038c9c4Sjoerg   PrintOMPExecutableDirective(Node);
967*e038c9c4Sjoerg }
968*e038c9c4Sjoerg 
VisitOMPDispatchDirective(OMPDispatchDirective * Node)969*e038c9c4Sjoerg void StmtPrinter::VisitOMPDispatchDirective(OMPDispatchDirective *Node) {
970*e038c9c4Sjoerg   Indent() << "#pragma omp dispatch";
971*e038c9c4Sjoerg   PrintOMPExecutableDirective(Node);
972*e038c9c4Sjoerg }
973*e038c9c4Sjoerg 
VisitOMPMaskedDirective(OMPMaskedDirective * Node)974*e038c9c4Sjoerg void StmtPrinter::VisitOMPMaskedDirective(OMPMaskedDirective *Node) {
975*e038c9c4Sjoerg   Indent() << "#pragma omp masked";
976*e038c9c4Sjoerg   PrintOMPExecutableDirective(Node);
977*e038c9c4Sjoerg }
978*e038c9c4Sjoerg 
9797330f729Sjoerg //===----------------------------------------------------------------------===//
9807330f729Sjoerg //  Expr printing methods.
9817330f729Sjoerg //===----------------------------------------------------------------------===//
9827330f729Sjoerg 
VisitSourceLocExpr(SourceLocExpr * Node)9837330f729Sjoerg void StmtPrinter::VisitSourceLocExpr(SourceLocExpr *Node) {
9847330f729Sjoerg   OS << Node->getBuiltinStr() << "()";
9857330f729Sjoerg }
9867330f729Sjoerg 
VisitConstantExpr(ConstantExpr * Node)9877330f729Sjoerg void StmtPrinter::VisitConstantExpr(ConstantExpr *Node) {
9887330f729Sjoerg   PrintExpr(Node->getSubExpr());
9897330f729Sjoerg }
9907330f729Sjoerg 
VisitDeclRefExpr(DeclRefExpr * Node)9917330f729Sjoerg void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
9927330f729Sjoerg   if (const auto *OCED = dyn_cast<OMPCapturedExprDecl>(Node->getDecl())) {
9937330f729Sjoerg     OCED->getInit()->IgnoreImpCasts()->printPretty(OS, nullptr, Policy);
9947330f729Sjoerg     return;
9957330f729Sjoerg   }
996*e038c9c4Sjoerg   if (const auto *TPOD = dyn_cast<TemplateParamObjectDecl>(Node->getDecl())) {
997*e038c9c4Sjoerg     TPOD->printAsExpr(OS);
998*e038c9c4Sjoerg     return;
999*e038c9c4Sjoerg   }
10007330f729Sjoerg   if (NestedNameSpecifier *Qualifier = Node->getQualifier())
10017330f729Sjoerg     Qualifier->print(OS, Policy);
10027330f729Sjoerg   if (Node->hasTemplateKeyword())
10037330f729Sjoerg     OS << "template ";
10047330f729Sjoerg   OS << Node->getNameInfo();
1005*e038c9c4Sjoerg   if (Node->hasExplicitTemplateArgs()) {
1006*e038c9c4Sjoerg     const TemplateParameterList *TPL = nullptr;
1007*e038c9c4Sjoerg     if (!Node->hadMultipleCandidates())
1008*e038c9c4Sjoerg       if (auto *TD = dyn_cast<TemplateDecl>(Node->getDecl()))
1009*e038c9c4Sjoerg         TPL = TD->getTemplateParameters();
1010*e038c9c4Sjoerg     printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
1011*e038c9c4Sjoerg   }
10127330f729Sjoerg }
10137330f729Sjoerg 
VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr * Node)10147330f729Sjoerg void StmtPrinter::VisitDependentScopeDeclRefExpr(
10157330f729Sjoerg                                            DependentScopeDeclRefExpr *Node) {
10167330f729Sjoerg   if (NestedNameSpecifier *Qualifier = Node->getQualifier())
10177330f729Sjoerg     Qualifier->print(OS, Policy);
10187330f729Sjoerg   if (Node->hasTemplateKeyword())
10197330f729Sjoerg     OS << "template ";
10207330f729Sjoerg   OS << Node->getNameInfo();
10217330f729Sjoerg   if (Node->hasExplicitTemplateArgs())
10227330f729Sjoerg     printTemplateArgumentList(OS, Node->template_arguments(), Policy);
10237330f729Sjoerg }
10247330f729Sjoerg 
VisitUnresolvedLookupExpr(UnresolvedLookupExpr * Node)10257330f729Sjoerg void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
10267330f729Sjoerg   if (Node->getQualifier())
10277330f729Sjoerg     Node->getQualifier()->print(OS, Policy);
10287330f729Sjoerg   if (Node->hasTemplateKeyword())
10297330f729Sjoerg     OS << "template ";
10307330f729Sjoerg   OS << Node->getNameInfo();
10317330f729Sjoerg   if (Node->hasExplicitTemplateArgs())
10327330f729Sjoerg     printTemplateArgumentList(OS, Node->template_arguments(), Policy);
10337330f729Sjoerg }
10347330f729Sjoerg 
isImplicitSelf(const Expr * E)10357330f729Sjoerg static bool isImplicitSelf(const Expr *E) {
10367330f729Sjoerg   if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
10377330f729Sjoerg     if (const auto *PD = dyn_cast<ImplicitParamDecl>(DRE->getDecl())) {
10387330f729Sjoerg       if (PD->getParameterKind() == ImplicitParamDecl::ObjCSelf &&
10397330f729Sjoerg           DRE->getBeginLoc().isInvalid())
10407330f729Sjoerg         return true;
10417330f729Sjoerg     }
10427330f729Sjoerg   }
10437330f729Sjoerg   return false;
10447330f729Sjoerg }
10457330f729Sjoerg 
VisitObjCIvarRefExpr(ObjCIvarRefExpr * Node)10467330f729Sjoerg void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
10477330f729Sjoerg   if (Node->getBase()) {
10487330f729Sjoerg     if (!Policy.SuppressImplicitBase ||
10497330f729Sjoerg         !isImplicitSelf(Node->getBase()->IgnoreImpCasts())) {
10507330f729Sjoerg       PrintExpr(Node->getBase());
10517330f729Sjoerg       OS << (Node->isArrow() ? "->" : ".");
10527330f729Sjoerg     }
10537330f729Sjoerg   }
10547330f729Sjoerg   OS << *Node->getDecl();
10557330f729Sjoerg }
10567330f729Sjoerg 
VisitObjCPropertyRefExpr(ObjCPropertyRefExpr * Node)10577330f729Sjoerg void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
10587330f729Sjoerg   if (Node->isSuperReceiver())
10597330f729Sjoerg     OS << "super.";
10607330f729Sjoerg   else if (Node->isObjectReceiver() && Node->getBase()) {
10617330f729Sjoerg     PrintExpr(Node->getBase());
10627330f729Sjoerg     OS << ".";
10637330f729Sjoerg   } else if (Node->isClassReceiver() && Node->getClassReceiver()) {
10647330f729Sjoerg     OS << Node->getClassReceiver()->getName() << ".";
10657330f729Sjoerg   }
10667330f729Sjoerg 
10677330f729Sjoerg   if (Node->isImplicitProperty()) {
10687330f729Sjoerg     if (const auto *Getter = Node->getImplicitPropertyGetter())
10697330f729Sjoerg       Getter->getSelector().print(OS);
10707330f729Sjoerg     else
10717330f729Sjoerg       OS << SelectorTable::getPropertyNameFromSetterSelector(
10727330f729Sjoerg           Node->getImplicitPropertySetter()->getSelector());
10737330f729Sjoerg   } else
10747330f729Sjoerg     OS << Node->getExplicitProperty()->getName();
10757330f729Sjoerg }
10767330f729Sjoerg 
VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr * Node)10777330f729Sjoerg void StmtPrinter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node) {
10787330f729Sjoerg   PrintExpr(Node->getBaseExpr());
10797330f729Sjoerg   OS << "[";
10807330f729Sjoerg   PrintExpr(Node->getKeyExpr());
10817330f729Sjoerg   OS << "]";
10827330f729Sjoerg }
10837330f729Sjoerg 
VisitPredefinedExpr(PredefinedExpr * Node)10847330f729Sjoerg void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
10857330f729Sjoerg   OS << PredefinedExpr::getIdentKindName(Node->getIdentKind());
10867330f729Sjoerg }
10877330f729Sjoerg 
VisitCharacterLiteral(CharacterLiteral * Node)10887330f729Sjoerg void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
1089*e038c9c4Sjoerg   CharacterLiteral::print(Node->getValue(), Node->getKind(), OS);
10907330f729Sjoerg }
10917330f729Sjoerg 
10927330f729Sjoerg /// Prints the given expression using the original source text. Returns true on
10937330f729Sjoerg /// success, false otherwise.
printExprAsWritten(raw_ostream & OS,Expr * E,const ASTContext * Context)10947330f729Sjoerg static bool printExprAsWritten(raw_ostream &OS, Expr *E,
10957330f729Sjoerg                                const ASTContext *Context) {
10967330f729Sjoerg   if (!Context)
10977330f729Sjoerg     return false;
10987330f729Sjoerg   bool Invalid = false;
10997330f729Sjoerg   StringRef Source = Lexer::getSourceText(
11007330f729Sjoerg       CharSourceRange::getTokenRange(E->getSourceRange()),
11017330f729Sjoerg       Context->getSourceManager(), Context->getLangOpts(), &Invalid);
11027330f729Sjoerg   if (!Invalid) {
11037330f729Sjoerg     OS << Source;
11047330f729Sjoerg     return true;
11057330f729Sjoerg   }
11067330f729Sjoerg   return false;
11077330f729Sjoerg }
11087330f729Sjoerg 
VisitIntegerLiteral(IntegerLiteral * Node)11097330f729Sjoerg void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
11107330f729Sjoerg   if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
11117330f729Sjoerg     return;
11127330f729Sjoerg   bool isSigned = Node->getType()->isSignedIntegerType();
11137330f729Sjoerg   OS << Node->getValue().toString(10, isSigned);
11147330f729Sjoerg 
11157330f729Sjoerg   // Emit suffixes.  Integer literals are always a builtin integer type.
11167330f729Sjoerg   switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
11177330f729Sjoerg   default: llvm_unreachable("Unexpected type for integer literal!");
11187330f729Sjoerg   case BuiltinType::Char_S:
11197330f729Sjoerg   case BuiltinType::Char_U:    OS << "i8"; break;
11207330f729Sjoerg   case BuiltinType::UChar:     OS << "Ui8"; break;
11217330f729Sjoerg   case BuiltinType::Short:     OS << "i16"; break;
11227330f729Sjoerg   case BuiltinType::UShort:    OS << "Ui16"; break;
11237330f729Sjoerg   case BuiltinType::Int:       break; // no suffix.
11247330f729Sjoerg   case BuiltinType::UInt:      OS << 'U'; break;
11257330f729Sjoerg   case BuiltinType::Long:      OS << 'L'; break;
11267330f729Sjoerg   case BuiltinType::ULong:     OS << "UL"; break;
11277330f729Sjoerg   case BuiltinType::LongLong:  OS << "LL"; break;
11287330f729Sjoerg   case BuiltinType::ULongLong: OS << "ULL"; break;
1129*e038c9c4Sjoerg   case BuiltinType::Int128:
1130*e038c9c4Sjoerg     break; // no suffix.
1131*e038c9c4Sjoerg   case BuiltinType::UInt128:
1132*e038c9c4Sjoerg     break; // no suffix.
11337330f729Sjoerg   }
11347330f729Sjoerg }
11357330f729Sjoerg 
VisitFixedPointLiteral(FixedPointLiteral * Node)11367330f729Sjoerg void StmtPrinter::VisitFixedPointLiteral(FixedPointLiteral *Node) {
11377330f729Sjoerg   if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
11387330f729Sjoerg     return;
11397330f729Sjoerg   OS << Node->getValueAsString(/*Radix=*/10);
11407330f729Sjoerg 
11417330f729Sjoerg   switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
11427330f729Sjoerg     default: llvm_unreachable("Unexpected type for fixed point literal!");
11437330f729Sjoerg     case BuiltinType::ShortFract:   OS << "hr"; break;
11447330f729Sjoerg     case BuiltinType::ShortAccum:   OS << "hk"; break;
11457330f729Sjoerg     case BuiltinType::UShortFract:  OS << "uhr"; break;
11467330f729Sjoerg     case BuiltinType::UShortAccum:  OS << "uhk"; break;
11477330f729Sjoerg     case BuiltinType::Fract:        OS << "r"; break;
11487330f729Sjoerg     case BuiltinType::Accum:        OS << "k"; break;
11497330f729Sjoerg     case BuiltinType::UFract:       OS << "ur"; break;
11507330f729Sjoerg     case BuiltinType::UAccum:       OS << "uk"; break;
11517330f729Sjoerg     case BuiltinType::LongFract:    OS << "lr"; break;
11527330f729Sjoerg     case BuiltinType::LongAccum:    OS << "lk"; break;
11537330f729Sjoerg     case BuiltinType::ULongFract:   OS << "ulr"; break;
11547330f729Sjoerg     case BuiltinType::ULongAccum:   OS << "ulk"; break;
11557330f729Sjoerg   }
11567330f729Sjoerg }
11577330f729Sjoerg 
PrintFloatingLiteral(raw_ostream & OS,FloatingLiteral * Node,bool PrintSuffix)11587330f729Sjoerg static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node,
11597330f729Sjoerg                                  bool PrintSuffix) {
11607330f729Sjoerg   SmallString<16> Str;
11617330f729Sjoerg   Node->getValue().toString(Str);
11627330f729Sjoerg   OS << Str;
11637330f729Sjoerg   if (Str.find_first_not_of("-0123456789") == StringRef::npos)
11647330f729Sjoerg     OS << '.'; // Trailing dot in order to separate from ints.
11657330f729Sjoerg 
11667330f729Sjoerg   if (!PrintSuffix)
11677330f729Sjoerg     return;
11687330f729Sjoerg 
11697330f729Sjoerg   // Emit suffixes.  Float literals are always a builtin float type.
11707330f729Sjoerg   switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
11717330f729Sjoerg   default: llvm_unreachable("Unexpected type for float literal!");
11727330f729Sjoerg   case BuiltinType::Half:       break; // FIXME: suffix?
11737330f729Sjoerg   case BuiltinType::Double:     break; // no suffix.
11747330f729Sjoerg   case BuiltinType::Float16:    OS << "F16"; break;
11757330f729Sjoerg   case BuiltinType::Float:      OS << 'F'; break;
11767330f729Sjoerg   case BuiltinType::LongDouble: OS << 'L'; break;
11777330f729Sjoerg   case BuiltinType::Float128:   OS << 'Q'; break;
11787330f729Sjoerg   }
11797330f729Sjoerg }
11807330f729Sjoerg 
VisitFloatingLiteral(FloatingLiteral * Node)11817330f729Sjoerg void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
11827330f729Sjoerg   if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
11837330f729Sjoerg     return;
11847330f729Sjoerg   PrintFloatingLiteral(OS, Node, /*PrintSuffix=*/true);
11857330f729Sjoerg }
11867330f729Sjoerg 
VisitImaginaryLiteral(ImaginaryLiteral * Node)11877330f729Sjoerg void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
11887330f729Sjoerg   PrintExpr(Node->getSubExpr());
11897330f729Sjoerg   OS << "i";
11907330f729Sjoerg }
11917330f729Sjoerg 
VisitStringLiteral(StringLiteral * Str)11927330f729Sjoerg void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
11937330f729Sjoerg   Str->outputString(OS);
11947330f729Sjoerg }
11957330f729Sjoerg 
VisitParenExpr(ParenExpr * Node)11967330f729Sjoerg void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
11977330f729Sjoerg   OS << "(";
11987330f729Sjoerg   PrintExpr(Node->getSubExpr());
11997330f729Sjoerg   OS << ")";
12007330f729Sjoerg }
12017330f729Sjoerg 
VisitUnaryOperator(UnaryOperator * Node)12027330f729Sjoerg void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
12037330f729Sjoerg   if (!Node->isPostfix()) {
12047330f729Sjoerg     OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
12057330f729Sjoerg 
12067330f729Sjoerg     // Print a space if this is an "identifier operator" like __real, or if
12077330f729Sjoerg     // it might be concatenated incorrectly like '+'.
12087330f729Sjoerg     switch (Node->getOpcode()) {
12097330f729Sjoerg     default: break;
12107330f729Sjoerg     case UO_Real:
12117330f729Sjoerg     case UO_Imag:
12127330f729Sjoerg     case UO_Extension:
12137330f729Sjoerg       OS << ' ';
12147330f729Sjoerg       break;
12157330f729Sjoerg     case UO_Plus:
12167330f729Sjoerg     case UO_Minus:
12177330f729Sjoerg       if (isa<UnaryOperator>(Node->getSubExpr()))
12187330f729Sjoerg         OS << ' ';
12197330f729Sjoerg       break;
12207330f729Sjoerg     }
12217330f729Sjoerg   }
12227330f729Sjoerg   PrintExpr(Node->getSubExpr());
12237330f729Sjoerg 
12247330f729Sjoerg   if (Node->isPostfix())
12257330f729Sjoerg     OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
12267330f729Sjoerg }
12277330f729Sjoerg 
VisitOffsetOfExpr(OffsetOfExpr * Node)12287330f729Sjoerg void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {
12297330f729Sjoerg   OS << "__builtin_offsetof(";
12307330f729Sjoerg   Node->getTypeSourceInfo()->getType().print(OS, Policy);
12317330f729Sjoerg   OS << ", ";
12327330f729Sjoerg   bool PrintedSomething = false;
12337330f729Sjoerg   for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) {
12347330f729Sjoerg     OffsetOfNode ON = Node->getComponent(i);
12357330f729Sjoerg     if (ON.getKind() == OffsetOfNode::Array) {
12367330f729Sjoerg       // Array node
12377330f729Sjoerg       OS << "[";
12387330f729Sjoerg       PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex()));
12397330f729Sjoerg       OS << "]";
12407330f729Sjoerg       PrintedSomething = true;
12417330f729Sjoerg       continue;
12427330f729Sjoerg     }
12437330f729Sjoerg 
12447330f729Sjoerg     // Skip implicit base indirections.
12457330f729Sjoerg     if (ON.getKind() == OffsetOfNode::Base)
12467330f729Sjoerg       continue;
12477330f729Sjoerg 
12487330f729Sjoerg     // Field or identifier node.
12497330f729Sjoerg     IdentifierInfo *Id = ON.getFieldName();
12507330f729Sjoerg     if (!Id)
12517330f729Sjoerg       continue;
12527330f729Sjoerg 
12537330f729Sjoerg     if (PrintedSomething)
12547330f729Sjoerg       OS << ".";
12557330f729Sjoerg     else
12567330f729Sjoerg       PrintedSomething = true;
12577330f729Sjoerg     OS << Id->getName();
12587330f729Sjoerg   }
12597330f729Sjoerg   OS << ")";
12607330f729Sjoerg }
12617330f729Sjoerg 
VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr * Node)1262*e038c9c4Sjoerg void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(
1263*e038c9c4Sjoerg     UnaryExprOrTypeTraitExpr *Node) {
1264*e038c9c4Sjoerg   const char *Spelling = getTraitSpelling(Node->getKind());
1265*e038c9c4Sjoerg   if (Node->getKind() == UETT_AlignOf) {
12667330f729Sjoerg     if (Policy.Alignof)
1267*e038c9c4Sjoerg       Spelling = "alignof";
12687330f729Sjoerg     else if (Policy.UnderscoreAlignof)
1269*e038c9c4Sjoerg       Spelling = "_Alignof";
12707330f729Sjoerg     else
1271*e038c9c4Sjoerg       Spelling = "__alignof";
12727330f729Sjoerg   }
1273*e038c9c4Sjoerg 
1274*e038c9c4Sjoerg   OS << Spelling;
1275*e038c9c4Sjoerg 
12767330f729Sjoerg   if (Node->isArgumentType()) {
12777330f729Sjoerg     OS << '(';
12787330f729Sjoerg     Node->getArgumentType().print(OS, Policy);
12797330f729Sjoerg     OS << ')';
12807330f729Sjoerg   } else {
12817330f729Sjoerg     OS << " ";
12827330f729Sjoerg     PrintExpr(Node->getArgumentExpr());
12837330f729Sjoerg   }
12847330f729Sjoerg }
12857330f729Sjoerg 
VisitGenericSelectionExpr(GenericSelectionExpr * Node)12867330f729Sjoerg void StmtPrinter::VisitGenericSelectionExpr(GenericSelectionExpr *Node) {
12877330f729Sjoerg   OS << "_Generic(";
12887330f729Sjoerg   PrintExpr(Node->getControllingExpr());
1289*e038c9c4Sjoerg   for (const GenericSelectionExpr::Association Assoc : Node->associations()) {
12907330f729Sjoerg     OS << ", ";
12917330f729Sjoerg     QualType T = Assoc.getType();
12927330f729Sjoerg     if (T.isNull())
12937330f729Sjoerg       OS << "default";
12947330f729Sjoerg     else
12957330f729Sjoerg       T.print(OS, Policy);
12967330f729Sjoerg     OS << ": ";
12977330f729Sjoerg     PrintExpr(Assoc.getAssociationExpr());
12987330f729Sjoerg   }
12997330f729Sjoerg   OS << ")";
13007330f729Sjoerg }
13017330f729Sjoerg 
VisitArraySubscriptExpr(ArraySubscriptExpr * Node)13027330f729Sjoerg void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
13037330f729Sjoerg   PrintExpr(Node->getLHS());
13047330f729Sjoerg   OS << "[";
13057330f729Sjoerg   PrintExpr(Node->getRHS());
13067330f729Sjoerg   OS << "]";
13077330f729Sjoerg }
13087330f729Sjoerg 
VisitMatrixSubscriptExpr(MatrixSubscriptExpr * Node)1309*e038c9c4Sjoerg void StmtPrinter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *Node) {
1310*e038c9c4Sjoerg   PrintExpr(Node->getBase());
1311*e038c9c4Sjoerg   OS << "[";
1312*e038c9c4Sjoerg   PrintExpr(Node->getRowIdx());
1313*e038c9c4Sjoerg   OS << "]";
1314*e038c9c4Sjoerg   OS << "[";
1315*e038c9c4Sjoerg   PrintExpr(Node->getColumnIdx());
1316*e038c9c4Sjoerg   OS << "]";
1317*e038c9c4Sjoerg }
1318*e038c9c4Sjoerg 
VisitOMPArraySectionExpr(OMPArraySectionExpr * Node)13197330f729Sjoerg void StmtPrinter::VisitOMPArraySectionExpr(OMPArraySectionExpr *Node) {
13207330f729Sjoerg   PrintExpr(Node->getBase());
13217330f729Sjoerg   OS << "[";
13227330f729Sjoerg   if (Node->getLowerBound())
13237330f729Sjoerg     PrintExpr(Node->getLowerBound());
1324*e038c9c4Sjoerg   if (Node->getColonLocFirst().isValid()) {
13257330f729Sjoerg     OS << ":";
13267330f729Sjoerg     if (Node->getLength())
13277330f729Sjoerg       PrintExpr(Node->getLength());
13287330f729Sjoerg   }
1329*e038c9c4Sjoerg   if (Node->getColonLocSecond().isValid()) {
1330*e038c9c4Sjoerg     OS << ":";
1331*e038c9c4Sjoerg     if (Node->getStride())
1332*e038c9c4Sjoerg       PrintExpr(Node->getStride());
1333*e038c9c4Sjoerg   }
13347330f729Sjoerg   OS << "]";
13357330f729Sjoerg }
13367330f729Sjoerg 
VisitOMPArrayShapingExpr(OMPArrayShapingExpr * Node)1337*e038c9c4Sjoerg void StmtPrinter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *Node) {
1338*e038c9c4Sjoerg   OS << "(";
1339*e038c9c4Sjoerg   for (Expr *E : Node->getDimensions()) {
1340*e038c9c4Sjoerg     OS << "[";
1341*e038c9c4Sjoerg     PrintExpr(E);
1342*e038c9c4Sjoerg     OS << "]";
1343*e038c9c4Sjoerg   }
1344*e038c9c4Sjoerg   OS << ")";
1345*e038c9c4Sjoerg   PrintExpr(Node->getBase());
1346*e038c9c4Sjoerg }
1347*e038c9c4Sjoerg 
VisitOMPIteratorExpr(OMPIteratorExpr * Node)1348*e038c9c4Sjoerg void StmtPrinter::VisitOMPIteratorExpr(OMPIteratorExpr *Node) {
1349*e038c9c4Sjoerg   OS << "iterator(";
1350*e038c9c4Sjoerg   for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) {
1351*e038c9c4Sjoerg     auto *VD = cast<ValueDecl>(Node->getIteratorDecl(I));
1352*e038c9c4Sjoerg     VD->getType().print(OS, Policy);
1353*e038c9c4Sjoerg     const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I);
1354*e038c9c4Sjoerg     OS << " " << VD->getName() << " = ";
1355*e038c9c4Sjoerg     PrintExpr(Range.Begin);
1356*e038c9c4Sjoerg     OS << ":";
1357*e038c9c4Sjoerg     PrintExpr(Range.End);
1358*e038c9c4Sjoerg     if (Range.Step) {
1359*e038c9c4Sjoerg       OS << ":";
1360*e038c9c4Sjoerg       PrintExpr(Range.Step);
1361*e038c9c4Sjoerg     }
1362*e038c9c4Sjoerg     if (I < E - 1)
1363*e038c9c4Sjoerg       OS << ", ";
1364*e038c9c4Sjoerg   }
1365*e038c9c4Sjoerg   OS << ")";
1366*e038c9c4Sjoerg }
1367*e038c9c4Sjoerg 
PrintCallArgs(CallExpr * Call)13687330f729Sjoerg void StmtPrinter::PrintCallArgs(CallExpr *Call) {
13697330f729Sjoerg   for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
13707330f729Sjoerg     if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
13717330f729Sjoerg       // Don't print any defaulted arguments
13727330f729Sjoerg       break;
13737330f729Sjoerg     }
13747330f729Sjoerg 
13757330f729Sjoerg     if (i) OS << ", ";
13767330f729Sjoerg     PrintExpr(Call->getArg(i));
13777330f729Sjoerg   }
13787330f729Sjoerg }
13797330f729Sjoerg 
VisitCallExpr(CallExpr * Call)13807330f729Sjoerg void StmtPrinter::VisitCallExpr(CallExpr *Call) {
13817330f729Sjoerg   PrintExpr(Call->getCallee());
13827330f729Sjoerg   OS << "(";
13837330f729Sjoerg   PrintCallArgs(Call);
13847330f729Sjoerg   OS << ")";
13857330f729Sjoerg }
13867330f729Sjoerg 
isImplicitThis(const Expr * E)13877330f729Sjoerg static bool isImplicitThis(const Expr *E) {
13887330f729Sjoerg   if (const auto *TE = dyn_cast<CXXThisExpr>(E))
13897330f729Sjoerg     return TE->isImplicit();
13907330f729Sjoerg   return false;
13917330f729Sjoerg }
13927330f729Sjoerg 
VisitMemberExpr(MemberExpr * Node)13937330f729Sjoerg void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
13947330f729Sjoerg   if (!Policy.SuppressImplicitBase || !isImplicitThis(Node->getBase())) {
13957330f729Sjoerg     PrintExpr(Node->getBase());
13967330f729Sjoerg 
13977330f729Sjoerg     auto *ParentMember = dyn_cast<MemberExpr>(Node->getBase());
13987330f729Sjoerg     FieldDecl *ParentDecl =
13997330f729Sjoerg         ParentMember ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl())
14007330f729Sjoerg                      : nullptr;
14017330f729Sjoerg 
14027330f729Sjoerg     if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion())
14037330f729Sjoerg       OS << (Node->isArrow() ? "->" : ".");
14047330f729Sjoerg   }
14057330f729Sjoerg 
14067330f729Sjoerg   if (auto *FD = dyn_cast<FieldDecl>(Node->getMemberDecl()))
14077330f729Sjoerg     if (FD->isAnonymousStructOrUnion())
14087330f729Sjoerg       return;
14097330f729Sjoerg 
14107330f729Sjoerg   if (NestedNameSpecifier *Qualifier = Node->getQualifier())
14117330f729Sjoerg     Qualifier->print(OS, Policy);
14127330f729Sjoerg   if (Node->hasTemplateKeyword())
14137330f729Sjoerg     OS << "template ";
14147330f729Sjoerg   OS << Node->getMemberNameInfo();
1415*e038c9c4Sjoerg   const TemplateParameterList *TPL = nullptr;
1416*e038c9c4Sjoerg   if (auto *FD = dyn_cast<FunctionDecl>(Node->getMemberDecl())) {
1417*e038c9c4Sjoerg     if (!Node->hadMultipleCandidates())
1418*e038c9c4Sjoerg       if (auto *FTD = FD->getPrimaryTemplate())
1419*e038c9c4Sjoerg         TPL = FTD->getTemplateParameters();
1420*e038c9c4Sjoerg   } else if (auto *VTSD =
1421*e038c9c4Sjoerg                  dyn_cast<VarTemplateSpecializationDecl>(Node->getMemberDecl()))
1422*e038c9c4Sjoerg     TPL = VTSD->getSpecializedTemplate()->getTemplateParameters();
14237330f729Sjoerg   if (Node->hasExplicitTemplateArgs())
1424*e038c9c4Sjoerg     printTemplateArgumentList(OS, Node->template_arguments(), Policy, TPL);
14257330f729Sjoerg }
14267330f729Sjoerg 
VisitObjCIsaExpr(ObjCIsaExpr * Node)14277330f729Sjoerg void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
14287330f729Sjoerg   PrintExpr(Node->getBase());
14297330f729Sjoerg   OS << (Node->isArrow() ? "->isa" : ".isa");
14307330f729Sjoerg }
14317330f729Sjoerg 
VisitExtVectorElementExpr(ExtVectorElementExpr * Node)14327330f729Sjoerg void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
14337330f729Sjoerg   PrintExpr(Node->getBase());
14347330f729Sjoerg   OS << ".";
14357330f729Sjoerg   OS << Node->getAccessor().getName();
14367330f729Sjoerg }
14377330f729Sjoerg 
VisitCStyleCastExpr(CStyleCastExpr * Node)14387330f729Sjoerg void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
14397330f729Sjoerg   OS << '(';
14407330f729Sjoerg   Node->getTypeAsWritten().print(OS, Policy);
14417330f729Sjoerg   OS << ')';
14427330f729Sjoerg   PrintExpr(Node->getSubExpr());
14437330f729Sjoerg }
14447330f729Sjoerg 
VisitCompoundLiteralExpr(CompoundLiteralExpr * Node)14457330f729Sjoerg void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
14467330f729Sjoerg   OS << '(';
14477330f729Sjoerg   Node->getType().print(OS, Policy);
14487330f729Sjoerg   OS << ')';
14497330f729Sjoerg   PrintExpr(Node->getInitializer());
14507330f729Sjoerg }
14517330f729Sjoerg 
VisitImplicitCastExpr(ImplicitCastExpr * Node)14527330f729Sjoerg void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
14537330f729Sjoerg   // No need to print anything, simply forward to the subexpression.
14547330f729Sjoerg   PrintExpr(Node->getSubExpr());
14557330f729Sjoerg }
14567330f729Sjoerg 
VisitBinaryOperator(BinaryOperator * Node)14577330f729Sjoerg void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
14587330f729Sjoerg   PrintExpr(Node->getLHS());
14597330f729Sjoerg   OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
14607330f729Sjoerg   PrintExpr(Node->getRHS());
14617330f729Sjoerg }
14627330f729Sjoerg 
VisitCompoundAssignOperator(CompoundAssignOperator * Node)14637330f729Sjoerg void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
14647330f729Sjoerg   PrintExpr(Node->getLHS());
14657330f729Sjoerg   OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
14667330f729Sjoerg   PrintExpr(Node->getRHS());
14677330f729Sjoerg }
14687330f729Sjoerg 
VisitConditionalOperator(ConditionalOperator * Node)14697330f729Sjoerg void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
14707330f729Sjoerg   PrintExpr(Node->getCond());
14717330f729Sjoerg   OS << " ? ";
14727330f729Sjoerg   PrintExpr(Node->getLHS());
14737330f729Sjoerg   OS << " : ";
14747330f729Sjoerg   PrintExpr(Node->getRHS());
14757330f729Sjoerg }
14767330f729Sjoerg 
14777330f729Sjoerg // GNU extensions.
14787330f729Sjoerg 
14797330f729Sjoerg void
VisitBinaryConditionalOperator(BinaryConditionalOperator * Node)14807330f729Sjoerg StmtPrinter::VisitBinaryConditionalOperator(BinaryConditionalOperator *Node) {
14817330f729Sjoerg   PrintExpr(Node->getCommon());
14827330f729Sjoerg   OS << " ?: ";
14837330f729Sjoerg   PrintExpr(Node->getFalseExpr());
14847330f729Sjoerg }
14857330f729Sjoerg 
VisitAddrLabelExpr(AddrLabelExpr * Node)14867330f729Sjoerg void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
14877330f729Sjoerg   OS << "&&" << Node->getLabel()->getName();
14887330f729Sjoerg }
14897330f729Sjoerg 
VisitStmtExpr(StmtExpr * E)14907330f729Sjoerg void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
14917330f729Sjoerg   OS << "(";
14927330f729Sjoerg   PrintRawCompoundStmt(E->getSubStmt());
14937330f729Sjoerg   OS << ")";
14947330f729Sjoerg }
14957330f729Sjoerg 
VisitChooseExpr(ChooseExpr * Node)14967330f729Sjoerg void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
14977330f729Sjoerg   OS << "__builtin_choose_expr(";
14987330f729Sjoerg   PrintExpr(Node->getCond());
14997330f729Sjoerg   OS << ", ";
15007330f729Sjoerg   PrintExpr(Node->getLHS());
15017330f729Sjoerg   OS << ", ";
15027330f729Sjoerg   PrintExpr(Node->getRHS());
15037330f729Sjoerg   OS << ")";
15047330f729Sjoerg }
15057330f729Sjoerg 
VisitGNUNullExpr(GNUNullExpr *)15067330f729Sjoerg void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
15077330f729Sjoerg   OS << "__null";
15087330f729Sjoerg }
15097330f729Sjoerg 
VisitShuffleVectorExpr(ShuffleVectorExpr * Node)15107330f729Sjoerg void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
15117330f729Sjoerg   OS << "__builtin_shufflevector(";
15127330f729Sjoerg   for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
15137330f729Sjoerg     if (i) OS << ", ";
15147330f729Sjoerg     PrintExpr(Node->getExpr(i));
15157330f729Sjoerg   }
15167330f729Sjoerg   OS << ")";
15177330f729Sjoerg }
15187330f729Sjoerg 
VisitConvertVectorExpr(ConvertVectorExpr * Node)15197330f729Sjoerg void StmtPrinter::VisitConvertVectorExpr(ConvertVectorExpr *Node) {
15207330f729Sjoerg   OS << "__builtin_convertvector(";
15217330f729Sjoerg   PrintExpr(Node->getSrcExpr());
15227330f729Sjoerg   OS << ", ";
15237330f729Sjoerg   Node->getType().print(OS, Policy);
15247330f729Sjoerg   OS << ")";
15257330f729Sjoerg }
15267330f729Sjoerg 
VisitInitListExpr(InitListExpr * Node)15277330f729Sjoerg void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
15287330f729Sjoerg   if (Node->getSyntacticForm()) {
15297330f729Sjoerg     Visit(Node->getSyntacticForm());
15307330f729Sjoerg     return;
15317330f729Sjoerg   }
15327330f729Sjoerg 
15337330f729Sjoerg   OS << "{";
15347330f729Sjoerg   for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
15357330f729Sjoerg     if (i) OS << ", ";
15367330f729Sjoerg     if (Node->getInit(i))
15377330f729Sjoerg       PrintExpr(Node->getInit(i));
15387330f729Sjoerg     else
15397330f729Sjoerg       OS << "{}";
15407330f729Sjoerg   }
15417330f729Sjoerg   OS << "}";
15427330f729Sjoerg }
15437330f729Sjoerg 
VisitArrayInitLoopExpr(ArrayInitLoopExpr * Node)15447330f729Sjoerg void StmtPrinter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *Node) {
15457330f729Sjoerg   // There's no way to express this expression in any of our supported
15467330f729Sjoerg   // languages, so just emit something terse and (hopefully) clear.
15477330f729Sjoerg   OS << "{";
15487330f729Sjoerg   PrintExpr(Node->getSubExpr());
15497330f729Sjoerg   OS << "}";
15507330f729Sjoerg }
15517330f729Sjoerg 
VisitArrayInitIndexExpr(ArrayInitIndexExpr * Node)15527330f729Sjoerg void StmtPrinter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *Node) {
15537330f729Sjoerg   OS << "*";
15547330f729Sjoerg }
15557330f729Sjoerg 
VisitParenListExpr(ParenListExpr * Node)15567330f729Sjoerg void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
15577330f729Sjoerg   OS << "(";
15587330f729Sjoerg   for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {
15597330f729Sjoerg     if (i) OS << ", ";
15607330f729Sjoerg     PrintExpr(Node->getExpr(i));
15617330f729Sjoerg   }
15627330f729Sjoerg   OS << ")";
15637330f729Sjoerg }
15647330f729Sjoerg 
VisitDesignatedInitExpr(DesignatedInitExpr * Node)15657330f729Sjoerg void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
15667330f729Sjoerg   bool NeedsEquals = true;
15677330f729Sjoerg   for (const DesignatedInitExpr::Designator &D : Node->designators()) {
15687330f729Sjoerg     if (D.isFieldDesignator()) {
15697330f729Sjoerg       if (D.getDotLoc().isInvalid()) {
15707330f729Sjoerg         if (IdentifierInfo *II = D.getFieldName()) {
15717330f729Sjoerg           OS << II->getName() << ":";
15727330f729Sjoerg           NeedsEquals = false;
15737330f729Sjoerg         }
15747330f729Sjoerg       } else {
15757330f729Sjoerg         OS << "." << D.getFieldName()->getName();
15767330f729Sjoerg       }
15777330f729Sjoerg     } else {
15787330f729Sjoerg       OS << "[";
15797330f729Sjoerg       if (D.isArrayDesignator()) {
15807330f729Sjoerg         PrintExpr(Node->getArrayIndex(D));
15817330f729Sjoerg       } else {
15827330f729Sjoerg         PrintExpr(Node->getArrayRangeStart(D));
15837330f729Sjoerg         OS << " ... ";
15847330f729Sjoerg         PrintExpr(Node->getArrayRangeEnd(D));
15857330f729Sjoerg       }
15867330f729Sjoerg       OS << "]";
15877330f729Sjoerg     }
15887330f729Sjoerg   }
15897330f729Sjoerg 
15907330f729Sjoerg   if (NeedsEquals)
15917330f729Sjoerg     OS << " = ";
15927330f729Sjoerg   else
15937330f729Sjoerg     OS << " ";
15947330f729Sjoerg   PrintExpr(Node->getInit());
15957330f729Sjoerg }
15967330f729Sjoerg 
VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr * Node)15977330f729Sjoerg void StmtPrinter::VisitDesignatedInitUpdateExpr(
15987330f729Sjoerg     DesignatedInitUpdateExpr *Node) {
15997330f729Sjoerg   OS << "{";
16007330f729Sjoerg   OS << "/*base*/";
16017330f729Sjoerg   PrintExpr(Node->getBase());
16027330f729Sjoerg   OS << ", ";
16037330f729Sjoerg 
16047330f729Sjoerg   OS << "/*updater*/";
16057330f729Sjoerg   PrintExpr(Node->getUpdater());
16067330f729Sjoerg   OS << "}";
16077330f729Sjoerg }
16087330f729Sjoerg 
VisitNoInitExpr(NoInitExpr * Node)16097330f729Sjoerg void StmtPrinter::VisitNoInitExpr(NoInitExpr *Node) {
16107330f729Sjoerg   OS << "/*no init*/";
16117330f729Sjoerg }
16127330f729Sjoerg 
VisitImplicitValueInitExpr(ImplicitValueInitExpr * Node)16137330f729Sjoerg void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
16147330f729Sjoerg   if (Node->getType()->getAsCXXRecordDecl()) {
16157330f729Sjoerg     OS << "/*implicit*/";
16167330f729Sjoerg     Node->getType().print(OS, Policy);
16177330f729Sjoerg     OS << "()";
16187330f729Sjoerg   } else {
16197330f729Sjoerg     OS << "/*implicit*/(";
16207330f729Sjoerg     Node->getType().print(OS, Policy);
16217330f729Sjoerg     OS << ')';
16227330f729Sjoerg     if (Node->getType()->isRecordType())
16237330f729Sjoerg       OS << "{}";
16247330f729Sjoerg     else
16257330f729Sjoerg       OS << 0;
16267330f729Sjoerg   }
16277330f729Sjoerg }
16287330f729Sjoerg 
VisitVAArgExpr(VAArgExpr * Node)16297330f729Sjoerg void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
16307330f729Sjoerg   OS << "__builtin_va_arg(";
16317330f729Sjoerg   PrintExpr(Node->getSubExpr());
16327330f729Sjoerg   OS << ", ";
16337330f729Sjoerg   Node->getType().print(OS, Policy);
16347330f729Sjoerg   OS << ")";
16357330f729Sjoerg }
16367330f729Sjoerg 
VisitPseudoObjectExpr(PseudoObjectExpr * Node)16377330f729Sjoerg void StmtPrinter::VisitPseudoObjectExpr(PseudoObjectExpr *Node) {
16387330f729Sjoerg   PrintExpr(Node->getSyntacticForm());
16397330f729Sjoerg }
16407330f729Sjoerg 
VisitAtomicExpr(AtomicExpr * Node)16417330f729Sjoerg void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) {
16427330f729Sjoerg   const char *Name = nullptr;
16437330f729Sjoerg   switch (Node->getOp()) {
16447330f729Sjoerg #define BUILTIN(ID, TYPE, ATTRS)
16457330f729Sjoerg #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
16467330f729Sjoerg   case AtomicExpr::AO ## ID: \
16477330f729Sjoerg     Name = #ID "("; \
16487330f729Sjoerg     break;
16497330f729Sjoerg #include "clang/Basic/Builtins.def"
16507330f729Sjoerg   }
16517330f729Sjoerg   OS << Name;
16527330f729Sjoerg 
16537330f729Sjoerg   // AtomicExpr stores its subexpressions in a permuted order.
16547330f729Sjoerg   PrintExpr(Node->getPtr());
16557330f729Sjoerg   if (Node->getOp() != AtomicExpr::AO__c11_atomic_load &&
16567330f729Sjoerg       Node->getOp() != AtomicExpr::AO__atomic_load_n &&
16577330f729Sjoerg       Node->getOp() != AtomicExpr::AO__opencl_atomic_load) {
16587330f729Sjoerg     OS << ", ";
16597330f729Sjoerg     PrintExpr(Node->getVal1());
16607330f729Sjoerg   }
16617330f729Sjoerg   if (Node->getOp() == AtomicExpr::AO__atomic_exchange ||
16627330f729Sjoerg       Node->isCmpXChg()) {
16637330f729Sjoerg     OS << ", ";
16647330f729Sjoerg     PrintExpr(Node->getVal2());
16657330f729Sjoerg   }
16667330f729Sjoerg   if (Node->getOp() == AtomicExpr::AO__atomic_compare_exchange ||
16677330f729Sjoerg       Node->getOp() == AtomicExpr::AO__atomic_compare_exchange_n) {
16687330f729Sjoerg     OS << ", ";
16697330f729Sjoerg     PrintExpr(Node->getWeak());
16707330f729Sjoerg   }
16717330f729Sjoerg   if (Node->getOp() != AtomicExpr::AO__c11_atomic_init &&
16727330f729Sjoerg       Node->getOp() != AtomicExpr::AO__opencl_atomic_init) {
16737330f729Sjoerg     OS << ", ";
16747330f729Sjoerg     PrintExpr(Node->getOrder());
16757330f729Sjoerg   }
16767330f729Sjoerg   if (Node->isCmpXChg()) {
16777330f729Sjoerg     OS << ", ";
16787330f729Sjoerg     PrintExpr(Node->getOrderFail());
16797330f729Sjoerg   }
16807330f729Sjoerg   OS << ")";
16817330f729Sjoerg }
16827330f729Sjoerg 
16837330f729Sjoerg // C++
VisitCXXOperatorCallExpr(CXXOperatorCallExpr * Node)16847330f729Sjoerg void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
16857330f729Sjoerg   OverloadedOperatorKind Kind = Node->getOperator();
16867330f729Sjoerg   if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
16877330f729Sjoerg     if (Node->getNumArgs() == 1) {
16887330f729Sjoerg       OS << getOperatorSpelling(Kind) << ' ';
16897330f729Sjoerg       PrintExpr(Node->getArg(0));
16907330f729Sjoerg     } else {
16917330f729Sjoerg       PrintExpr(Node->getArg(0));
16927330f729Sjoerg       OS << ' ' << getOperatorSpelling(Kind);
16937330f729Sjoerg     }
16947330f729Sjoerg   } else if (Kind == OO_Arrow) {
16957330f729Sjoerg     PrintExpr(Node->getArg(0));
16967330f729Sjoerg   } else if (Kind == OO_Call) {
16977330f729Sjoerg     PrintExpr(Node->getArg(0));
16987330f729Sjoerg     OS << '(';
16997330f729Sjoerg     for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) {
17007330f729Sjoerg       if (ArgIdx > 1)
17017330f729Sjoerg         OS << ", ";
17027330f729Sjoerg       if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx)))
17037330f729Sjoerg         PrintExpr(Node->getArg(ArgIdx));
17047330f729Sjoerg     }
17057330f729Sjoerg     OS << ')';
17067330f729Sjoerg   } else if (Kind == OO_Subscript) {
17077330f729Sjoerg     PrintExpr(Node->getArg(0));
17087330f729Sjoerg     OS << '[';
17097330f729Sjoerg     PrintExpr(Node->getArg(1));
17107330f729Sjoerg     OS << ']';
17117330f729Sjoerg   } else if (Node->getNumArgs() == 1) {
17127330f729Sjoerg     OS << getOperatorSpelling(Kind) << ' ';
17137330f729Sjoerg     PrintExpr(Node->getArg(0));
17147330f729Sjoerg   } else if (Node->getNumArgs() == 2) {
17157330f729Sjoerg     PrintExpr(Node->getArg(0));
17167330f729Sjoerg     OS << ' ' << getOperatorSpelling(Kind) << ' ';
17177330f729Sjoerg     PrintExpr(Node->getArg(1));
17187330f729Sjoerg   } else {
17197330f729Sjoerg     llvm_unreachable("unknown overloaded operator");
17207330f729Sjoerg   }
17217330f729Sjoerg }
17227330f729Sjoerg 
VisitCXXMemberCallExpr(CXXMemberCallExpr * Node)17237330f729Sjoerg void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
17247330f729Sjoerg   // If we have a conversion operator call only print the argument.
17257330f729Sjoerg   CXXMethodDecl *MD = Node->getMethodDecl();
17267330f729Sjoerg   if (MD && isa<CXXConversionDecl>(MD)) {
17277330f729Sjoerg     PrintExpr(Node->getImplicitObjectArgument());
17287330f729Sjoerg     return;
17297330f729Sjoerg   }
17307330f729Sjoerg   VisitCallExpr(cast<CallExpr>(Node));
17317330f729Sjoerg }
17327330f729Sjoerg 
VisitCUDAKernelCallExpr(CUDAKernelCallExpr * Node)17337330f729Sjoerg void StmtPrinter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *Node) {
17347330f729Sjoerg   PrintExpr(Node->getCallee());
17357330f729Sjoerg   OS << "<<<";
17367330f729Sjoerg   PrintCallArgs(Node->getConfig());
17377330f729Sjoerg   OS << ">>>(";
17387330f729Sjoerg   PrintCallArgs(Node);
17397330f729Sjoerg   OS << ")";
17407330f729Sjoerg }
17417330f729Sjoerg 
VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator * Node)17427330f729Sjoerg void StmtPrinter::VisitCXXRewrittenBinaryOperator(
17437330f729Sjoerg     CXXRewrittenBinaryOperator *Node) {
17447330f729Sjoerg   CXXRewrittenBinaryOperator::DecomposedForm Decomposed =
17457330f729Sjoerg       Node->getDecomposedForm();
17467330f729Sjoerg   PrintExpr(const_cast<Expr*>(Decomposed.LHS));
17477330f729Sjoerg   OS << ' ' << BinaryOperator::getOpcodeStr(Decomposed.Opcode) << ' ';
17487330f729Sjoerg   PrintExpr(const_cast<Expr*>(Decomposed.RHS));
17497330f729Sjoerg }
17507330f729Sjoerg 
VisitCXXNamedCastExpr(CXXNamedCastExpr * Node)17517330f729Sjoerg void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
17527330f729Sjoerg   OS << Node->getCastName() << '<';
17537330f729Sjoerg   Node->getTypeAsWritten().print(OS, Policy);
17547330f729Sjoerg   OS << ">(";
17557330f729Sjoerg   PrintExpr(Node->getSubExpr());
17567330f729Sjoerg   OS << ")";
17577330f729Sjoerg }
17587330f729Sjoerg 
VisitCXXStaticCastExpr(CXXStaticCastExpr * Node)17597330f729Sjoerg void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {
17607330f729Sjoerg   VisitCXXNamedCastExpr(Node);
17617330f729Sjoerg }
17627330f729Sjoerg 
VisitCXXDynamicCastExpr(CXXDynamicCastExpr * Node)17637330f729Sjoerg void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {
17647330f729Sjoerg   VisitCXXNamedCastExpr(Node);
17657330f729Sjoerg }
17667330f729Sjoerg 
VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr * Node)17677330f729Sjoerg void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {
17687330f729Sjoerg   VisitCXXNamedCastExpr(Node);
17697330f729Sjoerg }
17707330f729Sjoerg 
VisitCXXConstCastExpr(CXXConstCastExpr * Node)17717330f729Sjoerg void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
17727330f729Sjoerg   VisitCXXNamedCastExpr(Node);
17737330f729Sjoerg }
17747330f729Sjoerg 
VisitBuiltinBitCastExpr(BuiltinBitCastExpr * Node)17757330f729Sjoerg void StmtPrinter::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *Node) {
17767330f729Sjoerg   OS << "__builtin_bit_cast(";
17777330f729Sjoerg   Node->getTypeInfoAsWritten()->getType().print(OS, Policy);
17787330f729Sjoerg   OS << ", ";
17797330f729Sjoerg   PrintExpr(Node->getSubExpr());
17807330f729Sjoerg   OS << ")";
17817330f729Sjoerg }
17827330f729Sjoerg 
VisitCXXAddrspaceCastExpr(CXXAddrspaceCastExpr * Node)1783*e038c9c4Sjoerg void StmtPrinter::VisitCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *Node) {
1784*e038c9c4Sjoerg   VisitCXXNamedCastExpr(Node);
1785*e038c9c4Sjoerg }
1786*e038c9c4Sjoerg 
VisitCXXTypeidExpr(CXXTypeidExpr * Node)17877330f729Sjoerg void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
17887330f729Sjoerg   OS << "typeid(";
17897330f729Sjoerg   if (Node->isTypeOperand()) {
17907330f729Sjoerg     Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
17917330f729Sjoerg   } else {
17927330f729Sjoerg     PrintExpr(Node->getExprOperand());
17937330f729Sjoerg   }
17947330f729Sjoerg   OS << ")";
17957330f729Sjoerg }
17967330f729Sjoerg 
VisitCXXUuidofExpr(CXXUuidofExpr * Node)17977330f729Sjoerg void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) {
17987330f729Sjoerg   OS << "__uuidof(";
17997330f729Sjoerg   if (Node->isTypeOperand()) {
18007330f729Sjoerg     Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
18017330f729Sjoerg   } else {
18027330f729Sjoerg     PrintExpr(Node->getExprOperand());
18037330f729Sjoerg   }
18047330f729Sjoerg   OS << ")";
18057330f729Sjoerg }
18067330f729Sjoerg 
VisitMSPropertyRefExpr(MSPropertyRefExpr * Node)18077330f729Sjoerg void StmtPrinter::VisitMSPropertyRefExpr(MSPropertyRefExpr *Node) {
18087330f729Sjoerg   PrintExpr(Node->getBaseExpr());
18097330f729Sjoerg   if (Node->isArrow())
18107330f729Sjoerg     OS << "->";
18117330f729Sjoerg   else
18127330f729Sjoerg     OS << ".";
18137330f729Sjoerg   if (NestedNameSpecifier *Qualifier =
18147330f729Sjoerg       Node->getQualifierLoc().getNestedNameSpecifier())
18157330f729Sjoerg     Qualifier->print(OS, Policy);
18167330f729Sjoerg   OS << Node->getPropertyDecl()->getDeclName();
18177330f729Sjoerg }
18187330f729Sjoerg 
VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr * Node)18197330f729Sjoerg void StmtPrinter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *Node) {
18207330f729Sjoerg   PrintExpr(Node->getBase());
18217330f729Sjoerg   OS << "[";
18227330f729Sjoerg   PrintExpr(Node->getIdx());
18237330f729Sjoerg   OS << "]";
18247330f729Sjoerg }
18257330f729Sjoerg 
VisitUserDefinedLiteral(UserDefinedLiteral * Node)18267330f729Sjoerg void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) {
18277330f729Sjoerg   switch (Node->getLiteralOperatorKind()) {
18287330f729Sjoerg   case UserDefinedLiteral::LOK_Raw:
18297330f729Sjoerg     OS << cast<StringLiteral>(Node->getArg(0)->IgnoreImpCasts())->getString();
18307330f729Sjoerg     break;
18317330f729Sjoerg   case UserDefinedLiteral::LOK_Template: {
18327330f729Sjoerg     const auto *DRE = cast<DeclRefExpr>(Node->getCallee()->IgnoreImpCasts());
18337330f729Sjoerg     const TemplateArgumentList *Args =
18347330f729Sjoerg       cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs();
18357330f729Sjoerg     assert(Args);
18367330f729Sjoerg 
18377330f729Sjoerg     if (Args->size() != 1) {
1838*e038c9c4Sjoerg       const TemplateParameterList *TPL = nullptr;
1839*e038c9c4Sjoerg       if (!DRE->hadMultipleCandidates())
1840*e038c9c4Sjoerg         if (const auto *TD = dyn_cast<TemplateDecl>(DRE->getDecl()))
1841*e038c9c4Sjoerg           TPL = TD->getTemplateParameters();
18427330f729Sjoerg       OS << "operator\"\"" << Node->getUDSuffix()->getName();
1843*e038c9c4Sjoerg       printTemplateArgumentList(OS, Args->asArray(), Policy, TPL);
18447330f729Sjoerg       OS << "()";
18457330f729Sjoerg       return;
18467330f729Sjoerg     }
18477330f729Sjoerg 
18487330f729Sjoerg     const TemplateArgument &Pack = Args->get(0);
18497330f729Sjoerg     for (const auto &P : Pack.pack_elements()) {
18507330f729Sjoerg       char C = (char)P.getAsIntegral().getZExtValue();
18517330f729Sjoerg       OS << C;
18527330f729Sjoerg     }
18537330f729Sjoerg     break;
18547330f729Sjoerg   }
18557330f729Sjoerg   case UserDefinedLiteral::LOK_Integer: {
18567330f729Sjoerg     // Print integer literal without suffix.
18577330f729Sjoerg     const auto *Int = cast<IntegerLiteral>(Node->getCookedLiteral());
18587330f729Sjoerg     OS << Int->getValue().toString(10, /*isSigned*/false);
18597330f729Sjoerg     break;
18607330f729Sjoerg   }
18617330f729Sjoerg   case UserDefinedLiteral::LOK_Floating: {
18627330f729Sjoerg     // Print floating literal without suffix.
18637330f729Sjoerg     auto *Float = cast<FloatingLiteral>(Node->getCookedLiteral());
18647330f729Sjoerg     PrintFloatingLiteral(OS, Float, /*PrintSuffix=*/false);
18657330f729Sjoerg     break;
18667330f729Sjoerg   }
18677330f729Sjoerg   case UserDefinedLiteral::LOK_String:
18687330f729Sjoerg   case UserDefinedLiteral::LOK_Character:
18697330f729Sjoerg     PrintExpr(Node->getCookedLiteral());
18707330f729Sjoerg     break;
18717330f729Sjoerg   }
18727330f729Sjoerg   OS << Node->getUDSuffix()->getName();
18737330f729Sjoerg }
18747330f729Sjoerg 
VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr * Node)18757330f729Sjoerg void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
18767330f729Sjoerg   OS << (Node->getValue() ? "true" : "false");
18777330f729Sjoerg }
18787330f729Sjoerg 
VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr * Node)18797330f729Sjoerg void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
18807330f729Sjoerg   OS << "nullptr";
18817330f729Sjoerg }
18827330f729Sjoerg 
VisitCXXThisExpr(CXXThisExpr * Node)18837330f729Sjoerg void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
18847330f729Sjoerg   OS << "this";
18857330f729Sjoerg }
18867330f729Sjoerg 
VisitCXXThrowExpr(CXXThrowExpr * Node)18877330f729Sjoerg void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
18887330f729Sjoerg   if (!Node->getSubExpr())
18897330f729Sjoerg     OS << "throw";
18907330f729Sjoerg   else {
18917330f729Sjoerg     OS << "throw ";
18927330f729Sjoerg     PrintExpr(Node->getSubExpr());
18937330f729Sjoerg   }
18947330f729Sjoerg }
18957330f729Sjoerg 
VisitCXXDefaultArgExpr(CXXDefaultArgExpr * Node)18967330f729Sjoerg void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
18977330f729Sjoerg   // Nothing to print: we picked up the default argument.
18987330f729Sjoerg }
18997330f729Sjoerg 
VisitCXXDefaultInitExpr(CXXDefaultInitExpr * Node)19007330f729Sjoerg void StmtPrinter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Node) {
19017330f729Sjoerg   // Nothing to print: we picked up the default initializer.
19027330f729Sjoerg }
19037330f729Sjoerg 
VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr * Node)19047330f729Sjoerg void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
19057330f729Sjoerg   Node->getType().print(OS, Policy);
19067330f729Sjoerg   // If there are no parens, this is list-initialization, and the braces are
19077330f729Sjoerg   // part of the syntax of the inner construct.
19087330f729Sjoerg   if (Node->getLParenLoc().isValid())
19097330f729Sjoerg     OS << "(";
19107330f729Sjoerg   PrintExpr(Node->getSubExpr());
19117330f729Sjoerg   if (Node->getLParenLoc().isValid())
19127330f729Sjoerg     OS << ")";
19137330f729Sjoerg }
19147330f729Sjoerg 
VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr * Node)19157330f729Sjoerg void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
19167330f729Sjoerg   PrintExpr(Node->getSubExpr());
19177330f729Sjoerg }
19187330f729Sjoerg 
VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr * Node)19197330f729Sjoerg void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
19207330f729Sjoerg   Node->getType().print(OS, Policy);
19217330f729Sjoerg   if (Node->isStdInitListInitialization())
19227330f729Sjoerg     /* Nothing to do; braces are part of creating the std::initializer_list. */;
19237330f729Sjoerg   else if (Node->isListInitialization())
19247330f729Sjoerg     OS << "{";
19257330f729Sjoerg   else
19267330f729Sjoerg     OS << "(";
19277330f729Sjoerg   for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),
19287330f729Sjoerg                                          ArgEnd = Node->arg_end();
19297330f729Sjoerg        Arg != ArgEnd; ++Arg) {
19307330f729Sjoerg     if ((*Arg)->isDefaultArgument())
19317330f729Sjoerg       break;
19327330f729Sjoerg     if (Arg != Node->arg_begin())
19337330f729Sjoerg       OS << ", ";
19347330f729Sjoerg     PrintExpr(*Arg);
19357330f729Sjoerg   }
19367330f729Sjoerg   if (Node->isStdInitListInitialization())
19377330f729Sjoerg     /* See above. */;
19387330f729Sjoerg   else if (Node->isListInitialization())
19397330f729Sjoerg     OS << "}";
19407330f729Sjoerg   else
19417330f729Sjoerg     OS << ")";
19427330f729Sjoerg }
19437330f729Sjoerg 
VisitLambdaExpr(LambdaExpr * Node)19447330f729Sjoerg void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {
19457330f729Sjoerg   OS << '[';
19467330f729Sjoerg   bool NeedComma = false;
19477330f729Sjoerg   switch (Node->getCaptureDefault()) {
19487330f729Sjoerg   case LCD_None:
19497330f729Sjoerg     break;
19507330f729Sjoerg 
19517330f729Sjoerg   case LCD_ByCopy:
19527330f729Sjoerg     OS << '=';
19537330f729Sjoerg     NeedComma = true;
19547330f729Sjoerg     break;
19557330f729Sjoerg 
19567330f729Sjoerg   case LCD_ByRef:
19577330f729Sjoerg     OS << '&';
19587330f729Sjoerg     NeedComma = true;
19597330f729Sjoerg     break;
19607330f729Sjoerg   }
19617330f729Sjoerg   for (LambdaExpr::capture_iterator C = Node->explicit_capture_begin(),
19627330f729Sjoerg                                  CEnd = Node->explicit_capture_end();
19637330f729Sjoerg        C != CEnd;
19647330f729Sjoerg        ++C) {
19657330f729Sjoerg     if (C->capturesVLAType())
19667330f729Sjoerg       continue;
19677330f729Sjoerg 
19687330f729Sjoerg     if (NeedComma)
19697330f729Sjoerg       OS << ", ";
19707330f729Sjoerg     NeedComma = true;
19717330f729Sjoerg 
19727330f729Sjoerg     switch (C->getCaptureKind()) {
19737330f729Sjoerg     case LCK_This:
19747330f729Sjoerg       OS << "this";
19757330f729Sjoerg       break;
19767330f729Sjoerg 
19777330f729Sjoerg     case LCK_StarThis:
19787330f729Sjoerg       OS << "*this";
19797330f729Sjoerg       break;
19807330f729Sjoerg 
19817330f729Sjoerg     case LCK_ByRef:
19827330f729Sjoerg       if (Node->getCaptureDefault() != LCD_ByRef || Node->isInitCapture(C))
19837330f729Sjoerg         OS << '&';
19847330f729Sjoerg       OS << C->getCapturedVar()->getName();
19857330f729Sjoerg       break;
19867330f729Sjoerg 
19877330f729Sjoerg     case LCK_ByCopy:
19887330f729Sjoerg       OS << C->getCapturedVar()->getName();
19897330f729Sjoerg       break;
19907330f729Sjoerg 
19917330f729Sjoerg     case LCK_VLAType:
19927330f729Sjoerg       llvm_unreachable("VLA type in explicit captures.");
19937330f729Sjoerg     }
19947330f729Sjoerg 
19957330f729Sjoerg     if (C->isPackExpansion())
19967330f729Sjoerg       OS << "...";
19977330f729Sjoerg 
1998*e038c9c4Sjoerg     if (Node->isInitCapture(C)) {
1999*e038c9c4Sjoerg       VarDecl *D = C->getCapturedVar();
2000*e038c9c4Sjoerg 
2001*e038c9c4Sjoerg       llvm::StringRef Pre;
2002*e038c9c4Sjoerg       llvm::StringRef Post;
2003*e038c9c4Sjoerg       if (D->getInitStyle() == VarDecl::CallInit &&
2004*e038c9c4Sjoerg           !isa<ParenListExpr>(D->getInit())) {
2005*e038c9c4Sjoerg         Pre = "(";
2006*e038c9c4Sjoerg         Post = ")";
2007*e038c9c4Sjoerg       } else if (D->getInitStyle() == VarDecl::CInit) {
2008*e038c9c4Sjoerg         Pre = " = ";
2009*e038c9c4Sjoerg       }
2010*e038c9c4Sjoerg 
2011*e038c9c4Sjoerg       OS << Pre;
2012*e038c9c4Sjoerg       PrintExpr(D->getInit());
2013*e038c9c4Sjoerg       OS << Post;
2014*e038c9c4Sjoerg     }
20157330f729Sjoerg   }
20167330f729Sjoerg   OS << ']';
20177330f729Sjoerg 
20187330f729Sjoerg   if (!Node->getExplicitTemplateParameters().empty()) {
20197330f729Sjoerg     Node->getTemplateParameterList()->print(
20207330f729Sjoerg         OS, Node->getLambdaClass()->getASTContext(),
20217330f729Sjoerg         /*OmitTemplateKW*/true);
20227330f729Sjoerg   }
20237330f729Sjoerg 
20247330f729Sjoerg   if (Node->hasExplicitParameters()) {
20257330f729Sjoerg     OS << '(';
20267330f729Sjoerg     CXXMethodDecl *Method = Node->getCallOperator();
20277330f729Sjoerg     NeedComma = false;
20287330f729Sjoerg     for (const auto *P : Method->parameters()) {
20297330f729Sjoerg       if (NeedComma) {
20307330f729Sjoerg         OS << ", ";
20317330f729Sjoerg       } else {
20327330f729Sjoerg         NeedComma = true;
20337330f729Sjoerg       }
20347330f729Sjoerg       std::string ParamStr = P->getNameAsString();
20357330f729Sjoerg       P->getOriginalType().print(OS, Policy, ParamStr);
20367330f729Sjoerg     }
20377330f729Sjoerg     if (Method->isVariadic()) {
20387330f729Sjoerg       if (NeedComma)
20397330f729Sjoerg         OS << ", ";
20407330f729Sjoerg       OS << "...";
20417330f729Sjoerg     }
20427330f729Sjoerg     OS << ')';
20437330f729Sjoerg 
20447330f729Sjoerg     if (Node->isMutable())
20457330f729Sjoerg       OS << " mutable";
20467330f729Sjoerg 
20477330f729Sjoerg     auto *Proto = Method->getType()->castAs<FunctionProtoType>();
20487330f729Sjoerg     Proto->printExceptionSpecification(OS, Policy);
20497330f729Sjoerg 
20507330f729Sjoerg     // FIXME: Attributes
20517330f729Sjoerg 
20527330f729Sjoerg     // Print the trailing return type if it was specified in the source.
20537330f729Sjoerg     if (Node->hasExplicitResultType()) {
20547330f729Sjoerg       OS << " -> ";
20557330f729Sjoerg       Proto->getReturnType().print(OS, Policy);
20567330f729Sjoerg     }
20577330f729Sjoerg   }
20587330f729Sjoerg 
20597330f729Sjoerg   // Print the body.
20607330f729Sjoerg   OS << ' ';
20617330f729Sjoerg   if (Policy.TerseOutput)
20627330f729Sjoerg     OS << "{}";
20637330f729Sjoerg   else
2064*e038c9c4Sjoerg     PrintRawCompoundStmt(Node->getCompoundStmtBody());
20657330f729Sjoerg }
20667330f729Sjoerg 
VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr * Node)20677330f729Sjoerg void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) {
20687330f729Sjoerg   if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo())
20697330f729Sjoerg     TSInfo->getType().print(OS, Policy);
20707330f729Sjoerg   else
20717330f729Sjoerg     Node->getType().print(OS, Policy);
20727330f729Sjoerg   OS << "()";
20737330f729Sjoerg }
20747330f729Sjoerg 
VisitCXXNewExpr(CXXNewExpr * E)20757330f729Sjoerg void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
20767330f729Sjoerg   if (E->isGlobalNew())
20777330f729Sjoerg     OS << "::";
20787330f729Sjoerg   OS << "new ";
20797330f729Sjoerg   unsigned NumPlace = E->getNumPlacementArgs();
20807330f729Sjoerg   if (NumPlace > 0 && !isa<CXXDefaultArgExpr>(E->getPlacementArg(0))) {
20817330f729Sjoerg     OS << "(";
20827330f729Sjoerg     PrintExpr(E->getPlacementArg(0));
20837330f729Sjoerg     for (unsigned i = 1; i < NumPlace; ++i) {
20847330f729Sjoerg       if (isa<CXXDefaultArgExpr>(E->getPlacementArg(i)))
20857330f729Sjoerg         break;
20867330f729Sjoerg       OS << ", ";
20877330f729Sjoerg       PrintExpr(E->getPlacementArg(i));
20887330f729Sjoerg     }
20897330f729Sjoerg     OS << ") ";
20907330f729Sjoerg   }
20917330f729Sjoerg   if (E->isParenTypeId())
20927330f729Sjoerg     OS << "(";
20937330f729Sjoerg   std::string TypeS;
20947330f729Sjoerg   if (Optional<Expr *> Size = E->getArraySize()) {
20957330f729Sjoerg     llvm::raw_string_ostream s(TypeS);
20967330f729Sjoerg     s << '[';
20977330f729Sjoerg     if (*Size)
20987330f729Sjoerg       (*Size)->printPretty(s, Helper, Policy);
20997330f729Sjoerg     s << ']';
21007330f729Sjoerg   }
21017330f729Sjoerg   E->getAllocatedType().print(OS, Policy, TypeS);
21027330f729Sjoerg   if (E->isParenTypeId())
21037330f729Sjoerg     OS << ")";
21047330f729Sjoerg 
21057330f729Sjoerg   CXXNewExpr::InitializationStyle InitStyle = E->getInitializationStyle();
21067330f729Sjoerg   if (InitStyle) {
21077330f729Sjoerg     if (InitStyle == CXXNewExpr::CallInit)
21087330f729Sjoerg       OS << "(";
21097330f729Sjoerg     PrintExpr(E->getInitializer());
21107330f729Sjoerg     if (InitStyle == CXXNewExpr::CallInit)
21117330f729Sjoerg       OS << ")";
21127330f729Sjoerg   }
21137330f729Sjoerg }
21147330f729Sjoerg 
VisitCXXDeleteExpr(CXXDeleteExpr * E)21157330f729Sjoerg void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
21167330f729Sjoerg   if (E->isGlobalDelete())
21177330f729Sjoerg     OS << "::";
21187330f729Sjoerg   OS << "delete ";
21197330f729Sjoerg   if (E->isArrayForm())
21207330f729Sjoerg     OS << "[] ";
21217330f729Sjoerg   PrintExpr(E->getArgument());
21227330f729Sjoerg }
21237330f729Sjoerg 
VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr * E)21247330f729Sjoerg void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
21257330f729Sjoerg   PrintExpr(E->getBase());
21267330f729Sjoerg   if (E->isArrow())
21277330f729Sjoerg     OS << "->";
21287330f729Sjoerg   else
21297330f729Sjoerg     OS << '.';
21307330f729Sjoerg   if (E->getQualifier())
21317330f729Sjoerg     E->getQualifier()->print(OS, Policy);
21327330f729Sjoerg   OS << "~";
21337330f729Sjoerg 
21347330f729Sjoerg   if (IdentifierInfo *II = E->getDestroyedTypeIdentifier())
21357330f729Sjoerg     OS << II->getName();
21367330f729Sjoerg   else
21377330f729Sjoerg     E->getDestroyedType().print(OS, Policy);
21387330f729Sjoerg }
21397330f729Sjoerg 
VisitCXXConstructExpr(CXXConstructExpr * E)21407330f729Sjoerg void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
21417330f729Sjoerg   if (E->isListInitialization() && !E->isStdInitListInitialization())
21427330f729Sjoerg     OS << "{";
21437330f729Sjoerg 
21447330f729Sjoerg   for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
21457330f729Sjoerg     if (isa<CXXDefaultArgExpr>(E->getArg(i))) {
21467330f729Sjoerg       // Don't print any defaulted arguments
21477330f729Sjoerg       break;
21487330f729Sjoerg     }
21497330f729Sjoerg 
21507330f729Sjoerg     if (i) OS << ", ";
21517330f729Sjoerg     PrintExpr(E->getArg(i));
21527330f729Sjoerg   }
21537330f729Sjoerg 
21547330f729Sjoerg   if (E->isListInitialization() && !E->isStdInitListInitialization())
21557330f729Sjoerg     OS << "}";
21567330f729Sjoerg }
21577330f729Sjoerg 
VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr * E)21587330f729Sjoerg void StmtPrinter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {
21597330f729Sjoerg   // Parens are printed by the surrounding context.
21607330f729Sjoerg   OS << "<forwarded>";
21617330f729Sjoerg }
21627330f729Sjoerg 
VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr * E)21637330f729Sjoerg void StmtPrinter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
21647330f729Sjoerg   PrintExpr(E->getSubExpr());
21657330f729Sjoerg }
21667330f729Sjoerg 
VisitExprWithCleanups(ExprWithCleanups * E)21677330f729Sjoerg void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) {
21687330f729Sjoerg   // Just forward to the subexpression.
21697330f729Sjoerg   PrintExpr(E->getSubExpr());
21707330f729Sjoerg }
21717330f729Sjoerg 
21727330f729Sjoerg void
VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr * Node)21737330f729Sjoerg StmtPrinter::VisitCXXUnresolvedConstructExpr(
21747330f729Sjoerg                                            CXXUnresolvedConstructExpr *Node) {
21757330f729Sjoerg   Node->getTypeAsWritten().print(OS, Policy);
21767330f729Sjoerg   OS << "(";
21777330f729Sjoerg   for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(),
21787330f729Sjoerg                                              ArgEnd = Node->arg_end();
21797330f729Sjoerg        Arg != ArgEnd; ++Arg) {
21807330f729Sjoerg     if (Arg != Node->arg_begin())
21817330f729Sjoerg       OS << ", ";
21827330f729Sjoerg     PrintExpr(*Arg);
21837330f729Sjoerg   }
21847330f729Sjoerg   OS << ")";
21857330f729Sjoerg }
21867330f729Sjoerg 
VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr * Node)21877330f729Sjoerg void StmtPrinter::VisitCXXDependentScopeMemberExpr(
21887330f729Sjoerg                                          CXXDependentScopeMemberExpr *Node) {
21897330f729Sjoerg   if (!Node->isImplicitAccess()) {
21907330f729Sjoerg     PrintExpr(Node->getBase());
21917330f729Sjoerg     OS << (Node->isArrow() ? "->" : ".");
21927330f729Sjoerg   }
21937330f729Sjoerg   if (NestedNameSpecifier *Qualifier = Node->getQualifier())
21947330f729Sjoerg     Qualifier->print(OS, Policy);
21957330f729Sjoerg   if (Node->hasTemplateKeyword())
21967330f729Sjoerg     OS << "template ";
21977330f729Sjoerg   OS << Node->getMemberNameInfo();
21987330f729Sjoerg   if (Node->hasExplicitTemplateArgs())
21997330f729Sjoerg     printTemplateArgumentList(OS, Node->template_arguments(), Policy);
22007330f729Sjoerg }
22017330f729Sjoerg 
VisitUnresolvedMemberExpr(UnresolvedMemberExpr * Node)22027330f729Sjoerg void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
22037330f729Sjoerg   if (!Node->isImplicitAccess()) {
22047330f729Sjoerg     PrintExpr(Node->getBase());
22057330f729Sjoerg     OS << (Node->isArrow() ? "->" : ".");
22067330f729Sjoerg   }
22077330f729Sjoerg   if (NestedNameSpecifier *Qualifier = Node->getQualifier())
22087330f729Sjoerg     Qualifier->print(OS, Policy);
22097330f729Sjoerg   if (Node->hasTemplateKeyword())
22107330f729Sjoerg     OS << "template ";
22117330f729Sjoerg   OS << Node->getMemberNameInfo();
22127330f729Sjoerg   if (Node->hasExplicitTemplateArgs())
22137330f729Sjoerg     printTemplateArgumentList(OS, Node->template_arguments(), Policy);
22147330f729Sjoerg }
22157330f729Sjoerg 
VisitTypeTraitExpr(TypeTraitExpr * E)22167330f729Sjoerg void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) {
2217*e038c9c4Sjoerg   OS << getTraitSpelling(E->getTrait()) << "(";
22187330f729Sjoerg   for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
22197330f729Sjoerg     if (I > 0)
22207330f729Sjoerg       OS << ", ";
22217330f729Sjoerg     E->getArg(I)->getType().print(OS, Policy);
22227330f729Sjoerg   }
22237330f729Sjoerg   OS << ")";
22247330f729Sjoerg }
22257330f729Sjoerg 
VisitArrayTypeTraitExpr(ArrayTypeTraitExpr * E)22267330f729Sjoerg void StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
2227*e038c9c4Sjoerg   OS << getTraitSpelling(E->getTrait()) << '(';
22287330f729Sjoerg   E->getQueriedType().print(OS, Policy);
22297330f729Sjoerg   OS << ')';
22307330f729Sjoerg }
22317330f729Sjoerg 
VisitExpressionTraitExpr(ExpressionTraitExpr * E)22327330f729Sjoerg void StmtPrinter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
2233*e038c9c4Sjoerg   OS << getTraitSpelling(E->getTrait()) << '(';
22347330f729Sjoerg   PrintExpr(E->getQueriedExpression());
22357330f729Sjoerg   OS << ')';
22367330f729Sjoerg }
22377330f729Sjoerg 
VisitCXXNoexceptExpr(CXXNoexceptExpr * E)22387330f729Sjoerg void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
22397330f729Sjoerg   OS << "noexcept(";
22407330f729Sjoerg   PrintExpr(E->getOperand());
22417330f729Sjoerg   OS << ")";
22427330f729Sjoerg }
22437330f729Sjoerg 
VisitPackExpansionExpr(PackExpansionExpr * E)22447330f729Sjoerg void StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) {
22457330f729Sjoerg   PrintExpr(E->getPattern());
22467330f729Sjoerg   OS << "...";
22477330f729Sjoerg }
22487330f729Sjoerg 
VisitSizeOfPackExpr(SizeOfPackExpr * E)22497330f729Sjoerg void StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
22507330f729Sjoerg   OS << "sizeof...(" << *E->getPack() << ")";
22517330f729Sjoerg }
22527330f729Sjoerg 
VisitSubstNonTypeTemplateParmPackExpr(SubstNonTypeTemplateParmPackExpr * Node)22537330f729Sjoerg void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr(
22547330f729Sjoerg                                        SubstNonTypeTemplateParmPackExpr *Node) {
22557330f729Sjoerg   OS << *Node->getParameterPack();
22567330f729Sjoerg }
22577330f729Sjoerg 
VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr * Node)22587330f729Sjoerg void StmtPrinter::VisitSubstNonTypeTemplateParmExpr(
22597330f729Sjoerg                                        SubstNonTypeTemplateParmExpr *Node) {
22607330f729Sjoerg   Visit(Node->getReplacement());
22617330f729Sjoerg }
22627330f729Sjoerg 
VisitFunctionParmPackExpr(FunctionParmPackExpr * E)22637330f729Sjoerg void StmtPrinter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
22647330f729Sjoerg   OS << *E->getParameterPack();
22657330f729Sjoerg }
22667330f729Sjoerg 
VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr * Node)22677330f729Sjoerg void StmtPrinter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *Node){
2268*e038c9c4Sjoerg   PrintExpr(Node->getSubExpr());
22697330f729Sjoerg }
22707330f729Sjoerg 
VisitCXXFoldExpr(CXXFoldExpr * E)22717330f729Sjoerg void StmtPrinter::VisitCXXFoldExpr(CXXFoldExpr *E) {
22727330f729Sjoerg   OS << "(";
22737330f729Sjoerg   if (E->getLHS()) {
22747330f729Sjoerg     PrintExpr(E->getLHS());
22757330f729Sjoerg     OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
22767330f729Sjoerg   }
22777330f729Sjoerg   OS << "...";
22787330f729Sjoerg   if (E->getRHS()) {
22797330f729Sjoerg     OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
22807330f729Sjoerg     PrintExpr(E->getRHS());
22817330f729Sjoerg   }
22827330f729Sjoerg   OS << ")";
22837330f729Sjoerg }
22847330f729Sjoerg 
VisitConceptSpecializationExpr(ConceptSpecializationExpr * E)22857330f729Sjoerg void StmtPrinter::VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) {
22867330f729Sjoerg   NestedNameSpecifierLoc NNS = E->getNestedNameSpecifierLoc();
22877330f729Sjoerg   if (NNS)
22887330f729Sjoerg     NNS.getNestedNameSpecifier()->print(OS, Policy);
22897330f729Sjoerg   if (E->getTemplateKWLoc().isValid())
22907330f729Sjoerg     OS << "template ";
22917330f729Sjoerg   OS << E->getFoundDecl()->getName();
22927330f729Sjoerg   printTemplateArgumentList(OS, E->getTemplateArgsAsWritten()->arguments(),
2293*e038c9c4Sjoerg                             Policy,
2294*e038c9c4Sjoerg                             E->getNamedConcept()->getTemplateParameters());
2295*e038c9c4Sjoerg }
2296*e038c9c4Sjoerg 
VisitRequiresExpr(RequiresExpr * E)2297*e038c9c4Sjoerg void StmtPrinter::VisitRequiresExpr(RequiresExpr *E) {
2298*e038c9c4Sjoerg   OS << "requires ";
2299*e038c9c4Sjoerg   auto LocalParameters = E->getLocalParameters();
2300*e038c9c4Sjoerg   if (!LocalParameters.empty()) {
2301*e038c9c4Sjoerg     OS << "(";
2302*e038c9c4Sjoerg     for (ParmVarDecl *LocalParam : LocalParameters) {
2303*e038c9c4Sjoerg       PrintRawDecl(LocalParam);
2304*e038c9c4Sjoerg       if (LocalParam != LocalParameters.back())
2305*e038c9c4Sjoerg         OS << ", ";
2306*e038c9c4Sjoerg     }
2307*e038c9c4Sjoerg 
2308*e038c9c4Sjoerg     OS << ") ";
2309*e038c9c4Sjoerg   }
2310*e038c9c4Sjoerg   OS << "{ ";
2311*e038c9c4Sjoerg   auto Requirements = E->getRequirements();
2312*e038c9c4Sjoerg   for (concepts::Requirement *Req : Requirements) {
2313*e038c9c4Sjoerg     if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
2314*e038c9c4Sjoerg       if (TypeReq->isSubstitutionFailure())
2315*e038c9c4Sjoerg         OS << "<<error-type>>";
2316*e038c9c4Sjoerg       else
2317*e038c9c4Sjoerg         TypeReq->getType()->getType().print(OS, Policy);
2318*e038c9c4Sjoerg     } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
2319*e038c9c4Sjoerg       if (ExprReq->isCompound())
2320*e038c9c4Sjoerg         OS << "{ ";
2321*e038c9c4Sjoerg       if (ExprReq->isExprSubstitutionFailure())
2322*e038c9c4Sjoerg         OS << "<<error-expression>>";
2323*e038c9c4Sjoerg       else
2324*e038c9c4Sjoerg         PrintExpr(ExprReq->getExpr());
2325*e038c9c4Sjoerg       if (ExprReq->isCompound()) {
2326*e038c9c4Sjoerg         OS << " }";
2327*e038c9c4Sjoerg         if (ExprReq->getNoexceptLoc().isValid())
2328*e038c9c4Sjoerg           OS << " noexcept";
2329*e038c9c4Sjoerg         const auto &RetReq = ExprReq->getReturnTypeRequirement();
2330*e038c9c4Sjoerg         if (!RetReq.isEmpty()) {
2331*e038c9c4Sjoerg           OS << " -> ";
2332*e038c9c4Sjoerg           if (RetReq.isSubstitutionFailure())
2333*e038c9c4Sjoerg             OS << "<<error-type>>";
2334*e038c9c4Sjoerg           else if (RetReq.isTypeConstraint())
2335*e038c9c4Sjoerg             RetReq.getTypeConstraint()->print(OS, Policy);
2336*e038c9c4Sjoerg         }
2337*e038c9c4Sjoerg       }
2338*e038c9c4Sjoerg     } else {
2339*e038c9c4Sjoerg       auto *NestedReq = cast<concepts::NestedRequirement>(Req);
2340*e038c9c4Sjoerg       OS << "requires ";
2341*e038c9c4Sjoerg       if (NestedReq->isSubstitutionFailure())
2342*e038c9c4Sjoerg         OS << "<<error-expression>>";
2343*e038c9c4Sjoerg       else
2344*e038c9c4Sjoerg         PrintExpr(NestedReq->getConstraintExpr());
2345*e038c9c4Sjoerg     }
2346*e038c9c4Sjoerg     OS << "; ";
2347*e038c9c4Sjoerg   }
2348*e038c9c4Sjoerg   OS << "}";
23497330f729Sjoerg }
23507330f729Sjoerg 
23517330f729Sjoerg // C++ Coroutines TS
23527330f729Sjoerg 
VisitCoroutineBodyStmt(CoroutineBodyStmt * S)23537330f729Sjoerg void StmtPrinter::VisitCoroutineBodyStmt(CoroutineBodyStmt *S) {
23547330f729Sjoerg   Visit(S->getBody());
23557330f729Sjoerg }
23567330f729Sjoerg 
VisitCoreturnStmt(CoreturnStmt * S)23577330f729Sjoerg void StmtPrinter::VisitCoreturnStmt(CoreturnStmt *S) {
23587330f729Sjoerg   OS << "co_return";
23597330f729Sjoerg   if (S->getOperand()) {
23607330f729Sjoerg     OS << " ";
23617330f729Sjoerg     Visit(S->getOperand());
23627330f729Sjoerg   }
23637330f729Sjoerg   OS << ";";
23647330f729Sjoerg }
23657330f729Sjoerg 
VisitCoawaitExpr(CoawaitExpr * S)23667330f729Sjoerg void StmtPrinter::VisitCoawaitExpr(CoawaitExpr *S) {
23677330f729Sjoerg   OS << "co_await ";
23687330f729Sjoerg   PrintExpr(S->getOperand());
23697330f729Sjoerg }
23707330f729Sjoerg 
VisitDependentCoawaitExpr(DependentCoawaitExpr * S)23717330f729Sjoerg void StmtPrinter::VisitDependentCoawaitExpr(DependentCoawaitExpr *S) {
23727330f729Sjoerg   OS << "co_await ";
23737330f729Sjoerg   PrintExpr(S->getOperand());
23747330f729Sjoerg }
23757330f729Sjoerg 
VisitCoyieldExpr(CoyieldExpr * S)23767330f729Sjoerg void StmtPrinter::VisitCoyieldExpr(CoyieldExpr *S) {
23777330f729Sjoerg   OS << "co_yield ";
23787330f729Sjoerg   PrintExpr(S->getOperand());
23797330f729Sjoerg }
23807330f729Sjoerg 
23817330f729Sjoerg // Obj-C
23827330f729Sjoerg 
VisitObjCStringLiteral(ObjCStringLiteral * Node)23837330f729Sjoerg void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
23847330f729Sjoerg   OS << "@";
23857330f729Sjoerg   VisitStringLiteral(Node->getString());
23867330f729Sjoerg }
23877330f729Sjoerg 
VisitObjCBoxedExpr(ObjCBoxedExpr * E)23887330f729Sjoerg void StmtPrinter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
23897330f729Sjoerg   OS << "@";
23907330f729Sjoerg   Visit(E->getSubExpr());
23917330f729Sjoerg }
23927330f729Sjoerg 
VisitObjCArrayLiteral(ObjCArrayLiteral * E)23937330f729Sjoerg void StmtPrinter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
23947330f729Sjoerg   OS << "@[ ";
23957330f729Sjoerg   ObjCArrayLiteral::child_range Ch = E->children();
23967330f729Sjoerg   for (auto I = Ch.begin(), E = Ch.end(); I != E; ++I) {
23977330f729Sjoerg     if (I != Ch.begin())
23987330f729Sjoerg       OS << ", ";
23997330f729Sjoerg     Visit(*I);
24007330f729Sjoerg   }
24017330f729Sjoerg   OS << " ]";
24027330f729Sjoerg }
24037330f729Sjoerg 
VisitObjCDictionaryLiteral(ObjCDictionaryLiteral * E)24047330f729Sjoerg void StmtPrinter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
24057330f729Sjoerg   OS << "@{ ";
24067330f729Sjoerg   for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
24077330f729Sjoerg     if (I > 0)
24087330f729Sjoerg       OS << ", ";
24097330f729Sjoerg 
24107330f729Sjoerg     ObjCDictionaryElement Element = E->getKeyValueElement(I);
24117330f729Sjoerg     Visit(Element.Key);
24127330f729Sjoerg     OS << " : ";
24137330f729Sjoerg     Visit(Element.Value);
24147330f729Sjoerg     if (Element.isPackExpansion())
24157330f729Sjoerg       OS << "...";
24167330f729Sjoerg   }
24177330f729Sjoerg   OS << " }";
24187330f729Sjoerg }
24197330f729Sjoerg 
VisitObjCEncodeExpr(ObjCEncodeExpr * Node)24207330f729Sjoerg void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
24217330f729Sjoerg   OS << "@encode(";
24227330f729Sjoerg   Node->getEncodedType().print(OS, Policy);
24237330f729Sjoerg   OS << ')';
24247330f729Sjoerg }
24257330f729Sjoerg 
VisitObjCSelectorExpr(ObjCSelectorExpr * Node)24267330f729Sjoerg void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
24277330f729Sjoerg   OS << "@selector(";
24287330f729Sjoerg   Node->getSelector().print(OS);
24297330f729Sjoerg   OS << ')';
24307330f729Sjoerg }
24317330f729Sjoerg 
VisitObjCProtocolExpr(ObjCProtocolExpr * Node)24327330f729Sjoerg void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
24337330f729Sjoerg   OS << "@protocol(" << *Node->getProtocol() << ')';
24347330f729Sjoerg }
24357330f729Sjoerg 
VisitObjCMessageExpr(ObjCMessageExpr * Mess)24367330f729Sjoerg void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
24377330f729Sjoerg   OS << "[";
24387330f729Sjoerg   switch (Mess->getReceiverKind()) {
24397330f729Sjoerg   case ObjCMessageExpr::Instance:
24407330f729Sjoerg     PrintExpr(Mess->getInstanceReceiver());
24417330f729Sjoerg     break;
24427330f729Sjoerg 
24437330f729Sjoerg   case ObjCMessageExpr::Class:
24447330f729Sjoerg     Mess->getClassReceiver().print(OS, Policy);
24457330f729Sjoerg     break;
24467330f729Sjoerg 
24477330f729Sjoerg   case ObjCMessageExpr::SuperInstance:
24487330f729Sjoerg   case ObjCMessageExpr::SuperClass:
24497330f729Sjoerg     OS << "Super";
24507330f729Sjoerg     break;
24517330f729Sjoerg   }
24527330f729Sjoerg 
24537330f729Sjoerg   OS << ' ';
24547330f729Sjoerg   Selector selector = Mess->getSelector();
24557330f729Sjoerg   if (selector.isUnarySelector()) {
24567330f729Sjoerg     OS << selector.getNameForSlot(0);
24577330f729Sjoerg   } else {
24587330f729Sjoerg     for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
24597330f729Sjoerg       if (i < selector.getNumArgs()) {
24607330f729Sjoerg         if (i > 0) OS << ' ';
24617330f729Sjoerg         if (selector.getIdentifierInfoForSlot(i))
24627330f729Sjoerg           OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';
24637330f729Sjoerg         else
24647330f729Sjoerg            OS << ":";
24657330f729Sjoerg       }
24667330f729Sjoerg       else OS << ", "; // Handle variadic methods.
24677330f729Sjoerg 
24687330f729Sjoerg       PrintExpr(Mess->getArg(i));
24697330f729Sjoerg     }
24707330f729Sjoerg   }
24717330f729Sjoerg   OS << "]";
24727330f729Sjoerg }
24737330f729Sjoerg 
VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr * Node)24747330f729Sjoerg void StmtPrinter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) {
24757330f729Sjoerg   OS << (Node->getValue() ? "__objc_yes" : "__objc_no");
24767330f729Sjoerg }
24777330f729Sjoerg 
24787330f729Sjoerg void
VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr * E)24797330f729Sjoerg StmtPrinter::VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
24807330f729Sjoerg   PrintExpr(E->getSubExpr());
24817330f729Sjoerg }
24827330f729Sjoerg 
24837330f729Sjoerg void
VisitObjCBridgedCastExpr(ObjCBridgedCastExpr * E)24847330f729Sjoerg StmtPrinter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
24857330f729Sjoerg   OS << '(' << E->getBridgeKindName();
24867330f729Sjoerg   E->getType().print(OS, Policy);
24877330f729Sjoerg   OS << ')';
24887330f729Sjoerg   PrintExpr(E->getSubExpr());
24897330f729Sjoerg }
24907330f729Sjoerg 
VisitBlockExpr(BlockExpr * Node)24917330f729Sjoerg void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
24927330f729Sjoerg   BlockDecl *BD = Node->getBlockDecl();
24937330f729Sjoerg   OS << "^";
24947330f729Sjoerg 
24957330f729Sjoerg   const FunctionType *AFT = Node->getFunctionType();
24967330f729Sjoerg 
24977330f729Sjoerg   if (isa<FunctionNoProtoType>(AFT)) {
24987330f729Sjoerg     OS << "()";
24997330f729Sjoerg   } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
25007330f729Sjoerg     OS << '(';
25017330f729Sjoerg     for (BlockDecl::param_iterator AI = BD->param_begin(),
25027330f729Sjoerg          E = BD->param_end(); AI != E; ++AI) {
25037330f729Sjoerg       if (AI != BD->param_begin()) OS << ", ";
25047330f729Sjoerg       std::string ParamStr = (*AI)->getNameAsString();
25057330f729Sjoerg       (*AI)->getType().print(OS, Policy, ParamStr);
25067330f729Sjoerg     }
25077330f729Sjoerg 
25087330f729Sjoerg     const auto *FT = cast<FunctionProtoType>(AFT);
25097330f729Sjoerg     if (FT->isVariadic()) {
25107330f729Sjoerg       if (!BD->param_empty()) OS << ", ";
25117330f729Sjoerg       OS << "...";
25127330f729Sjoerg     }
25137330f729Sjoerg     OS << ')';
25147330f729Sjoerg   }
25157330f729Sjoerg   OS << "{ }";
25167330f729Sjoerg }
25177330f729Sjoerg 
VisitOpaqueValueExpr(OpaqueValueExpr * Node)25187330f729Sjoerg void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {
25197330f729Sjoerg   PrintExpr(Node->getSourceExpr());
25207330f729Sjoerg }
25217330f729Sjoerg 
VisitTypoExpr(TypoExpr * Node)25227330f729Sjoerg void StmtPrinter::VisitTypoExpr(TypoExpr *Node) {
25237330f729Sjoerg   // TODO: Print something reasonable for a TypoExpr, if necessary.
25247330f729Sjoerg   llvm_unreachable("Cannot print TypoExpr nodes");
25257330f729Sjoerg }
25267330f729Sjoerg 
VisitRecoveryExpr(RecoveryExpr * Node)2527*e038c9c4Sjoerg void StmtPrinter::VisitRecoveryExpr(RecoveryExpr *Node) {
2528*e038c9c4Sjoerg   OS << "<recovery-expr>(";
2529*e038c9c4Sjoerg   const char *Sep = "";
2530*e038c9c4Sjoerg   for (Expr *E : Node->subExpressions()) {
2531*e038c9c4Sjoerg     OS << Sep;
2532*e038c9c4Sjoerg     PrintExpr(E);
2533*e038c9c4Sjoerg     Sep = ", ";
2534*e038c9c4Sjoerg   }
2535*e038c9c4Sjoerg   OS << ')';
2536*e038c9c4Sjoerg }
2537*e038c9c4Sjoerg 
VisitAsTypeExpr(AsTypeExpr * Node)25387330f729Sjoerg void StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) {
25397330f729Sjoerg   OS << "__builtin_astype(";
25407330f729Sjoerg   PrintExpr(Node->getSrcExpr());
25417330f729Sjoerg   OS << ", ";
25427330f729Sjoerg   Node->getType().print(OS, Policy);
25437330f729Sjoerg   OS << ")";
25447330f729Sjoerg }
25457330f729Sjoerg 
25467330f729Sjoerg //===----------------------------------------------------------------------===//
25477330f729Sjoerg // Stmt method implementations
25487330f729Sjoerg //===----------------------------------------------------------------------===//
25497330f729Sjoerg 
dumpPretty(const ASTContext & Context) const25507330f729Sjoerg void Stmt::dumpPretty(const ASTContext &Context) const {
25517330f729Sjoerg   printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts()));
25527330f729Sjoerg }
25537330f729Sjoerg 
printPretty(raw_ostream & Out,PrinterHelper * Helper,const PrintingPolicy & Policy,unsigned Indentation,StringRef NL,const ASTContext * Context) const25547330f729Sjoerg void Stmt::printPretty(raw_ostream &Out, PrinterHelper *Helper,
25557330f729Sjoerg                        const PrintingPolicy &Policy, unsigned Indentation,
25567330f729Sjoerg                        StringRef NL, const ASTContext *Context) const {
25577330f729Sjoerg   StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);
25587330f729Sjoerg   P.Visit(const_cast<Stmt *>(this));
25597330f729Sjoerg }
25607330f729Sjoerg 
printJson(raw_ostream & Out,PrinterHelper * Helper,const PrintingPolicy & Policy,bool AddQuotes) const25617330f729Sjoerg void Stmt::printJson(raw_ostream &Out, PrinterHelper *Helper,
25627330f729Sjoerg                      const PrintingPolicy &Policy, bool AddQuotes) const {
25637330f729Sjoerg   std::string Buf;
25647330f729Sjoerg   llvm::raw_string_ostream TempOut(Buf);
25657330f729Sjoerg 
25667330f729Sjoerg   printPretty(TempOut, Helper, Policy);
25677330f729Sjoerg 
25687330f729Sjoerg   Out << JsonFormat(TempOut.str(), AddQuotes);
25697330f729Sjoerg }
25707330f729Sjoerg 
25717330f729Sjoerg //===----------------------------------------------------------------------===//
25727330f729Sjoerg // PrinterHelper
25737330f729Sjoerg //===----------------------------------------------------------------------===//
25747330f729Sjoerg 
25757330f729Sjoerg // Implement virtual destructor.
25767330f729Sjoerg PrinterHelper::~PrinterHelper() = default;
2577