1341825Sdim//===- StmtPrinter.cpp - Printing implementation for Stmt ASTs ------------===//
2193326Sed//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6193326Sed//
7193326Sed//===----------------------------------------------------------------------===//
8193326Sed//
9193326Sed// This file implements the Stmt::dumpPretty/Stmt::printPretty methods, which
10193326Sed// pretty print the AST back out to C code.
11193326Sed//
12193326Sed//===----------------------------------------------------------------------===//
13193326Sed
14239462Sdim#include "clang/AST/ASTContext.h"
15249423Sdim#include "clang/AST/Attr.h"
16341825Sdim#include "clang/AST/Decl.h"
17341825Sdim#include "clang/AST/DeclBase.h"
18193326Sed#include "clang/AST/DeclCXX.h"
19193326Sed#include "clang/AST/DeclObjC.h"
20309124Sdim#include "clang/AST/DeclOpenMP.h"
21218893Sdim#include "clang/AST/DeclTemplate.h"
22207619Srdivacky#include "clang/AST/Expr.h"
23218893Sdim#include "clang/AST/ExprCXX.h"
24341825Sdim#include "clang/AST/ExprObjC.h"
25296417Sdim#include "clang/AST/ExprOpenMP.h"
26341825Sdim#include "clang/AST/NestedNameSpecifier.h"
27341825Sdim#include "clang/AST/OpenMPClause.h"
28249423Sdim#include "clang/AST/PrettyPrinter.h"
29341825Sdim#include "clang/AST/Stmt.h"
30341825Sdim#include "clang/AST/StmtCXX.h"
31341825Sdim#include "clang/AST/StmtObjC.h"
32341825Sdim#include "clang/AST/StmtOpenMP.h"
33249423Sdim#include "clang/AST/StmtVisitor.h"
34341825Sdim#include "clang/AST/TemplateBase.h"
35341825Sdim#include "clang/AST/Type.h"
36249423Sdim#include "clang/Basic/CharInfo.h"
37341825Sdim#include "clang/Basic/ExpressionTraits.h"
38341825Sdim#include "clang/Basic/IdentifierTable.h"
39353358Sdim#include "clang/Basic/JsonSupport.h"
40341825Sdim#include "clang/Basic/LLVM.h"
41341825Sdim#include "clang/Basic/Lambda.h"
42341825Sdim#include "clang/Basic/OpenMPKinds.h"
43341825Sdim#include "clang/Basic/OperatorKinds.h"
44341825Sdim#include "clang/Basic/SourceLocation.h"
45341825Sdim#include "clang/Basic/TypeTraits.h"
46327952Sdim#include "clang/Lex/Lexer.h"
47341825Sdim#include "llvm/ADT/ArrayRef.h"
48234353Sdim#include "llvm/ADT/SmallString.h"
49341825Sdim#include "llvm/ADT/SmallVector.h"
50341825Sdim#include "llvm/ADT/StringRef.h"
51341825Sdim#include "llvm/Support/Casting.h"
52341825Sdim#include "llvm/Support/Compiler.h"
53341825Sdim#include "llvm/Support/ErrorHandling.h"
54249423Sdim#include "llvm/Support/Format.h"
55341825Sdim#include "llvm/Support/raw_ostream.h"
56341825Sdim#include <cassert>
57341825Sdim#include <string>
58341825Sdim
59193326Sedusing namespace clang;
60193326Sed
61193326Sed//===----------------------------------------------------------------------===//
62193326Sed// StmtPrinter Visitor
63193326Sed//===----------------------------------------------------------------------===//
64193326Sed
65341825Sdimnamespace {
66341825Sdim
67199990Srdivacky  class StmtPrinter : public StmtVisitor<StmtPrinter> {
68226633Sdim    raw_ostream &OS;
69193326Sed    unsigned IndentLevel;
70341825Sdim    PrinterHelper* Helper;
71193326Sed    PrintingPolicy Policy;
72344779Sdim    std::string NL;
73327952Sdim    const ASTContext *Context;
74193326Sed
75193326Sed  public:
76327952Sdim    StmtPrinter(raw_ostream &os, PrinterHelper *helper,
77327952Sdim                const PrintingPolicy &Policy, unsigned Indentation = 0,
78344779Sdim                StringRef NL = "\n",
79327952Sdim                const ASTContext *Context = nullptr)
80327952Sdim        : OS(os), IndentLevel(Indentation), Helper(helper), Policy(Policy),
81344779Sdim          NL(NL), Context(Context) {}
82198092Srdivacky
83193326Sed    void PrintStmt(Stmt *S) {
84193326Sed      PrintStmt(S, Policy.Indentation);
85193326Sed    }
86193326Sed
87193326Sed    void PrintStmt(Stmt *S, int SubIndent) {
88193326Sed      IndentLevel += SubIndent;
89193326Sed      if (S && isa<Expr>(S)) {
90193326Sed        // If this is an expr used in a stmt context, indent and newline it.
91193326Sed        Indent();
92193326Sed        Visit(S);
93344779Sdim        OS << ";" << NL;
94193326Sed      } else if (S) {
95193326Sed        Visit(S);
96193326Sed      } else {
97344779Sdim        Indent() << "<<<NULL STATEMENT>>>" << NL;
98193326Sed      }
99193326Sed      IndentLevel -= SubIndent;
100193326Sed    }
101193326Sed
102344779Sdim    void PrintInitStmt(Stmt *S, unsigned PrefixWidth) {
103344779Sdim      // FIXME: Cope better with odd prefix widths.
104344779Sdim      IndentLevel += (PrefixWidth + 1) / 2;
105344779Sdim      if (auto *DS = dyn_cast<DeclStmt>(S))
106344779Sdim        PrintRawDeclStmt(DS);
107344779Sdim      else
108344779Sdim        PrintExpr(cast<Expr>(S));
109344779Sdim      OS << "; ";
110344779Sdim      IndentLevel -= (PrefixWidth + 1) / 2;
111344779Sdim    }
112344779Sdim
113344779Sdim    void PrintControlledStmt(Stmt *S) {
114344779Sdim      if (auto *CS = dyn_cast<CompoundStmt>(S)) {
115344779Sdim        OS << " ";
116344779Sdim        PrintRawCompoundStmt(CS);
117344779Sdim        OS << NL;
118344779Sdim      } else {
119344779Sdim        OS << NL;
120344779Sdim        PrintStmt(S);
121344779Sdim      }
122344779Sdim    }
123344779Sdim
124193326Sed    void PrintRawCompoundStmt(CompoundStmt *S);
125193326Sed    void PrintRawDecl(Decl *D);
126243830Sdim    void PrintRawDeclStmt(const DeclStmt *S);
127193326Sed    void PrintRawIfStmt(IfStmt *If);
128193326Sed    void PrintRawCXXCatchStmt(CXXCatchStmt *Catch);
129218893Sdim    void PrintCallArgs(CallExpr *E);
130221345Sdim    void PrintRawSEHExceptHandler(SEHExceptStmt *S);
131221345Sdim    void PrintRawSEHFinallyStmt(SEHFinallyStmt *S);
132327952Sdim    void PrintOMPExecutableDirective(OMPExecutableDirective *S,
133327952Sdim                                     bool ForceNoStmt = false);
134198092Srdivacky
135193326Sed    void PrintExpr(Expr *E) {
136193326Sed      if (E)
137193326Sed        Visit(E);
138193326Sed      else
139193326Sed        OS << "<null expr>";
140193326Sed    }
141198092Srdivacky
142226633Sdim    raw_ostream &Indent(int Delta = 0) {
143193326Sed      for (int i = 0, e = IndentLevel+Delta; i < e; ++i)
144193326Sed        OS << "  ";
145193326Sed      return OS;
146193326Sed    }
147198092Srdivacky
148198092Srdivacky    void Visit(Stmt* S) {
149193326Sed      if (Helper && Helper->handledStmt(S,OS))
150193326Sed          return;
151193326Sed      else StmtVisitor<StmtPrinter>::Visit(S);
152193326Sed    }
153276479Sdim
154218893Sdim    void VisitStmt(Stmt *Node) LLVM_ATTRIBUTE_UNUSED {
155344779Sdim      Indent() << "<<unknown stmt type>>" << NL;
156212904Sdim    }
157341825Sdim
158218893Sdim    void VisitExpr(Expr *Node) LLVM_ATTRIBUTE_UNUSED {
159212904Sdim      OS << "<<unknown expr type>>";
160212904Sdim    }
161341825Sdim
162212904Sdim    void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node);
163198092Srdivacky
164212904Sdim#define ABSTRACT_STMT(CLASS)
165193326Sed#define STMT(CLASS, PARENT) \
166193326Sed    void Visit##CLASS(CLASS *Node);
167208600Srdivacky#include "clang/AST/StmtNodes.inc"
168193326Sed  };
169193326Sed
170341825Sdim} // namespace
171341825Sdim
172193326Sed//===----------------------------------------------------------------------===//
173193326Sed//  Stmt printing methods.
174193326Sed//===----------------------------------------------------------------------===//
175193326Sed
176193326Sed/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and
177193326Sed/// with no newline after the }.
178193326Sedvoid StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
179344779Sdim  OS << "{" << NL;
180276479Sdim  for (auto *I : Node->body())
181276479Sdim    PrintStmt(I);
182198092Srdivacky
183193326Sed  Indent() << "}";
184193326Sed}
185193326Sed
186193326Sedvoid StmtPrinter::PrintRawDecl(Decl *D) {
187195341Sed  D->print(OS, Policy, IndentLevel);
188193326Sed}
189193326Sed
190243830Sdimvoid StmtPrinter::PrintRawDeclStmt(const DeclStmt *S) {
191341825Sdim  SmallVector<Decl *, 2> Decls(S->decls());
192195341Sed  Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel);
193193326Sed}
194193326Sed
195193326Sedvoid StmtPrinter::VisitNullStmt(NullStmt *Node) {
196344779Sdim  Indent() << ";" << NL;
197193326Sed}
198193326Sed
199193326Sedvoid StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
200193326Sed  Indent();
201193326Sed  PrintRawDeclStmt(Node);
202344779Sdim  OS << ";" << NL;
203193326Sed}
204193326Sed
205193326Sedvoid StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
206193326Sed  Indent();
207193326Sed  PrintRawCompoundStmt(Node);
208344779Sdim  OS << "" << NL;
209193326Sed}
210193326Sed
211193326Sedvoid StmtPrinter::VisitCaseStmt(CaseStmt *Node) {
212193326Sed  Indent(-1) << "case ";
213193326Sed  PrintExpr(Node->getLHS());
214193326Sed  if (Node->getRHS()) {
215193326Sed    OS << " ... ";
216193326Sed    PrintExpr(Node->getRHS());
217193326Sed  }
218344779Sdim  OS << ":" << NL;
219198092Srdivacky
220193326Sed  PrintStmt(Node->getSubStmt(), 0);
221193326Sed}
222193326Sed
223193326Sedvoid StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) {
224344779Sdim  Indent(-1) << "default:" << NL;
225193326Sed  PrintStmt(Node->getSubStmt(), 0);
226193326Sed}
227193326Sed
228193326Sedvoid StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
229344779Sdim  Indent(-1) << Node->getName() << ":" << NL;
230193326Sed  PrintStmt(Node->getSubStmt(), 0);
231193326Sed}
232193326Sed
233234982Sdimvoid StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) {
234276479Sdim  for (const auto *Attr : Node->getAttrs()) {
235276479Sdim    Attr->printPretty(OS, Policy);
236234982Sdim  }
237276479Sdim
238234982Sdim  PrintStmt(Node->getSubStmt(), 0);
239234982Sdim}
240234982Sdim
241193326Sedvoid StmtPrinter::PrintRawIfStmt(IfStmt *If) {
242193326Sed  OS << "if (";
243344779Sdim  if (If->getInit())
244344779Sdim    PrintInitStmt(If->getInit(), 4);
245243830Sdim  if (const DeclStmt *DS = If->getConditionVariableDeclStmt())
246243830Sdim    PrintRawDeclStmt(DS);
247243830Sdim  else
248243830Sdim    PrintExpr(If->getCond());
249193326Sed  OS << ')';
250198092Srdivacky
251341825Sdim  if (auto *CS = dyn_cast<CompoundStmt>(If->getThen())) {
252193326Sed    OS << ' ';
253193326Sed    PrintRawCompoundStmt(CS);
254344779Sdim    OS << (If->getElse() ? " " : NL);
255193326Sed  } else {
256344779Sdim    OS << NL;
257193326Sed    PrintStmt(If->getThen());
258193326Sed    if (If->getElse()) Indent();
259193326Sed  }
260198092Srdivacky
261193326Sed  if (Stmt *Else = If->getElse()) {
262193326Sed    OS << "else";
263198092Srdivacky
264341825Sdim    if (auto *CS = dyn_cast<CompoundStmt>(Else)) {
265193326Sed      OS << ' ';
266193326Sed      PrintRawCompoundStmt(CS);
267344779Sdim      OS << NL;
268341825Sdim    } else if (auto *ElseIf = dyn_cast<IfStmt>(Else)) {
269193326Sed      OS << ' ';
270193326Sed      PrintRawIfStmt(ElseIf);
271193326Sed    } else {
272344779Sdim      OS << NL;
273193326Sed      PrintStmt(If->getElse());
274193326Sed    }
275193326Sed  }
276193326Sed}
277193326Sed
278193326Sedvoid StmtPrinter::VisitIfStmt(IfStmt *If) {
279193326Sed  Indent();
280193326Sed  PrintRawIfStmt(If);
281193326Sed}
282193326Sed
283193326Sedvoid StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) {
284193326Sed  Indent() << "switch (";
285344779Sdim  if (Node->getInit())
286344779Sdim    PrintInitStmt(Node->getInit(), 8);
287243830Sdim  if (const DeclStmt *DS = Node->getConditionVariableDeclStmt())
288243830Sdim    PrintRawDeclStmt(DS);
289243830Sdim  else
290243830Sdim    PrintExpr(Node->getCond());
291193326Sed  OS << ")";
292344779Sdim  PrintControlledStmt(Node->getBody());
293193326Sed}
294193326Sed
295193326Sedvoid StmtPrinter::VisitWhileStmt(WhileStmt *Node) {
296193326Sed  Indent() << "while (";
297243830Sdim  if (const DeclStmt *DS = Node->getConditionVariableDeclStmt())
298243830Sdim    PrintRawDeclStmt(DS);
299243830Sdim  else
300243830Sdim    PrintExpr(Node->getCond());
301344779Sdim  OS << ")" << NL;
302193326Sed  PrintStmt(Node->getBody());
303193326Sed}
304193326Sed
305193326Sedvoid StmtPrinter::VisitDoStmt(DoStmt *Node) {
306193326Sed  Indent() << "do ";
307341825Sdim  if (auto *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
308193326Sed    PrintRawCompoundStmt(CS);
309193326Sed    OS << " ";
310193326Sed  } else {
311344779Sdim    OS << NL;
312193326Sed    PrintStmt(Node->getBody());
313193326Sed    Indent();
314193326Sed  }
315198092Srdivacky
316193326Sed  OS << "while (";
317193326Sed  PrintExpr(Node->getCond());
318344779Sdim  OS << ");" << NL;
319193326Sed}
320193326Sed
321193326Sedvoid StmtPrinter::VisitForStmt(ForStmt *Node) {
322193326Sed  Indent() << "for (";
323344779Sdim  if (Node->getInit())
324344779Sdim    PrintInitStmt(Node->getInit(), 5);
325344779Sdim  else
326344779Sdim    OS << (Node->getCond() ? "; " : ";");
327344779Sdim  if (Node->getCond())
328193326Sed    PrintExpr(Node->getCond());
329193326Sed  OS << ";";
330193326Sed  if (Node->getInc()) {
331193326Sed    OS << " ";
332193326Sed    PrintExpr(Node->getInc());
333193326Sed  }
334344779Sdim  OS << ")";
335344779Sdim  PrintControlledStmt(Node->getBody());
336193326Sed}
337193326Sed
338193326Sedvoid StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) {
339193326Sed  Indent() << "for (";
340341825Sdim  if (auto *DS = dyn_cast<DeclStmt>(Node->getElement()))
341193326Sed    PrintRawDeclStmt(DS);
342193326Sed  else
343193326Sed    PrintExpr(cast<Expr>(Node->getElement()));
344193326Sed  OS << " in ";
345193326Sed  PrintExpr(Node->getCollection());
346344779Sdim  OS << ")";
347344779Sdim  PrintControlledStmt(Node->getBody());
348193326Sed}
349193326Sed
350221345Sdimvoid StmtPrinter::VisitCXXForRangeStmt(CXXForRangeStmt *Node) {
351221345Sdim  Indent() << "for (";
352344779Sdim  if (Node->getInit())
353344779Sdim    PrintInitStmt(Node->getInit(), 5);
354221345Sdim  PrintingPolicy SubPolicy(Policy);
355221345Sdim  SubPolicy.SuppressInitializers = true;
356221345Sdim  Node->getLoopVariable()->print(OS, SubPolicy, IndentLevel);
357221345Sdim  OS << " : ";
358221345Sdim  PrintExpr(Node->getRangeInit());
359344779Sdim  OS << ")";
360344779Sdim  PrintControlledStmt(Node->getBody());
361221345Sdim}
362221345Sdim
363234353Sdimvoid StmtPrinter::VisitMSDependentExistsStmt(MSDependentExistsStmt *Node) {
364234353Sdim  Indent();
365234353Sdim  if (Node->isIfExists())
366234353Sdim    OS << "__if_exists (";
367234353Sdim  else
368234353Sdim    OS << "__if_not_exists (";
369341825Sdim
370234353Sdim  if (NestedNameSpecifier *Qualifier
371234353Sdim        = Node->getQualifierLoc().getNestedNameSpecifier())
372234353Sdim    Qualifier->print(OS, Policy);
373341825Sdim
374234353Sdim  OS << Node->getNameInfo() << ") ";
375341825Sdim
376234353Sdim  PrintRawCompoundStmt(Node->getSubStmt());
377234353Sdim}
378234353Sdim
379193326Sedvoid StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
380276479Sdim  Indent() << "goto " << Node->getLabel()->getName() << ";";
381344779Sdim  if (Policy.IncludeNewlines) OS << NL;
382193326Sed}
383193326Sed
384193326Sedvoid StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
385193326Sed  Indent() << "goto *";
386193326Sed  PrintExpr(Node->getTarget());
387276479Sdim  OS << ";";
388344779Sdim  if (Policy.IncludeNewlines) OS << NL;
389193326Sed}
390193326Sed
391193326Sedvoid StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
392276479Sdim  Indent() << "continue;";
393344779Sdim  if (Policy.IncludeNewlines) OS << NL;
394193326Sed}
395193326Sed
396193326Sedvoid StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
397276479Sdim  Indent() << "break;";
398344779Sdim  if (Policy.IncludeNewlines) OS << NL;
399193326Sed}
400193326Sed
401193326Sedvoid StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
402193326Sed  Indent() << "return";
403193326Sed  if (Node->getRetValue()) {
404193326Sed    OS << " ";
405193326Sed    PrintExpr(Node->getRetValue());
406193326Sed  }
407276479Sdim  OS << ";";
408344779Sdim  if (Policy.IncludeNewlines) OS << NL;
409193326Sed}
410193326Sed
411243830Sdimvoid StmtPrinter::VisitGCCAsmStmt(GCCAsmStmt *Node) {
412193326Sed  Indent() << "asm ";
413198092Srdivacky
414193326Sed  if (Node->isVolatile())
415193326Sed    OS << "volatile ";
416198092Srdivacky
417353358Sdim  if (Node->isAsmGoto())
418353358Sdim    OS << "goto ";
419353358Sdim
420193326Sed  OS << "(";
421193326Sed  VisitStringLiteral(Node->getAsmString());
422198092Srdivacky
423193326Sed  // Outputs
424193326Sed  if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 ||
425353358Sdim      Node->getNumClobbers() != 0 || Node->getNumLabels() != 0)
426193326Sed    OS << " : ";
427198092Srdivacky
428193326Sed  for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) {
429193326Sed    if (i != 0)
430193326Sed      OS << ", ";
431198092Srdivacky
432193326Sed    if (!Node->getOutputName(i).empty()) {
433193326Sed      OS << '[';
434193326Sed      OS << Node->getOutputName(i);
435193326Sed      OS << "] ";
436193326Sed    }
437198092Srdivacky
438193326Sed    VisitStringLiteral(Node->getOutputConstraintLiteral(i));
439288943Sdim    OS << " (";
440193326Sed    Visit(Node->getOutputExpr(i));
441288943Sdim    OS << ")";
442193326Sed  }
443198092Srdivacky
444193326Sed  // Inputs
445353358Sdim  if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0 ||
446353358Sdim      Node->getNumLabels() != 0)
447193326Sed    OS << " : ";
448198092Srdivacky
449193326Sed  for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) {
450193326Sed    if (i != 0)
451193326Sed      OS << ", ";
452198092Srdivacky
453193326Sed    if (!Node->getInputName(i).empty()) {
454193326Sed      OS << '[';
455193326Sed      OS << Node->getInputName(i);
456193326Sed      OS << "] ";
457193326Sed    }
458198092Srdivacky
459193326Sed    VisitStringLiteral(Node->getInputConstraintLiteral(i));
460288943Sdim    OS << " (";
461193326Sed    Visit(Node->getInputExpr(i));
462288943Sdim    OS << ")";
463193326Sed  }
464198092Srdivacky
465193326Sed  // Clobbers
466353358Sdim  if (Node->getNumClobbers() != 0 || Node->getNumLabels())
467193326Sed    OS << " : ";
468198092Srdivacky
469193326Sed  for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) {
470193326Sed    if (i != 0)
471193326Sed      OS << ", ";
472198092Srdivacky
473243830Sdim    VisitStringLiteral(Node->getClobberStringLiteral(i));
474193326Sed  }
475198092Srdivacky
476353358Sdim  // Labels
477353358Sdim  if (Node->getNumLabels() != 0)
478353358Sdim    OS << " : ";
479353358Sdim
480353358Sdim  for (unsigned i = 0, e = Node->getNumLabels(); i != e; ++i) {
481353358Sdim    if (i != 0)
482353358Sdim      OS << ", ";
483353358Sdim    OS << Node->getLabelName(i);
484353358Sdim  }
485353358Sdim
486276479Sdim  OS << ");";
487344779Sdim  if (Policy.IncludeNewlines) OS << NL;
488193326Sed}
489193326Sed
490239462Sdimvoid StmtPrinter::VisitMSAsmStmt(MSAsmStmt *Node) {
491239462Sdim  // FIXME: Implement MS style inline asm statement printer.
492239462Sdim  Indent() << "__asm ";
493239462Sdim  if (Node->hasBraces())
494344779Sdim    OS << "{" << NL;
495344779Sdim  OS << Node->getAsmString() << NL;
496239462Sdim  if (Node->hasBraces())
497344779Sdim    Indent() << "}" << NL;
498239462Sdim}
499239462Sdim
500251662Sdimvoid StmtPrinter::VisitCapturedStmt(CapturedStmt *Node) {
501251662Sdim  PrintStmt(Node->getCapturedDecl()->getBody());
502251662Sdim}
503251662Sdim
504193326Sedvoid StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) {
505193326Sed  Indent() << "@try";
506341825Sdim  if (auto *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) {
507193326Sed    PrintRawCompoundStmt(TS);
508344779Sdim    OS << NL;
509193326Sed  }
510198092Srdivacky
511207619Srdivacky  for (unsigned I = 0, N = Node->getNumCatchStmts(); I != N; ++I) {
512207619Srdivacky    ObjCAtCatchStmt *catchStmt = Node->getCatchStmt(I);
513193326Sed    Indent() << "@catch(";
514193326Sed    if (catchStmt->getCatchParamDecl()) {
515193326Sed      if (Decl *DS = catchStmt->getCatchParamDecl())
516193326Sed        PrintRawDecl(DS);
517193326Sed    }
518193326Sed    OS << ")";
519341825Sdim    if (auto *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) {
520198092Srdivacky      PrintRawCompoundStmt(CS);
521344779Sdim      OS << NL;
522198092Srdivacky    }
523193326Sed  }
524198092Srdivacky
525341825Sdim  if (auto *FS = static_cast<ObjCAtFinallyStmt *>(Node->getFinallyStmt())) {
526193326Sed    Indent() << "@finally";
527193326Sed    PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody()));
528344779Sdim    OS << NL;
529198092Srdivacky  }
530193326Sed}
531193326Sed
532193326Sedvoid StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) {
533193326Sed}
534193326Sed
535193326Sedvoid StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) {
536344779Sdim  Indent() << "@catch (...) { /* todo */ } " << NL;
537193326Sed}
538193326Sed
539193326Sedvoid StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) {
540193326Sed  Indent() << "@throw";
541193326Sed  if (Node->getThrowExpr()) {
542193326Sed    OS << " ";
543193326Sed    PrintExpr(Node->getThrowExpr());
544193326Sed  }
545344779Sdim  OS << ";" << NL;
546193326Sed}
547193326Sed
548309124Sdimvoid StmtPrinter::VisitObjCAvailabilityCheckExpr(
549309124Sdim    ObjCAvailabilityCheckExpr *Node) {
550309124Sdim  OS << "@available(...)";
551309124Sdim}
552309124Sdim
553193326Sedvoid StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) {
554193326Sed  Indent() << "@synchronized (";
555193326Sed  PrintExpr(Node->getSynchExpr());
556193326Sed  OS << ")";
557193326Sed  PrintRawCompoundStmt(Node->getSynchBody());
558344779Sdim  OS << NL;
559193326Sed}
560193326Sed
561224145Sdimvoid StmtPrinter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *Node) {
562224145Sdim  Indent() << "@autoreleasepool";
563224145Sdim  PrintRawCompoundStmt(dyn_cast<CompoundStmt>(Node->getSubStmt()));
564344779Sdim  OS << NL;
565224145Sdim}
566224145Sdim
567193326Sedvoid StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) {
568193326Sed  OS << "catch (";
569193326Sed  if (Decl *ExDecl = Node->getExceptionDecl())
570193326Sed    PrintRawDecl(ExDecl);
571193326Sed  else
572193326Sed    OS << "...";
573193326Sed  OS << ") ";
574193326Sed  PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock()));
575193326Sed}
576193326Sed
577193326Sedvoid StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) {
578193326Sed  Indent();
579193326Sed  PrintRawCXXCatchStmt(Node);
580344779Sdim  OS << NL;
581193326Sed}
582193326Sed
583193326Sedvoid StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) {
584193326Sed  Indent() << "try ";
585193326Sed  PrintRawCompoundStmt(Node->getTryBlock());
586198092Srdivacky  for (unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) {
587193326Sed    OS << " ";
588193326Sed    PrintRawCXXCatchStmt(Node->getHandler(i));
589193326Sed  }
590344779Sdim  OS << NL;
591193326Sed}
592193326Sed
593221345Sdimvoid StmtPrinter::VisitSEHTryStmt(SEHTryStmt *Node) {
594221345Sdim  Indent() << (Node->getIsCXXTry() ? "try " : "__try ");
595221345Sdim  PrintRawCompoundStmt(Node->getTryBlock());
596221345Sdim  SEHExceptStmt *E = Node->getExceptHandler();
597221345Sdim  SEHFinallyStmt *F = Node->getFinallyHandler();
598221345Sdim  if(E)
599221345Sdim    PrintRawSEHExceptHandler(E);
600221345Sdim  else {
601221345Sdim    assert(F && "Must have a finally block...");
602221345Sdim    PrintRawSEHFinallyStmt(F);
603221345Sdim  }
604344779Sdim  OS << NL;
605221345Sdim}
606221345Sdim
607221345Sdimvoid StmtPrinter::PrintRawSEHFinallyStmt(SEHFinallyStmt *Node) {
608221345Sdim  OS << "__finally ";
609221345Sdim  PrintRawCompoundStmt(Node->getBlock());
610344779Sdim  OS << NL;
611221345Sdim}
612221345Sdim
613221345Sdimvoid StmtPrinter::PrintRawSEHExceptHandler(SEHExceptStmt *Node) {
614221345Sdim  OS << "__except (";
615221345Sdim  VisitExpr(Node->getFilterExpr());
616344779Sdim  OS << ")" << NL;
617221345Sdim  PrintRawCompoundStmt(Node->getBlock());
618344779Sdim  OS << NL;
619221345Sdim}
620221345Sdim
621221345Sdimvoid StmtPrinter::VisitSEHExceptStmt(SEHExceptStmt *Node) {
622221345Sdim  Indent();
623221345Sdim  PrintRawSEHExceptHandler(Node);
624344779Sdim  OS << NL;
625221345Sdim}
626221345Sdim
627221345Sdimvoid StmtPrinter::VisitSEHFinallyStmt(SEHFinallyStmt *Node) {
628221345Sdim  Indent();
629221345Sdim  PrintRawSEHFinallyStmt(Node);
630344779Sdim  OS << NL;
631221345Sdim}
632221345Sdim
633276479Sdimvoid StmtPrinter::VisitSEHLeaveStmt(SEHLeaveStmt *Node) {
634276479Sdim  Indent() << "__leave;";
635344779Sdim  if (Policy.IncludeNewlines) OS << NL;
636276479Sdim}
637276479Sdim
638193326Sed//===----------------------------------------------------------------------===//
639261991Sdim//  OpenMP directives printing methods
640261991Sdim//===----------------------------------------------------------------------===//
641261991Sdim
642327952Sdimvoid StmtPrinter::PrintOMPExecutableDirective(OMPExecutableDirective *S,
643327952Sdim                                              bool ForceNoStmt) {
644276479Sdim  OMPClausePrinter Printer(OS, Policy);
645276479Sdim  ArrayRef<OMPClause *> Clauses = S->clauses();
646341825Sdim  for (auto *Clause : Clauses)
647341825Sdim    if (Clause && !Clause->isImplicit()) {
648261991Sdim      OS << ' ';
649341825Sdim      Printer.Visit(Clause);
650261991Sdim    }
651344779Sdim  OS << NL;
652341825Sdim  if (!ForceNoStmt && S->hasAssociatedStmt())
653341825Sdim    PrintStmt(S->getInnermostCapturedStmt()->getCapturedStmt());
654261991Sdim}
655276479Sdim
656276479Sdimvoid StmtPrinter::VisitOMPParallelDirective(OMPParallelDirective *Node) {
657341825Sdim  Indent() << "#pragma omp parallel";
658276479Sdim  PrintOMPExecutableDirective(Node);
659276479Sdim}
660276479Sdim
661276479Sdimvoid StmtPrinter::VisitOMPSimdDirective(OMPSimdDirective *Node) {
662341825Sdim  Indent() << "#pragma omp simd";
663276479Sdim  PrintOMPExecutableDirective(Node);
664276479Sdim}
665276479Sdim
666276479Sdimvoid StmtPrinter::VisitOMPForDirective(OMPForDirective *Node) {
667341825Sdim  Indent() << "#pragma omp for";
668276479Sdim  PrintOMPExecutableDirective(Node);
669276479Sdim}
670276479Sdim
671280031Sdimvoid StmtPrinter::VisitOMPForSimdDirective(OMPForSimdDirective *Node) {
672341825Sdim  Indent() << "#pragma omp for simd";
673280031Sdim  PrintOMPExecutableDirective(Node);
674280031Sdim}
675280031Sdim
676276479Sdimvoid StmtPrinter::VisitOMPSectionsDirective(OMPSectionsDirective *Node) {
677341825Sdim  Indent() << "#pragma omp sections";
678276479Sdim  PrintOMPExecutableDirective(Node);
679276479Sdim}
680276479Sdim
681276479Sdimvoid StmtPrinter::VisitOMPSectionDirective(OMPSectionDirective *Node) {
682276479Sdim  Indent() << "#pragma omp section";
683276479Sdim  PrintOMPExecutableDirective(Node);
684276479Sdim}
685276479Sdim
686276479Sdimvoid StmtPrinter::VisitOMPSingleDirective(OMPSingleDirective *Node) {
687341825Sdim  Indent() << "#pragma omp single";
688276479Sdim  PrintOMPExecutableDirective(Node);
689276479Sdim}
690276479Sdim
691276479Sdimvoid StmtPrinter::VisitOMPMasterDirective(OMPMasterDirective *Node) {
692276479Sdim  Indent() << "#pragma omp master";
693276479Sdim  PrintOMPExecutableDirective(Node);
694276479Sdim}
695276479Sdim
696276479Sdimvoid StmtPrinter::VisitOMPCriticalDirective(OMPCriticalDirective *Node) {
697276479Sdim  Indent() << "#pragma omp critical";
698276479Sdim  if (Node->getDirectiveName().getName()) {
699276479Sdim    OS << " (";
700360784Sdim    Node->getDirectiveName().printName(OS, Policy);
701276479Sdim    OS << ")";
702276479Sdim  }
703276479Sdim  PrintOMPExecutableDirective(Node);
704276479Sdim}
705276479Sdim
706276479Sdimvoid StmtPrinter::VisitOMPParallelForDirective(OMPParallelForDirective *Node) {
707341825Sdim  Indent() << "#pragma omp parallel for";
708276479Sdim  PrintOMPExecutableDirective(Node);
709276479Sdim}
710276479Sdim
711280031Sdimvoid StmtPrinter::VisitOMPParallelForSimdDirective(
712280031Sdim    OMPParallelForSimdDirective *Node) {
713341825Sdim  Indent() << "#pragma omp parallel for simd";
714280031Sdim  PrintOMPExecutableDirective(Node);
715280031Sdim}
716280031Sdim
717360784Sdimvoid StmtPrinter::VisitOMPParallelMasterDirective(
718360784Sdim    OMPParallelMasterDirective *Node) {
719360784Sdim  Indent() << "#pragma omp parallel master";
720360784Sdim  PrintOMPExecutableDirective(Node);
721360784Sdim}
722360784Sdim
723276479Sdimvoid StmtPrinter::VisitOMPParallelSectionsDirective(
724276479Sdim    OMPParallelSectionsDirective *Node) {
725341825Sdim  Indent() << "#pragma omp parallel sections";
726276479Sdim  PrintOMPExecutableDirective(Node);
727276479Sdim}
728276479Sdim
729276479Sdimvoid StmtPrinter::VisitOMPTaskDirective(OMPTaskDirective *Node) {
730341825Sdim  Indent() << "#pragma omp task";
731276479Sdim  PrintOMPExecutableDirective(Node);
732276479Sdim}
733276479Sdim
734276479Sdimvoid StmtPrinter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *Node) {
735276479Sdim  Indent() << "#pragma omp taskyield";
736276479Sdim  PrintOMPExecutableDirective(Node);
737276479Sdim}
738276479Sdim
739276479Sdimvoid StmtPrinter::VisitOMPBarrierDirective(OMPBarrierDirective *Node) {
740276479Sdim  Indent() << "#pragma omp barrier";
741276479Sdim  PrintOMPExecutableDirective(Node);
742276479Sdim}
743276479Sdim
744276479Sdimvoid StmtPrinter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *Node) {
745276479Sdim  Indent() << "#pragma omp taskwait";
746276479Sdim  PrintOMPExecutableDirective(Node);
747276479Sdim}
748276479Sdim
749288943Sdimvoid StmtPrinter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *Node) {
750341825Sdim  Indent() << "#pragma omp taskgroup";
751288943Sdim  PrintOMPExecutableDirective(Node);
752288943Sdim}
753288943Sdim
754276479Sdimvoid StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) {
755341825Sdim  Indent() << "#pragma omp flush";
756276479Sdim  PrintOMPExecutableDirective(Node);
757276479Sdim}
758276479Sdim
759280031Sdimvoid StmtPrinter::VisitOMPOrderedDirective(OMPOrderedDirective *Node) {
760341825Sdim  Indent() << "#pragma omp ordered";
761341825Sdim  PrintOMPExecutableDirective(Node, Node->hasClausesOfKind<OMPDependClause>());
762280031Sdim}
763280031Sdim
764280031Sdimvoid StmtPrinter::VisitOMPAtomicDirective(OMPAtomicDirective *Node) {
765341825Sdim  Indent() << "#pragma omp atomic";
766280031Sdim  PrintOMPExecutableDirective(Node);
767280031Sdim}
768280031Sdim
769280031Sdimvoid StmtPrinter::VisitOMPTargetDirective(OMPTargetDirective *Node) {
770341825Sdim  Indent() << "#pragma omp target";
771280031Sdim  PrintOMPExecutableDirective(Node);
772280031Sdim}
773280031Sdim
774296417Sdimvoid StmtPrinter::VisitOMPTargetDataDirective(OMPTargetDataDirective *Node) {
775341825Sdim  Indent() << "#pragma omp target data";
776296417Sdim  PrintOMPExecutableDirective(Node);
777296417Sdim}
778296417Sdim
779309124Sdimvoid StmtPrinter::VisitOMPTargetEnterDataDirective(
780309124Sdim    OMPTargetEnterDataDirective *Node) {
781341825Sdim  Indent() << "#pragma omp target enter data";
782327952Sdim  PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
783309124Sdim}
784309124Sdim
785309124Sdimvoid StmtPrinter::VisitOMPTargetExitDataDirective(
786309124Sdim    OMPTargetExitDataDirective *Node) {
787341825Sdim  Indent() << "#pragma omp target exit data";
788327952Sdim  PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
789309124Sdim}
790309124Sdim
791309124Sdimvoid StmtPrinter::VisitOMPTargetParallelDirective(
792309124Sdim    OMPTargetParallelDirective *Node) {
793341825Sdim  Indent() << "#pragma omp target parallel";
794309124Sdim  PrintOMPExecutableDirective(Node);
795309124Sdim}
796309124Sdim
797309124Sdimvoid StmtPrinter::VisitOMPTargetParallelForDirective(
798309124Sdim    OMPTargetParallelForDirective *Node) {
799341825Sdim  Indent() << "#pragma omp target parallel for";
800309124Sdim  PrintOMPExecutableDirective(Node);
801309124Sdim}
802309124Sdim
803280031Sdimvoid StmtPrinter::VisitOMPTeamsDirective(OMPTeamsDirective *Node) {
804341825Sdim  Indent() << "#pragma omp teams";
805280031Sdim  PrintOMPExecutableDirective(Node);
806280031Sdim}
807280031Sdim
808288943Sdimvoid StmtPrinter::VisitOMPCancellationPointDirective(
809288943Sdim    OMPCancellationPointDirective *Node) {
810288943Sdim  Indent() << "#pragma omp cancellation point "
811288943Sdim           << getOpenMPDirectiveName(Node->getCancelRegion());
812288943Sdim  PrintOMPExecutableDirective(Node);
813288943Sdim}
814288943Sdim
815288943Sdimvoid StmtPrinter::VisitOMPCancelDirective(OMPCancelDirective *Node) {
816288943Sdim  Indent() << "#pragma omp cancel "
817341825Sdim           << getOpenMPDirectiveName(Node->getCancelRegion());
818288943Sdim  PrintOMPExecutableDirective(Node);
819288943Sdim}
820296417Sdim
821296417Sdimvoid StmtPrinter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *Node) {
822341825Sdim  Indent() << "#pragma omp taskloop";
823296417Sdim  PrintOMPExecutableDirective(Node);
824296417Sdim}
825296417Sdim
826296417Sdimvoid StmtPrinter::VisitOMPTaskLoopSimdDirective(
827296417Sdim    OMPTaskLoopSimdDirective *Node) {
828341825Sdim  Indent() << "#pragma omp taskloop simd";
829296417Sdim  PrintOMPExecutableDirective(Node);
830296417Sdim}
831296417Sdim
832360784Sdimvoid StmtPrinter::VisitOMPMasterTaskLoopDirective(
833360784Sdim    OMPMasterTaskLoopDirective *Node) {
834360784Sdim  Indent() << "#pragma omp master taskloop";
835360784Sdim  PrintOMPExecutableDirective(Node);
836360784Sdim}
837360784Sdim
838360784Sdimvoid StmtPrinter::VisitOMPMasterTaskLoopSimdDirective(
839360784Sdim    OMPMasterTaskLoopSimdDirective *Node) {
840360784Sdim  Indent() << "#pragma omp master taskloop simd";
841360784Sdim  PrintOMPExecutableDirective(Node);
842360784Sdim}
843360784Sdim
844360784Sdimvoid StmtPrinter::VisitOMPParallelMasterTaskLoopDirective(
845360784Sdim    OMPParallelMasterTaskLoopDirective *Node) {
846360784Sdim  Indent() << "#pragma omp parallel master taskloop";
847360784Sdim  PrintOMPExecutableDirective(Node);
848360784Sdim}
849360784Sdim
850360784Sdimvoid StmtPrinter::VisitOMPParallelMasterTaskLoopSimdDirective(
851360784Sdim    OMPParallelMasterTaskLoopSimdDirective *Node) {
852360784Sdim  Indent() << "#pragma omp parallel master taskloop simd";
853360784Sdim  PrintOMPExecutableDirective(Node);
854360784Sdim}
855360784Sdim
856296417Sdimvoid StmtPrinter::VisitOMPDistributeDirective(OMPDistributeDirective *Node) {
857341825Sdim  Indent() << "#pragma omp distribute";
858296417Sdim  PrintOMPExecutableDirective(Node);
859296417Sdim}
860296417Sdim
861309124Sdimvoid StmtPrinter::VisitOMPTargetUpdateDirective(
862309124Sdim    OMPTargetUpdateDirective *Node) {
863341825Sdim  Indent() << "#pragma omp target update";
864327952Sdim  PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
865309124Sdim}
866309124Sdim
867309124Sdimvoid StmtPrinter::VisitOMPDistributeParallelForDirective(
868309124Sdim    OMPDistributeParallelForDirective *Node) {
869341825Sdim  Indent() << "#pragma omp distribute parallel for";
870309124Sdim  PrintOMPExecutableDirective(Node);
871309124Sdim}
872309124Sdim
873309124Sdimvoid StmtPrinter::VisitOMPDistributeParallelForSimdDirective(
874309124Sdim    OMPDistributeParallelForSimdDirective *Node) {
875341825Sdim  Indent() << "#pragma omp distribute parallel for simd";
876309124Sdim  PrintOMPExecutableDirective(Node);
877309124Sdim}
878309124Sdim
879309124Sdimvoid StmtPrinter::VisitOMPDistributeSimdDirective(
880309124Sdim    OMPDistributeSimdDirective *Node) {
881341825Sdim  Indent() << "#pragma omp distribute simd";
882309124Sdim  PrintOMPExecutableDirective(Node);
883309124Sdim}
884309124Sdim
885309124Sdimvoid StmtPrinter::VisitOMPTargetParallelForSimdDirective(
886309124Sdim    OMPTargetParallelForSimdDirective *Node) {
887341825Sdim  Indent() << "#pragma omp target parallel for simd";
888309124Sdim  PrintOMPExecutableDirective(Node);
889309124Sdim}
890309124Sdim
891314564Sdimvoid StmtPrinter::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *Node) {
892341825Sdim  Indent() << "#pragma omp target simd";
893314564Sdim  PrintOMPExecutableDirective(Node);
894314564Sdim}
895314564Sdim
896314564Sdimvoid StmtPrinter::VisitOMPTeamsDistributeDirective(
897314564Sdim    OMPTeamsDistributeDirective *Node) {
898341825Sdim  Indent() << "#pragma omp teams distribute";
899314564Sdim  PrintOMPExecutableDirective(Node);
900314564Sdim}
901314564Sdim
902314564Sdimvoid StmtPrinter::VisitOMPTeamsDistributeSimdDirective(
903314564Sdim    OMPTeamsDistributeSimdDirective *Node) {
904341825Sdim  Indent() << "#pragma omp teams distribute simd";
905314564Sdim  PrintOMPExecutableDirective(Node);
906314564Sdim}
907314564Sdim
908314564Sdimvoid StmtPrinter::VisitOMPTeamsDistributeParallelForSimdDirective(
909314564Sdim    OMPTeamsDistributeParallelForSimdDirective *Node) {
910341825Sdim  Indent() << "#pragma omp teams distribute parallel for simd";
911314564Sdim  PrintOMPExecutableDirective(Node);
912314564Sdim}
913314564Sdim
914314564Sdimvoid StmtPrinter::VisitOMPTeamsDistributeParallelForDirective(
915314564Sdim    OMPTeamsDistributeParallelForDirective *Node) {
916341825Sdim  Indent() << "#pragma omp teams distribute parallel for";
917314564Sdim  PrintOMPExecutableDirective(Node);
918314564Sdim}
919314564Sdim
920314564Sdimvoid StmtPrinter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *Node) {
921341825Sdim  Indent() << "#pragma omp target teams";
922314564Sdim  PrintOMPExecutableDirective(Node);
923314564Sdim}
924314564Sdim
925314564Sdimvoid StmtPrinter::VisitOMPTargetTeamsDistributeDirective(
926314564Sdim    OMPTargetTeamsDistributeDirective *Node) {
927341825Sdim  Indent() << "#pragma omp target teams distribute";
928314564Sdim  PrintOMPExecutableDirective(Node);
929314564Sdim}
930314564Sdim
931314564Sdimvoid StmtPrinter::VisitOMPTargetTeamsDistributeParallelForDirective(
932314564Sdim    OMPTargetTeamsDistributeParallelForDirective *Node) {
933341825Sdim  Indent() << "#pragma omp target teams distribute parallel for";
934314564Sdim  PrintOMPExecutableDirective(Node);
935314564Sdim}
936314564Sdim
937314564Sdimvoid StmtPrinter::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
938314564Sdim    OMPTargetTeamsDistributeParallelForSimdDirective *Node) {
939341825Sdim  Indent() << "#pragma omp target teams distribute parallel for simd";
940314564Sdim  PrintOMPExecutableDirective(Node);
941314564Sdim}
942314564Sdim
943314564Sdimvoid StmtPrinter::VisitOMPTargetTeamsDistributeSimdDirective(
944314564Sdim    OMPTargetTeamsDistributeSimdDirective *Node) {
945341825Sdim  Indent() << "#pragma omp target teams distribute simd";
946314564Sdim  PrintOMPExecutableDirective(Node);
947314564Sdim}
948314564Sdim
949261991Sdim//===----------------------------------------------------------------------===//
950193326Sed//  Expr printing methods.
951193326Sed//===----------------------------------------------------------------------===//
952193326Sed
953353358Sdimvoid StmtPrinter::VisitSourceLocExpr(SourceLocExpr *Node) {
954353358Sdim  OS << Node->getBuiltinStr() << "()";
955353358Sdim}
956353358Sdim
957344779Sdimvoid StmtPrinter::VisitConstantExpr(ConstantExpr *Node) {
958344779Sdim  PrintExpr(Node->getSubExpr());
959344779Sdim}
960344779Sdim
961193326Sedvoid StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
962341825Sdim  if (const auto *OCED = dyn_cast<OMPCapturedExprDecl>(Node->getDecl())) {
963309124Sdim    OCED->getInit()->IgnoreImpCasts()->printPretty(OS, nullptr, Policy);
964309124Sdim    return;
965309124Sdim  }
966198893Srdivacky  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
967198893Srdivacky    Qualifier->print(OS, Policy);
968234353Sdim  if (Node->hasTemplateKeyword())
969234353Sdim    OS << "template ";
970212904Sdim  OS << Node->getNameInfo();
971212904Sdim  if (Node->hasExplicitTemplateArgs())
972327952Sdim    printTemplateArgumentList(OS, Node->template_arguments(), Policy);
973193326Sed}
974193326Sed
975199990Srdivackyvoid StmtPrinter::VisitDependentScopeDeclRefExpr(
976199990Srdivacky                                           DependentScopeDeclRefExpr *Node) {
977218893Sdim  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
978218893Sdim    Qualifier->print(OS, Policy);
979234353Sdim  if (Node->hasTemplateKeyword())
980234353Sdim    OS << "template ";
981212904Sdim  OS << Node->getNameInfo();
982199990Srdivacky  if (Node->hasExplicitTemplateArgs())
983327952Sdim    printTemplateArgumentList(OS, Node->template_arguments(), Policy);
984193326Sed}
985193326Sed
986199990Srdivackyvoid StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
987195341Sed  if (Node->getQualifier())
988195341Sed    Node->getQualifier()->print(OS, Policy);
989234353Sdim  if (Node->hasTemplateKeyword())
990234353Sdim    OS << "template ";
991212904Sdim  OS << Node->getNameInfo();
992199990Srdivacky  if (Node->hasExplicitTemplateArgs())
993327952Sdim    printTemplateArgumentList(OS, Node->template_arguments(), Policy);
994195341Sed}
995195341Sed
996327952Sdimstatic bool isImplicitSelf(const Expr *E) {
997327952Sdim  if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
998341825Sdim    if (const auto *PD = dyn_cast<ImplicitParamDecl>(DRE->getDecl())) {
999327952Sdim      if (PD->getParameterKind() == ImplicitParamDecl::ObjCSelf &&
1000344779Sdim          DRE->getBeginLoc().isInvalid())
1001327952Sdim        return true;
1002327952Sdim    }
1003327952Sdim  }
1004327952Sdim  return false;
1005327952Sdim}
1006327952Sdim
1007193326Sedvoid StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
1008193326Sed  if (Node->getBase()) {
1009327952Sdim    if (!Policy.SuppressImplicitBase ||
1010327952Sdim        !isImplicitSelf(Node->getBase()->IgnoreImpCasts())) {
1011327952Sdim      PrintExpr(Node->getBase());
1012327952Sdim      OS << (Node->isArrow() ? "->" : ".");
1013327952Sdim    }
1014193326Sed  }
1015226633Sdim  OS << *Node->getDecl();
1016193326Sed}
1017193326Sed
1018193326Sedvoid StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
1019218893Sdim  if (Node->isSuperReceiver())
1020218893Sdim    OS << "super.";
1021265925Sdim  else if (Node->isObjectReceiver() && Node->getBase()) {
1022193326Sed    PrintExpr(Node->getBase());
1023193326Sed    OS << ".";
1024265925Sdim  } else if (Node->isClassReceiver() && Node->getClassReceiver()) {
1025265925Sdim    OS << Node->getClassReceiver()->getName() << ".";
1026193326Sed  }
1027193326Sed
1028341825Sdim  if (Node->isImplicitProperty()) {
1029341825Sdim    if (const auto *Getter = Node->getImplicitPropertyGetter())
1030341825Sdim      Getter->getSelector().print(OS);
1031341825Sdim    else
1032341825Sdim      OS << SelectorTable::getPropertyNameFromSetterSelector(
1033341825Sdim          Node->getImplicitPropertySetter()->getSelector());
1034341825Sdim  } else
1035218893Sdim    OS << Node->getExplicitProperty()->getName();
1036193326Sed}
1037193326Sed
1038234353Sdimvoid StmtPrinter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node) {
1039234353Sdim  PrintExpr(Node->getBaseExpr());
1040234353Sdim  OS << "[";
1041234353Sdim  PrintExpr(Node->getKeyExpr());
1042234353Sdim  OS << "]";
1043234353Sdim}
1044234353Sdim
1045193326Sedvoid StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
1046344779Sdim  OS << PredefinedExpr::getIdentKindName(Node->getIdentKind());
1047193326Sed}
1048193326Sed
1049193326Sedvoid StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
1050193326Sed  unsigned value = Node->getValue();
1051226633Sdim
1052226633Sdim  switch (Node->getKind()) {
1053226633Sdim  case CharacterLiteral::Ascii: break; // no prefix.
1054226633Sdim  case CharacterLiteral::Wide:  OS << 'L'; break;
1055296417Sdim  case CharacterLiteral::UTF8:  OS << "u8"; break;
1056226633Sdim  case CharacterLiteral::UTF16: OS << 'u'; break;
1057226633Sdim  case CharacterLiteral::UTF32: OS << 'U'; break;
1058226633Sdim  }
1059226633Sdim
1060193326Sed  switch (value) {
1061193326Sed  case '\\':
1062193326Sed    OS << "'\\\\'";
1063193326Sed    break;
1064193326Sed  case '\'':
1065193326Sed    OS << "'\\''";
1066193326Sed    break;
1067193326Sed  case '\a':
1068193326Sed    // TODO: K&R: the meaning of '\\a' is different in traditional C
1069193326Sed    OS << "'\\a'";
1070193326Sed    break;
1071193326Sed  case '\b':
1072193326Sed    OS << "'\\b'";
1073193326Sed    break;
1074193326Sed  // Nonstandard escape sequence.
1075193326Sed  /*case '\e':
1076193326Sed    OS << "'\\e'";
1077193326Sed    break;*/
1078193326Sed  case '\f':
1079193326Sed    OS << "'\\f'";
1080193326Sed    break;
1081193326Sed  case '\n':
1082193326Sed    OS << "'\\n'";
1083193326Sed    break;
1084193326Sed  case '\r':
1085193326Sed    OS << "'\\r'";
1086193326Sed    break;
1087193326Sed  case '\t':
1088193326Sed    OS << "'\\t'";
1089193326Sed    break;
1090193326Sed  case '\v':
1091193326Sed    OS << "'\\v'";
1092193326Sed    break;
1093193326Sed  default:
1094309124Sdim    // A character literal might be sign-extended, which
1095309124Sdim    // would result in an invalid \U escape sequence.
1096309124Sdim    // FIXME: multicharacter literals such as '\xFF\xFF\xFF\xFF'
1097309124Sdim    // are not correctly handled.
1098309124Sdim    if ((value & ~0xFFu) == ~0xFFu && Node->getKind() == CharacterLiteral::Ascii)
1099309124Sdim      value &= 0xFFu;
1100249423Sdim    if (value < 256 && isPrintable((unsigned char)value))
1101193326Sed      OS << "'" << (char)value << "'";
1102249423Sdim    else if (value < 256)
1103249423Sdim      OS << "'\\x" << llvm::format("%02x", value) << "'";
1104249423Sdim    else if (value <= 0xFFFF)
1105249423Sdim      OS << "'\\u" << llvm::format("%04x", value) << "'";
1106249423Sdim    else
1107249423Sdim      OS << "'\\U" << llvm::format("%08x", value) << "'";
1108193326Sed  }
1109193326Sed}
1110193326Sed
1111327952Sdim/// Prints the given expression using the original source text. Returns true on
1112327952Sdim/// success, false otherwise.
1113327952Sdimstatic bool printExprAsWritten(raw_ostream &OS, Expr *E,
1114327952Sdim                               const ASTContext *Context) {
1115327952Sdim  if (!Context)
1116327952Sdim    return false;
1117327952Sdim  bool Invalid = false;
1118327952Sdim  StringRef Source = Lexer::getSourceText(
1119327952Sdim      CharSourceRange::getTokenRange(E->getSourceRange()),
1120327952Sdim      Context->getSourceManager(), Context->getLangOpts(), &Invalid);
1121327952Sdim  if (!Invalid) {
1122327952Sdim    OS << Source;
1123327952Sdim    return true;
1124327952Sdim  }
1125327952Sdim  return false;
1126327952Sdim}
1127327952Sdim
1128193326Sedvoid StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
1129327952Sdim  if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1130327952Sdim    return;
1131193326Sed  bool isSigned = Node->getType()->isSignedIntegerType();
1132193326Sed  OS << Node->getValue().toString(10, isSigned);
1133198092Srdivacky
1134193326Sed  // Emit suffixes.  Integer literals are always a builtin integer type.
1135360784Sdim  switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1136226633Sdim  default: llvm_unreachable("Unexpected type for integer literal!");
1137288943Sdim  case BuiltinType::Char_S:
1138288943Sdim  case BuiltinType::Char_U:    OS << "i8"; break;
1139276479Sdim  case BuiltinType::UChar:     OS << "Ui8"; break;
1140276479Sdim  case BuiltinType::Short:     OS << "i16"; break;
1141276479Sdim  case BuiltinType::UShort:    OS << "Ui16"; break;
1142193326Sed  case BuiltinType::Int:       break; // no suffix.
1143193326Sed  case BuiltinType::UInt:      OS << 'U'; break;
1144193326Sed  case BuiltinType::Long:      OS << 'L'; break;
1145193326Sed  case BuiltinType::ULong:     OS << "UL"; break;
1146193326Sed  case BuiltinType::LongLong:  OS << "LL"; break;
1147193326Sed  case BuiltinType::ULongLong: OS << "ULL"; break;
1148193326Sed  }
1149193326Sed}
1150243830Sdim
1151341825Sdimvoid StmtPrinter::VisitFixedPointLiteral(FixedPointLiteral *Node) {
1152341825Sdim  if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1153341825Sdim    return;
1154341825Sdim  OS << Node->getValueAsString(/*Radix=*/10);
1155341825Sdim
1156360784Sdim  switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1157341825Sdim    default: llvm_unreachable("Unexpected type for fixed point literal!");
1158341825Sdim    case BuiltinType::ShortFract:   OS << "hr"; break;
1159341825Sdim    case BuiltinType::ShortAccum:   OS << "hk"; break;
1160341825Sdim    case BuiltinType::UShortFract:  OS << "uhr"; break;
1161341825Sdim    case BuiltinType::UShortAccum:  OS << "uhk"; break;
1162341825Sdim    case BuiltinType::Fract:        OS << "r"; break;
1163341825Sdim    case BuiltinType::Accum:        OS << "k"; break;
1164341825Sdim    case BuiltinType::UFract:       OS << "ur"; break;
1165341825Sdim    case BuiltinType::UAccum:       OS << "uk"; break;
1166341825Sdim    case BuiltinType::LongFract:    OS << "lr"; break;
1167341825Sdim    case BuiltinType::LongAccum:    OS << "lk"; break;
1168341825Sdim    case BuiltinType::ULongFract:   OS << "ulr"; break;
1169341825Sdim    case BuiltinType::ULongAccum:   OS << "ulk"; break;
1170341825Sdim  }
1171341825Sdim}
1172341825Sdim
1173243830Sdimstatic void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node,
1174243830Sdim                                 bool PrintSuffix) {
1175234353Sdim  SmallString<16> Str;
1176226633Sdim  Node->getValue().toString(Str);
1177226633Sdim  OS << Str;
1178243830Sdim  if (Str.find_first_not_of("-0123456789") == StringRef::npos)
1179243830Sdim    OS << '.'; // Trailing dot in order to separate from ints.
1180243830Sdim
1181243830Sdim  if (!PrintSuffix)
1182243830Sdim    return;
1183243830Sdim
1184243830Sdim  // Emit suffixes.  Float literals are always a builtin float type.
1185360784Sdim  switch (Node->getType()->castAs<BuiltinType>()->getKind()) {
1186243830Sdim  default: llvm_unreachable("Unexpected type for float literal!");
1187243830Sdim  case BuiltinType::Half:       break; // FIXME: suffix?
1188243830Sdim  case BuiltinType::Double:     break; // no suffix.
1189327952Sdim  case BuiltinType::Float16:    OS << "F16"; break;
1190243830Sdim  case BuiltinType::Float:      OS << 'F'; break;
1191243830Sdim  case BuiltinType::LongDouble: OS << 'L'; break;
1192309124Sdim  case BuiltinType::Float128:   OS << 'Q'; break;
1193243830Sdim  }
1194193326Sed}
1195193326Sed
1196243830Sdimvoid StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
1197327952Sdim  if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1198327952Sdim    return;
1199243830Sdim  PrintFloatingLiteral(OS, Node, /*PrintSuffix=*/true);
1200243830Sdim}
1201243830Sdim
1202193326Sedvoid StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
1203193326Sed  PrintExpr(Node->getSubExpr());
1204193326Sed  OS << "i";
1205193326Sed}
1206193326Sed
1207193326Sedvoid StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
1208239462Sdim  Str->outputString(OS);
1209193326Sed}
1210341825Sdim
1211193326Sedvoid StmtPrinter::VisitParenExpr(ParenExpr *Node) {
1212193326Sed  OS << "(";
1213193326Sed  PrintExpr(Node->getSubExpr());
1214193326Sed  OS << ")";
1215193326Sed}
1216341825Sdim
1217193326Sedvoid StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
1218193326Sed  if (!Node->isPostfix()) {
1219193326Sed    OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
1220198092Srdivacky
1221194613Sed    // Print a space if this is an "identifier operator" like __real, or if
1222194613Sed    // it might be concatenated incorrectly like '+'.
1223193326Sed    switch (Node->getOpcode()) {
1224193326Sed    default: break;
1225212904Sdim    case UO_Real:
1226212904Sdim    case UO_Imag:
1227212904Sdim    case UO_Extension:
1228193326Sed      OS << ' ';
1229193326Sed      break;
1230212904Sdim    case UO_Plus:
1231212904Sdim    case UO_Minus:
1232194613Sed      if (isa<UnaryOperator>(Node->getSubExpr()))
1233194613Sed        OS << ' ';
1234194613Sed      break;
1235193326Sed    }
1236193326Sed  }
1237193326Sed  PrintExpr(Node->getSubExpr());
1238198092Srdivacky
1239193326Sed  if (Node->isPostfix())
1240193326Sed    OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
1241193326Sed}
1242193326Sed
1243207619Srdivackyvoid StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {
1244207619Srdivacky  OS << "__builtin_offsetof(";
1245249423Sdim  Node->getTypeSourceInfo()->getType().print(OS, Policy);
1246249423Sdim  OS << ", ";
1247207619Srdivacky  bool PrintedSomething = false;
1248207619Srdivacky  for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) {
1249296417Sdim    OffsetOfNode ON = Node->getComponent(i);
1250296417Sdim    if (ON.getKind() == OffsetOfNode::Array) {
1251207619Srdivacky      // Array node
1252207619Srdivacky      OS << "[";
1253207619Srdivacky      PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex()));
1254207619Srdivacky      OS << "]";
1255207619Srdivacky      PrintedSomething = true;
1256207619Srdivacky      continue;
1257207619Srdivacky    }
1258207619Srdivacky
1259207619Srdivacky    // Skip implicit base indirections.
1260296417Sdim    if (ON.getKind() == OffsetOfNode::Base)
1261207619Srdivacky      continue;
1262207619Srdivacky
1263207619Srdivacky    // Field or identifier node.
1264207619Srdivacky    IdentifierInfo *Id = ON.getFieldName();
1265207619Srdivacky    if (!Id)
1266207619Srdivacky      continue;
1267341825Sdim
1268207619Srdivacky    if (PrintedSomething)
1269207619Srdivacky      OS << ".";
1270207619Srdivacky    else
1271207619Srdivacky      PrintedSomething = true;
1272341825Sdim    OS << Id->getName();
1273207619Srdivacky  }
1274207619Srdivacky  OS << ")";
1275207619Srdivacky}
1276207619Srdivacky
1277221345Sdimvoid StmtPrinter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node){
1278221345Sdim  switch(Node->getKind()) {
1279221345Sdim  case UETT_SizeOf:
1280221345Sdim    OS << "sizeof";
1281221345Sdim    break;
1282221345Sdim  case UETT_AlignOf:
1283309124Sdim    if (Policy.Alignof)
1284239462Sdim      OS << "alignof";
1285309124Sdim    else if (Policy.UnderscoreAlignof)
1286239462Sdim      OS << "_Alignof";
1287239462Sdim    else
1288239462Sdim      OS << "__alignof";
1289221345Sdim    break;
1290344779Sdim  case UETT_PreferredAlignOf:
1291344779Sdim    OS << "__alignof";
1292344779Sdim    break;
1293221345Sdim  case UETT_VecStep:
1294221345Sdim    OS << "vec_step";
1295221345Sdim    break;
1296288943Sdim  case UETT_OpenMPRequiredSimdAlign:
1297288943Sdim    OS << "__builtin_omp_required_simd_align";
1298288943Sdim    break;
1299221345Sdim  }
1300249423Sdim  if (Node->isArgumentType()) {
1301249423Sdim    OS << '(';
1302249423Sdim    Node->getArgumentType().print(OS, Policy);
1303249423Sdim    OS << ')';
1304249423Sdim  } else {
1305193326Sed    OS << " ";
1306193326Sed    PrintExpr(Node->getArgumentExpr());
1307193326Sed  }
1308193326Sed}
1309221345Sdim
1310221345Sdimvoid StmtPrinter::VisitGenericSelectionExpr(GenericSelectionExpr *Node) {
1311221345Sdim  OS << "_Generic(";
1312221345Sdim  PrintExpr(Node->getControllingExpr());
1313360784Sdim  for (const GenericSelectionExpr::Association Assoc : Node->associations()) {
1314221345Sdim    OS << ", ";
1315353358Sdim    QualType T = Assoc.getType();
1316221345Sdim    if (T.isNull())
1317221345Sdim      OS << "default";
1318221345Sdim    else
1319249423Sdim      T.print(OS, Policy);
1320221345Sdim    OS << ": ";
1321353358Sdim    PrintExpr(Assoc.getAssociationExpr());
1322221345Sdim  }
1323221345Sdim  OS << ")";
1324221345Sdim}
1325221345Sdim
1326193326Sedvoid StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
1327193326Sed  PrintExpr(Node->getLHS());
1328193326Sed  OS << "[";
1329193326Sed  PrintExpr(Node->getRHS());
1330193326Sed  OS << "]";
1331193326Sed}
1332193326Sed
1333296417Sdimvoid StmtPrinter::VisitOMPArraySectionExpr(OMPArraySectionExpr *Node) {
1334296417Sdim  PrintExpr(Node->getBase());
1335296417Sdim  OS << "[";
1336296417Sdim  if (Node->getLowerBound())
1337296417Sdim    PrintExpr(Node->getLowerBound());
1338296417Sdim  if (Node->getColonLoc().isValid()) {
1339296417Sdim    OS << ":";
1340296417Sdim    if (Node->getLength())
1341296417Sdim      PrintExpr(Node->getLength());
1342296417Sdim  }
1343296417Sdim  OS << "]";
1344296417Sdim}
1345296417Sdim
1346218893Sdimvoid StmtPrinter::PrintCallArgs(CallExpr *Call) {
1347193326Sed  for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
1348193326Sed    if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
1349193326Sed      // Don't print any defaulted arguments
1350193326Sed      break;
1351193326Sed    }
1352193326Sed
1353193326Sed    if (i) OS << ", ";
1354193326Sed    PrintExpr(Call->getArg(i));
1355193326Sed  }
1356218893Sdim}
1357218893Sdim
1358218893Sdimvoid StmtPrinter::VisitCallExpr(CallExpr *Call) {
1359218893Sdim  PrintExpr(Call->getCallee());
1360218893Sdim  OS << "(";
1361218893Sdim  PrintCallArgs(Call);
1362193326Sed  OS << ")";
1363193326Sed}
1364327952Sdim
1365327952Sdimstatic bool isImplicitThis(const Expr *E) {
1366327952Sdim  if (const auto *TE = dyn_cast<CXXThisExpr>(E))
1367327952Sdim    return TE->isImplicit();
1368327952Sdim  return false;
1369327952Sdim}
1370327952Sdim
1371193326Sedvoid StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
1372327952Sdim  if (!Policy.SuppressImplicitBase || !isImplicitThis(Node->getBase())) {
1373327952Sdim    PrintExpr(Node->getBase());
1374249423Sdim
1375341825Sdim    auto *ParentMember = dyn_cast<MemberExpr>(Node->getBase());
1376327952Sdim    FieldDecl *ParentDecl =
1377327952Sdim        ParentMember ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl())
1378327952Sdim                     : nullptr;
1379249423Sdim
1380327952Sdim    if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion())
1381327952Sdim      OS << (Node->isArrow() ? "->" : ".");
1382327952Sdim  }
1383249423Sdim
1384341825Sdim  if (auto *FD = dyn_cast<FieldDecl>(Node->getMemberDecl()))
1385202379Srdivacky    if (FD->isAnonymousStructOrUnion())
1386202379Srdivacky      return;
1387249423Sdim
1388198092Srdivacky  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1389198092Srdivacky    Qualifier->print(OS, Policy);
1390234353Sdim  if (Node->hasTemplateKeyword())
1391234353Sdim    OS << "template ";
1392212904Sdim  OS << Node->getMemberNameInfo();
1393212904Sdim  if (Node->hasExplicitTemplateArgs())
1394327952Sdim    printTemplateArgumentList(OS, Node->template_arguments(), Policy);
1395193326Sed}
1396341825Sdim
1397198092Srdivackyvoid StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
1398198092Srdivacky  PrintExpr(Node->getBase());
1399198092Srdivacky  OS << (Node->isArrow() ? "->isa" : ".isa");
1400198092Srdivacky}
1401198092Srdivacky
1402193326Sedvoid StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
1403193326Sed  PrintExpr(Node->getBase());
1404193326Sed  OS << ".";
1405193326Sed  OS << Node->getAccessor().getName();
1406193326Sed}
1407341825Sdim
1408193326Sedvoid StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
1409249423Sdim  OS << '(';
1410249423Sdim  Node->getTypeAsWritten().print(OS, Policy);
1411249423Sdim  OS << ')';
1412193326Sed  PrintExpr(Node->getSubExpr());
1413193326Sed}
1414341825Sdim
1415193326Sedvoid StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
1416249423Sdim  OS << '(';
1417249423Sdim  Node->getType().print(OS, Policy);
1418249423Sdim  OS << ')';
1419193326Sed  PrintExpr(Node->getInitializer());
1420193326Sed}
1421341825Sdim
1422193326Sedvoid StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
1423276479Sdim  // No need to print anything, simply forward to the subexpression.
1424193326Sed  PrintExpr(Node->getSubExpr());
1425193326Sed}
1426341825Sdim
1427193326Sedvoid StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
1428193326Sed  PrintExpr(Node->getLHS());
1429193326Sed  OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
1430193326Sed  PrintExpr(Node->getRHS());
1431193326Sed}
1432341825Sdim
1433193326Sedvoid StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
1434193326Sed  PrintExpr(Node->getLHS());
1435193326Sed  OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
1436193326Sed  PrintExpr(Node->getRHS());
1437193326Sed}
1438341825Sdim
1439193326Sedvoid StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
1440193326Sed  PrintExpr(Node->getCond());
1441218893Sdim  OS << " ? ";
1442218893Sdim  PrintExpr(Node->getLHS());
1443218893Sdim  OS << " : ";
1444193326Sed  PrintExpr(Node->getRHS());
1445193326Sed}
1446193326Sed
1447193326Sed// GNU extensions.
1448193326Sed
1449218893Sdimvoid
1450218893SdimStmtPrinter::VisitBinaryConditionalOperator(BinaryConditionalOperator *Node) {
1451218893Sdim  PrintExpr(Node->getCommon());
1452218893Sdim  OS << " ?: ";
1453218893Sdim  PrintExpr(Node->getFalseExpr());
1454218893Sdim}
1455341825Sdim
1456193326Sedvoid StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
1457193326Sed  OS << "&&" << Node->getLabel()->getName();
1458193326Sed}
1459193326Sed
1460193326Sedvoid StmtPrinter::VisitStmtExpr(StmtExpr *E) {
1461193326Sed  OS << "(";
1462193326Sed  PrintRawCompoundStmt(E->getSubStmt());
1463193326Sed  OS << ")";
1464193326Sed}
1465193326Sed
1466193326Sedvoid StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
1467193326Sed  OS << "__builtin_choose_expr(";
1468193326Sed  PrintExpr(Node->getCond());
1469193326Sed  OS << ", ";
1470193326Sed  PrintExpr(Node->getLHS());
1471193326Sed  OS << ", ";
1472193326Sed  PrintExpr(Node->getRHS());
1473193326Sed  OS << ")";
1474193326Sed}
1475193326Sed
1476193326Sedvoid StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
1477193326Sed  OS << "__null";
1478193326Sed}
1479193326Sed
1480193326Sedvoid StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
1481193326Sed  OS << "__builtin_shufflevector(";
1482193326Sed  for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
1483193326Sed    if (i) OS << ", ";
1484193326Sed    PrintExpr(Node->getExpr(i));
1485193326Sed  }
1486193326Sed  OS << ")";
1487193326Sed}
1488193326Sed
1489261991Sdimvoid StmtPrinter::VisitConvertVectorExpr(ConvertVectorExpr *Node) {
1490261991Sdim  OS << "__builtin_convertvector(";
1491261991Sdim  PrintExpr(Node->getSrcExpr());
1492261991Sdim  OS << ", ";
1493261991Sdim  Node->getType().print(OS, Policy);
1494261991Sdim  OS << ")";
1495261991Sdim}
1496261991Sdim
1497193326Sedvoid StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
1498193326Sed  if (Node->getSyntacticForm()) {
1499193326Sed    Visit(Node->getSyntacticForm());
1500193326Sed    return;
1501193326Sed  }
1502193326Sed
1503288943Sdim  OS << "{";
1504193326Sed  for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
1505193326Sed    if (i) OS << ", ";
1506193326Sed    if (Node->getInit(i))
1507193326Sed      PrintExpr(Node->getInit(i));
1508193326Sed    else
1509288943Sdim      OS << "{}";
1510193326Sed  }
1511288943Sdim  OS << "}";
1512193326Sed}
1513193326Sed
1514314564Sdimvoid StmtPrinter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *Node) {
1515314564Sdim  // There's no way to express this expression in any of our supported
1516314564Sdim  // languages, so just emit something terse and (hopefully) clear.
1517314564Sdim  OS << "{";
1518314564Sdim  PrintExpr(Node->getSubExpr());
1519314564Sdim  OS << "}";
1520314564Sdim}
1521314564Sdim
1522314564Sdimvoid StmtPrinter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *Node) {
1523314564Sdim  OS << "*";
1524314564Sdim}
1525314564Sdim
1526198092Srdivackyvoid StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
1527288943Sdim  OS << "(";
1528198092Srdivacky  for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {
1529198092Srdivacky    if (i) OS << ", ";
1530198092Srdivacky    PrintExpr(Node->getExpr(i));
1531198092Srdivacky  }
1532288943Sdim  OS << ")";
1533198092Srdivacky}
1534198092Srdivacky
1535193326Sedvoid StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
1536288943Sdim  bool NeedsEquals = true;
1537309124Sdim  for (const DesignatedInitExpr::Designator &D : Node->designators()) {
1538309124Sdim    if (D.isFieldDesignator()) {
1539309124Sdim      if (D.getDotLoc().isInvalid()) {
1540309124Sdim        if (IdentifierInfo *II = D.getFieldName()) {
1541276479Sdim          OS << II->getName() << ":";
1542288943Sdim          NeedsEquals = false;
1543288943Sdim        }
1544276479Sdim      } else {
1545309124Sdim        OS << "." << D.getFieldName()->getName();
1546276479Sdim      }
1547193326Sed    } else {
1548193326Sed      OS << "[";
1549309124Sdim      if (D.isArrayDesignator()) {
1550309124Sdim        PrintExpr(Node->getArrayIndex(D));
1551193326Sed      } else {
1552309124Sdim        PrintExpr(Node->getArrayRangeStart(D));
1553193326Sed        OS << " ... ";
1554309124Sdim        PrintExpr(Node->getArrayRangeEnd(D));
1555193326Sed      }
1556193326Sed      OS << "]";
1557193326Sed    }
1558193326Sed  }
1559193326Sed
1560288943Sdim  if (NeedsEquals)
1561288943Sdim    OS << " = ";
1562288943Sdim  else
1563288943Sdim    OS << " ";
1564193326Sed  PrintExpr(Node->getInit());
1565193326Sed}
1566193326Sed
1567288943Sdimvoid StmtPrinter::VisitDesignatedInitUpdateExpr(
1568288943Sdim    DesignatedInitUpdateExpr *Node) {
1569288943Sdim  OS << "{";
1570288943Sdim  OS << "/*base*/";
1571288943Sdim  PrintExpr(Node->getBase());
1572288943Sdim  OS << ", ";
1573288943Sdim
1574288943Sdim  OS << "/*updater*/";
1575288943Sdim  PrintExpr(Node->getUpdater());
1576288943Sdim  OS << "}";
1577288943Sdim}
1578288943Sdim
1579288943Sdimvoid StmtPrinter::VisitNoInitExpr(NoInitExpr *Node) {
1580288943Sdim  OS << "/*no init*/";
1581288943Sdim}
1582288943Sdim
1583193326Sedvoid StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
1584309124Sdim  if (Node->getType()->getAsCXXRecordDecl()) {
1585249423Sdim    OS << "/*implicit*/";
1586249423Sdim    Node->getType().print(OS, Policy);
1587249423Sdim    OS << "()";
1588249423Sdim  } else {
1589249423Sdim    OS << "/*implicit*/(";
1590249423Sdim    Node->getType().print(OS, Policy);
1591249423Sdim    OS << ')';
1592193326Sed    if (Node->getType()->isRecordType())
1593193326Sed      OS << "{}";
1594193326Sed    else
1595193326Sed      OS << 0;
1596193326Sed  }
1597193326Sed}
1598193326Sed
1599193326Sedvoid StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
1600193326Sed  OS << "__builtin_va_arg(";
1601193326Sed  PrintExpr(Node->getSubExpr());
1602193326Sed  OS << ", ";
1603249423Sdim  Node->getType().print(OS, Policy);
1604193326Sed  OS << ")";
1605193326Sed}
1606193326Sed
1607234353Sdimvoid StmtPrinter::VisitPseudoObjectExpr(PseudoObjectExpr *Node) {
1608234353Sdim  PrintExpr(Node->getSyntacticForm());
1609234353Sdim}
1610234353Sdim
1611226633Sdimvoid StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) {
1612276479Sdim  const char *Name = nullptr;
1613226633Sdim  switch (Node->getOp()) {
1614234353Sdim#define BUILTIN(ID, TYPE, ATTRS)
1615234353Sdim#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
1616234353Sdim  case AtomicExpr::AO ## ID: \
1617234353Sdim    Name = #ID "("; \
1618234353Sdim    break;
1619234353Sdim#include "clang/Basic/Builtins.def"
1620226633Sdim  }
1621226633Sdim  OS << Name;
1622234353Sdim
1623234353Sdim  // AtomicExpr stores its subexpressions in a permuted order.
1624226633Sdim  PrintExpr(Node->getPtr());
1625234353Sdim  if (Node->getOp() != AtomicExpr::AO__c11_atomic_load &&
1626327952Sdim      Node->getOp() != AtomicExpr::AO__atomic_load_n &&
1627327952Sdim      Node->getOp() != AtomicExpr::AO__opencl_atomic_load) {
1628251662Sdim    OS << ", ";
1629226633Sdim    PrintExpr(Node->getVal1());
1630226633Sdim  }
1631234353Sdim  if (Node->getOp() == AtomicExpr::AO__atomic_exchange ||
1632234353Sdim      Node->isCmpXChg()) {
1633251662Sdim    OS << ", ";
1634226633Sdim    PrintExpr(Node->getVal2());
1635226633Sdim  }
1636234353Sdim  if (Node->getOp() == AtomicExpr::AO__atomic_compare_exchange ||
1637234353Sdim      Node->getOp() == AtomicExpr::AO__atomic_compare_exchange_n) {
1638251662Sdim    OS << ", ";
1639234353Sdim    PrintExpr(Node->getWeak());
1640251662Sdim  }
1641327952Sdim  if (Node->getOp() != AtomicExpr::AO__c11_atomic_init &&
1642327952Sdim      Node->getOp() != AtomicExpr::AO__opencl_atomic_init) {
1643234353Sdim    OS << ", ";
1644251662Sdim    PrintExpr(Node->getOrder());
1645234353Sdim  }
1646226633Sdim  if (Node->isCmpXChg()) {
1647226633Sdim    OS << ", ";
1648226633Sdim    PrintExpr(Node->getOrderFail());
1649226633Sdim  }
1650226633Sdim  OS << ")";
1651226633Sdim}
1652226633Sdim
1653193326Sed// C++
1654193326Sedvoid StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
1655193326Sed  OverloadedOperatorKind Kind = Node->getOperator();
1656193326Sed  if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
1657193326Sed    if (Node->getNumArgs() == 1) {
1658353358Sdim      OS << getOperatorSpelling(Kind) << ' ';
1659193326Sed      PrintExpr(Node->getArg(0));
1660193326Sed    } else {
1661193326Sed      PrintExpr(Node->getArg(0));
1662353358Sdim      OS << ' ' << getOperatorSpelling(Kind);
1663193326Sed    }
1664243830Sdim  } else if (Kind == OO_Arrow) {
1665243830Sdim    PrintExpr(Node->getArg(0));
1666193326Sed  } else if (Kind == OO_Call) {
1667193326Sed    PrintExpr(Node->getArg(0));
1668193326Sed    OS << '(';
1669193326Sed    for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) {
1670193326Sed      if (ArgIdx > 1)
1671193326Sed        OS << ", ";
1672193326Sed      if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx)))
1673193326Sed        PrintExpr(Node->getArg(ArgIdx));
1674193326Sed    }
1675193326Sed    OS << ')';
1676193326Sed  } else if (Kind == OO_Subscript) {
1677193326Sed    PrintExpr(Node->getArg(0));
1678193326Sed    OS << '[';
1679193326Sed    PrintExpr(Node->getArg(1));
1680193326Sed    OS << ']';
1681193326Sed  } else if (Node->getNumArgs() == 1) {
1682353358Sdim    OS << getOperatorSpelling(Kind) << ' ';
1683193326Sed    PrintExpr(Node->getArg(0));
1684193326Sed  } else if (Node->getNumArgs() == 2) {
1685193326Sed    PrintExpr(Node->getArg(0));
1686353358Sdim    OS << ' ' << getOperatorSpelling(Kind) << ' ';
1687193326Sed    PrintExpr(Node->getArg(1));
1688193326Sed  } else {
1689226633Sdim    llvm_unreachable("unknown overloaded operator");
1690193326Sed  }
1691193326Sed}
1692193326Sed
1693193326Sedvoid StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
1694276479Sdim  // If we have a conversion operator call only print the argument.
1695276479Sdim  CXXMethodDecl *MD = Node->getMethodDecl();
1696276479Sdim  if (MD && isa<CXXConversionDecl>(MD)) {
1697276479Sdim    PrintExpr(Node->getImplicitObjectArgument());
1698276479Sdim    return;
1699276479Sdim  }
1700193326Sed  VisitCallExpr(cast<CallExpr>(Node));
1701193326Sed}
1702193326Sed
1703218893Sdimvoid StmtPrinter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *Node) {
1704218893Sdim  PrintExpr(Node->getCallee());
1705218893Sdim  OS << "<<<";
1706218893Sdim  PrintCallArgs(Node->getConfig());
1707218893Sdim  OS << ">>>(";
1708218893Sdim  PrintCallArgs(Node);
1709218893Sdim  OS << ")";
1710218893Sdim}
1711218893Sdim
1712360784Sdimvoid StmtPrinter::VisitCXXRewrittenBinaryOperator(
1713360784Sdim    CXXRewrittenBinaryOperator *Node) {
1714360784Sdim  CXXRewrittenBinaryOperator::DecomposedForm Decomposed =
1715360784Sdim      Node->getDecomposedForm();
1716360784Sdim  PrintExpr(const_cast<Expr*>(Decomposed.LHS));
1717360784Sdim  OS << ' ' << BinaryOperator::getOpcodeStr(Decomposed.Opcode) << ' ';
1718360784Sdim  PrintExpr(const_cast<Expr*>(Decomposed.RHS));
1719360784Sdim}
1720360784Sdim
1721193326Sedvoid StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
1722193326Sed  OS << Node->getCastName() << '<';
1723249423Sdim  Node->getTypeAsWritten().print(OS, Policy);
1724249423Sdim  OS << ">(";
1725193326Sed  PrintExpr(Node->getSubExpr());
1726193326Sed  OS << ")";
1727193326Sed}
1728193326Sed
1729193326Sedvoid StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {
1730193326Sed  VisitCXXNamedCastExpr(Node);
1731193326Sed}
1732193326Sed
1733193326Sedvoid StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {
1734193326Sed  VisitCXXNamedCastExpr(Node);
1735193326Sed}
1736193326Sed
1737193326Sedvoid StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {
1738193326Sed  VisitCXXNamedCastExpr(Node);
1739193326Sed}
1740193326Sed
1741193326Sedvoid StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
1742193326Sed  VisitCXXNamedCastExpr(Node);
1743193326Sed}
1744193326Sed
1745353358Sdimvoid StmtPrinter::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *Node) {
1746353358Sdim  OS << "__builtin_bit_cast(";
1747353358Sdim  Node->getTypeInfoAsWritten()->getType().print(OS, Policy);
1748353358Sdim  OS << ", ";
1749353358Sdim  PrintExpr(Node->getSubExpr());
1750353358Sdim  OS << ")";
1751353358Sdim}
1752353358Sdim
1753193326Sedvoid StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
1754193326Sed  OS << "typeid(";
1755193326Sed  if (Node->isTypeOperand()) {
1756261991Sdim    Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
1757193326Sed  } else {
1758193326Sed    PrintExpr(Node->getExprOperand());
1759193326Sed  }
1760193326Sed  OS << ")";
1761193326Sed}
1762193326Sed
1763218893Sdimvoid StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) {
1764218893Sdim  OS << "__uuidof(";
1765218893Sdim  if (Node->isTypeOperand()) {
1766261991Sdim    Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
1767218893Sdim  } else {
1768218893Sdim    PrintExpr(Node->getExprOperand());
1769218893Sdim  }
1770218893Sdim  OS << ")";
1771218893Sdim}
1772218893Sdim
1773251662Sdimvoid StmtPrinter::VisitMSPropertyRefExpr(MSPropertyRefExpr *Node) {
1774251662Sdim  PrintExpr(Node->getBaseExpr());
1775251662Sdim  if (Node->isArrow())
1776251662Sdim    OS << "->";
1777251662Sdim  else
1778251662Sdim    OS << ".";
1779251662Sdim  if (NestedNameSpecifier *Qualifier =
1780251662Sdim      Node->getQualifierLoc().getNestedNameSpecifier())
1781251662Sdim    Qualifier->print(OS, Policy);
1782251662Sdim  OS << Node->getPropertyDecl()->getDeclName();
1783251662Sdim}
1784251662Sdim
1785296417Sdimvoid StmtPrinter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *Node) {
1786296417Sdim  PrintExpr(Node->getBase());
1787296417Sdim  OS << "[";
1788296417Sdim  PrintExpr(Node->getIdx());
1789296417Sdim  OS << "]";
1790296417Sdim}
1791296417Sdim
1792234353Sdimvoid StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) {
1793234353Sdim  switch (Node->getLiteralOperatorKind()) {
1794234353Sdim  case UserDefinedLiteral::LOK_Raw:
1795234353Sdim    OS << cast<StringLiteral>(Node->getArg(0)->IgnoreImpCasts())->getString();
1796234353Sdim    break;
1797234353Sdim  case UserDefinedLiteral::LOK_Template: {
1798341825Sdim    const auto *DRE = cast<DeclRefExpr>(Node->getCallee()->IgnoreImpCasts());
1799234353Sdim    const TemplateArgumentList *Args =
1800234353Sdim      cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs();
1801234353Sdim    assert(Args);
1802288943Sdim
1803288943Sdim    if (Args->size() != 1) {
1804296417Sdim      OS << "operator\"\"" << Node->getUDSuffix()->getName();
1805327952Sdim      printTemplateArgumentList(OS, Args->asArray(), Policy);
1806288943Sdim      OS << "()";
1807288943Sdim      return;
1808288943Sdim    }
1809288943Sdim
1810234353Sdim    const TemplateArgument &Pack = Args->get(0);
1811276479Sdim    for (const auto &P : Pack.pack_elements()) {
1812276479Sdim      char C = (char)P.getAsIntegral().getZExtValue();
1813234353Sdim      OS << C;
1814234353Sdim    }
1815234353Sdim    break;
1816234353Sdim  }
1817234353Sdim  case UserDefinedLiteral::LOK_Integer: {
1818234353Sdim    // Print integer literal without suffix.
1819341825Sdim    const auto *Int = cast<IntegerLiteral>(Node->getCookedLiteral());
1820234353Sdim    OS << Int->getValue().toString(10, /*isSigned*/false);
1821234353Sdim    break;
1822234353Sdim  }
1823243830Sdim  case UserDefinedLiteral::LOK_Floating: {
1824243830Sdim    // Print floating literal without suffix.
1825341825Sdim    auto *Float = cast<FloatingLiteral>(Node->getCookedLiteral());
1826243830Sdim    PrintFloatingLiteral(OS, Float, /*PrintSuffix=*/false);
1827243830Sdim    break;
1828243830Sdim  }
1829234353Sdim  case UserDefinedLiteral::LOK_String:
1830234353Sdim  case UserDefinedLiteral::LOK_Character:
1831234353Sdim    PrintExpr(Node->getCookedLiteral());
1832234353Sdim    break;
1833234353Sdim  }
1834234353Sdim  OS << Node->getUDSuffix()->getName();
1835234353Sdim}
1836234353Sdim
1837193326Sedvoid StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
1838193326Sed  OS << (Node->getValue() ? "true" : "false");
1839193326Sed}
1840193326Sed
1841193326Sedvoid StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
1842193326Sed  OS << "nullptr";
1843193326Sed}
1844193326Sed
1845193326Sedvoid StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
1846193326Sed  OS << "this";
1847193326Sed}
1848193326Sed
1849193326Sedvoid StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
1850276479Sdim  if (!Node->getSubExpr())
1851193326Sed    OS << "throw";
1852193326Sed  else {
1853193326Sed    OS << "throw ";
1854193326Sed    PrintExpr(Node->getSubExpr());
1855193326Sed  }
1856193326Sed}
1857193326Sed
1858193326Sedvoid StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
1859251662Sdim  // Nothing to print: we picked up the default argument.
1860193326Sed}
1861193326Sed
1862251662Sdimvoid StmtPrinter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Node) {
1863251662Sdim  // Nothing to print: we picked up the default initializer.
1864251662Sdim}
1865251662Sdim
1866193326Sedvoid StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
1867249423Sdim  Node->getType().print(OS, Policy);
1868288943Sdim  // If there are no parens, this is list-initialization, and the braces are
1869288943Sdim  // part of the syntax of the inner construct.
1870288943Sdim  if (Node->getLParenLoc().isValid())
1871288943Sdim    OS << "(";
1872193326Sed  PrintExpr(Node->getSubExpr());
1873288943Sdim  if (Node->getLParenLoc().isValid())
1874288943Sdim    OS << ")";
1875193326Sed}
1876193326Sed
1877193326Sedvoid StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
1878193326Sed  PrintExpr(Node->getSubExpr());
1879193326Sed}
1880193326Sed
1881193326Sedvoid StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
1882249423Sdim  Node->getType().print(OS, Policy);
1883288943Sdim  if (Node->isStdInitListInitialization())
1884288943Sdim    /* Nothing to do; braces are part of creating the std::initializer_list. */;
1885288943Sdim  else if (Node->isListInitialization())
1886288943Sdim    OS << "{";
1887288943Sdim  else
1888288943Sdim    OS << "(";
1889193326Sed  for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),
1890198092Srdivacky                                         ArgEnd = Node->arg_end();
1891193326Sed       Arg != ArgEnd; ++Arg) {
1892296417Sdim    if ((*Arg)->isDefaultArgument())
1893261991Sdim      break;
1894193326Sed    if (Arg != Node->arg_begin())
1895193326Sed      OS << ", ";
1896193326Sed    PrintExpr(*Arg);
1897193326Sed  }
1898288943Sdim  if (Node->isStdInitListInitialization())
1899288943Sdim    /* See above. */;
1900288943Sdim  else if (Node->isListInitialization())
1901288943Sdim    OS << "}";
1902288943Sdim  else
1903288943Sdim    OS << ")";
1904193326Sed}
1905193326Sed
1906234353Sdimvoid StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {
1907234353Sdim  OS << '[';
1908234353Sdim  bool NeedComma = false;
1909234353Sdim  switch (Node->getCaptureDefault()) {
1910234353Sdim  case LCD_None:
1911234353Sdim    break;
1912234353Sdim
1913234353Sdim  case LCD_ByCopy:
1914234353Sdim    OS << '=';
1915234353Sdim    NeedComma = true;
1916234353Sdim    break;
1917234353Sdim
1918234353Sdim  case LCD_ByRef:
1919234353Sdim    OS << '&';
1920234353Sdim    NeedComma = true;
1921234353Sdim    break;
1922234353Sdim  }
1923234353Sdim  for (LambdaExpr::capture_iterator C = Node->explicit_capture_begin(),
1924234353Sdim                                 CEnd = Node->explicit_capture_end();
1925234353Sdim       C != CEnd;
1926234353Sdim       ++C) {
1927327952Sdim    if (C->capturesVLAType())
1928327952Sdim      continue;
1929327952Sdim
1930234353Sdim    if (NeedComma)
1931234353Sdim      OS << ", ";
1932234353Sdim    NeedComma = true;
1933234353Sdim
1934234353Sdim    switch (C->getCaptureKind()) {
1935234353Sdim    case LCK_This:
1936234353Sdim      OS << "this";
1937234353Sdim      break;
1938341825Sdim
1939309124Sdim    case LCK_StarThis:
1940309124Sdim      OS << "*this";
1941309124Sdim      break;
1942341825Sdim
1943234353Sdim    case LCK_ByRef:
1944288943Sdim      if (Node->getCaptureDefault() != LCD_ByRef || Node->isInitCapture(C))
1945234353Sdim        OS << '&';
1946234353Sdim      OS << C->getCapturedVar()->getName();
1947234353Sdim      break;
1948234353Sdim
1949234353Sdim    case LCK_ByCopy:
1950234353Sdim      OS << C->getCapturedVar()->getName();
1951234353Sdim      break;
1952341825Sdim
1953280031Sdim    case LCK_VLAType:
1954280031Sdim      llvm_unreachable("VLA type in explicit captures.");
1955234353Sdim    }
1956261991Sdim
1957353358Sdim    if (C->isPackExpansion())
1958353358Sdim      OS << "...";
1959353358Sdim
1960288943Sdim    if (Node->isInitCapture(C))
1961261991Sdim      PrintExpr(C->getCapturedVar()->getInit());
1962234353Sdim  }
1963234353Sdim  OS << ']';
1964234353Sdim
1965353358Sdim  if (!Node->getExplicitTemplateParameters().empty()) {
1966353358Sdim    Node->getTemplateParameterList()->print(
1967353358Sdim        OS, Node->getLambdaClass()->getASTContext(),
1968353358Sdim        /*OmitTemplateKW*/true);
1969353358Sdim  }
1970353358Sdim
1971234353Sdim  if (Node->hasExplicitParameters()) {
1972353358Sdim    OS << '(';
1973234353Sdim    CXXMethodDecl *Method = Node->getCallOperator();
1974234353Sdim    NeedComma = false;
1975341825Sdim    for (const auto *P : Method->parameters()) {
1976234353Sdim      if (NeedComma) {
1977234353Sdim        OS << ", ";
1978234353Sdim      } else {
1979234353Sdim        NeedComma = true;
1980234353Sdim      }
1981276479Sdim      std::string ParamStr = P->getNameAsString();
1982276479Sdim      P->getOriginalType().print(OS, Policy, ParamStr);
1983234353Sdim    }
1984234353Sdim    if (Method->isVariadic()) {
1985234353Sdim      if (NeedComma)
1986234353Sdim        OS << ", ";
1987234353Sdim      OS << "...";
1988234353Sdim    }
1989234353Sdim    OS << ')';
1990234353Sdim
1991234353Sdim    if (Node->isMutable())
1992234353Sdim      OS << " mutable";
1993234353Sdim
1994360784Sdim    auto *Proto = Method->getType()->castAs<FunctionProtoType>();
1995249423Sdim    Proto->printExceptionSpecification(OS, Policy);
1996234353Sdim
1997234353Sdim    // FIXME: Attributes
1998234353Sdim
1999234353Sdim    // Print the trailing return type if it was specified in the source.
2000249423Sdim    if (Node->hasExplicitResultType()) {
2001249423Sdim      OS << " -> ";
2002276479Sdim      Proto->getReturnType().print(OS, Policy);
2003249423Sdim    }
2004234353Sdim  }
2005234353Sdim
2006234353Sdim  // Print the body.
2007234353Sdim  OS << ' ';
2008353358Sdim  if (Policy.TerseOutput)
2009353358Sdim    OS << "{}";
2010353358Sdim  else
2011353358Sdim    PrintRawCompoundStmt(Node->getBody());
2012234353Sdim}
2013234353Sdim
2014210299Sedvoid StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) {
2015218893Sdim  if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo())
2016249423Sdim    TSInfo->getType().print(OS, Policy);
2017218893Sdim  else
2018249423Sdim    Node->getType().print(OS, Policy);
2019249423Sdim  OS << "()";
2020193326Sed}
2021193326Sed
2022193326Sedvoid StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
2023193326Sed  if (E->isGlobalNew())
2024193326Sed    OS << "::";
2025193326Sed  OS << "new ";
2026193326Sed  unsigned NumPlace = E->getNumPlacementArgs();
2027243830Sdim  if (NumPlace > 0 && !isa<CXXDefaultArgExpr>(E->getPlacementArg(0))) {
2028193326Sed    OS << "(";
2029193326Sed    PrintExpr(E->getPlacementArg(0));
2030193326Sed    for (unsigned i = 1; i < NumPlace; ++i) {
2031243830Sdim      if (isa<CXXDefaultArgExpr>(E->getPlacementArg(i)))
2032243830Sdim        break;
2033193326Sed      OS << ", ";
2034193326Sed      PrintExpr(E->getPlacementArg(i));
2035193326Sed    }
2036193326Sed    OS << ") ";
2037193326Sed  }
2038193326Sed  if (E->isParenTypeId())
2039193326Sed    OS << "(";
2040193326Sed  std::string TypeS;
2041353358Sdim  if (Optional<Expr *> Size = E->getArraySize()) {
2042193326Sed    llvm::raw_string_ostream s(TypeS);
2043249423Sdim    s << '[';
2044353358Sdim    if (*Size)
2045353358Sdim      (*Size)->printPretty(s, Helper, Policy);
2046249423Sdim    s << ']';
2047193326Sed  }
2048249423Sdim  E->getAllocatedType().print(OS, Policy, TypeS);
2049193326Sed  if (E->isParenTypeId())
2050193326Sed    OS << ")";
2051193326Sed
2052234353Sdim  CXXNewExpr::InitializationStyle InitStyle = E->getInitializationStyle();
2053234353Sdim  if (InitStyle) {
2054234353Sdim    if (InitStyle == CXXNewExpr::CallInit)
2055234353Sdim      OS << "(";
2056234353Sdim    PrintExpr(E->getInitializer());
2057234353Sdim    if (InitStyle == CXXNewExpr::CallInit)
2058234353Sdim      OS << ")";
2059193326Sed  }
2060193326Sed}
2061193326Sed
2062193326Sedvoid StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
2063193326Sed  if (E->isGlobalDelete())
2064193326Sed    OS << "::";
2065193326Sed  OS << "delete ";
2066193326Sed  if (E->isArrayForm())
2067193326Sed    OS << "[] ";
2068193326Sed  PrintExpr(E->getArgument());
2069193326Sed}
2070193326Sed
2071198092Srdivackyvoid StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
2072198092Srdivacky  PrintExpr(E->getBase());
2073198092Srdivacky  if (E->isArrow())
2074198092Srdivacky    OS << "->";
2075198092Srdivacky  else
2076198092Srdivacky    OS << '.';
2077198092Srdivacky  if (E->getQualifier())
2078198092Srdivacky    E->getQualifier()->print(OS, Policy);
2079243830Sdim  OS << "~";
2080198092Srdivacky
2081204643Srdivacky  if (IdentifierInfo *II = E->getDestroyedTypeIdentifier())
2082204643Srdivacky    OS << II->getName();
2083204643Srdivacky  else
2084249423Sdim    E->getDestroyedType().print(OS, Policy);
2085198092Srdivacky}
2086198092Srdivacky
2087193326Sedvoid StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
2088288943Sdim  if (E->isListInitialization() && !E->isStdInitListInitialization())
2089288943Sdim    OS << "{";
2090249423Sdim
2091218893Sdim  for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
2092218893Sdim    if (isa<CXXDefaultArgExpr>(E->getArg(i))) {
2093218893Sdim      // Don't print any defaulted arguments
2094218893Sdim      break;
2095218893Sdim    }
2096218893Sdim
2097218893Sdim    if (i) OS << ", ";
2098218893Sdim    PrintExpr(E->getArg(i));
2099202379Srdivacky  }
2100249423Sdim
2101288943Sdim  if (E->isListInitialization() && !E->isStdInitListInitialization())
2102288943Sdim    OS << "}";
2103193326Sed}
2104193326Sed
2105309124Sdimvoid StmtPrinter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {
2106309124Sdim  // Parens are printed by the surrounding context.
2107309124Sdim  OS << "<forwarded>";
2108309124Sdim}
2109309124Sdim
2110261991Sdimvoid StmtPrinter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
2111261991Sdim  PrintExpr(E->getSubExpr());
2112261991Sdim}
2113261991Sdim
2114218893Sdimvoid StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) {
2115276479Sdim  // Just forward to the subexpression.
2116193326Sed  PrintExpr(E->getSubExpr());
2117193326Sed}
2118193326Sed
2119198092Srdivackyvoid
2120193326SedStmtPrinter::VisitCXXUnresolvedConstructExpr(
2121193326Sed                                           CXXUnresolvedConstructExpr *Node) {
2122249423Sdim  Node->getTypeAsWritten().print(OS, Policy);
2123193326Sed  OS << "(";
2124193326Sed  for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(),
2125198092Srdivacky                                             ArgEnd = Node->arg_end();
2126193326Sed       Arg != ArgEnd; ++Arg) {
2127193326Sed    if (Arg != Node->arg_begin())
2128193326Sed      OS << ", ";
2129193326Sed    PrintExpr(*Arg);
2130193326Sed  }
2131193326Sed  OS << ")";
2132193326Sed}
2133193326Sed
2134199990Srdivackyvoid StmtPrinter::VisitCXXDependentScopeMemberExpr(
2135199990Srdivacky                                         CXXDependentScopeMemberExpr *Node) {
2136200583Srdivacky  if (!Node->isImplicitAccess()) {
2137200583Srdivacky    PrintExpr(Node->getBase());
2138200583Srdivacky    OS << (Node->isArrow() ? "->" : ".");
2139200583Srdivacky  }
2140198092Srdivacky  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
2141198092Srdivacky    Qualifier->print(OS, Policy);
2142234353Sdim  if (Node->hasTemplateKeyword())
2143198092Srdivacky    OS << "template ";
2144212904Sdim  OS << Node->getMemberNameInfo();
2145249423Sdim  if (Node->hasExplicitTemplateArgs())
2146327952Sdim    printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2147193326Sed}
2148193326Sed
2149199990Srdivackyvoid StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
2150200583Srdivacky  if (!Node->isImplicitAccess()) {
2151200583Srdivacky    PrintExpr(Node->getBase());
2152200583Srdivacky    OS << (Node->isArrow() ? "->" : ".");
2153200583Srdivacky  }
2154199990Srdivacky  if (NestedNameSpecifier *Qualifier = Node->getQualifier())
2155199990Srdivacky    Qualifier->print(OS, Policy);
2156234353Sdim  if (Node->hasTemplateKeyword())
2157234353Sdim    OS << "template ";
2158212904Sdim  OS << Node->getMemberNameInfo();
2159249423Sdim  if (Node->hasExplicitTemplateArgs())
2160327952Sdim    printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2161199990Srdivacky}
2162199990Srdivacky
2163234353Sdimstatic const char *getTypeTraitName(TypeTrait TT) {
2164234353Sdim  switch (TT) {
2165276479Sdim#define TYPE_TRAIT_1(Spelling, Name, Key) \
2166276479Sdimcase clang::UTT_##Name: return #Spelling;
2167276479Sdim#define TYPE_TRAIT_2(Spelling, Name, Key) \
2168276479Sdimcase clang::BTT_##Name: return #Spelling;
2169276479Sdim#define TYPE_TRAIT_N(Spelling, Name, Key) \
2170276479Sdim  case clang::TT_##Name: return #Spelling;
2171276479Sdim#include "clang/Basic/TokenKinds.def"
2172234353Sdim  }
2173234353Sdim  llvm_unreachable("Type trait not covered by switch");
2174234353Sdim}
2175234353Sdim
2176221345Sdimstatic const char *getTypeTraitName(ArrayTypeTrait ATT) {
2177221345Sdim  switch (ATT) {
2178221345Sdim  case ATT_ArrayRank:        return "__array_rank";
2179221345Sdim  case ATT_ArrayExtent:      return "__array_extent";
2180221345Sdim  }
2181221345Sdim  llvm_unreachable("Array type trait not covered by switch");
2182221345Sdim}
2183221345Sdim
2184221345Sdimstatic const char *getExpressionTraitName(ExpressionTrait ET) {
2185221345Sdim  switch (ET) {
2186221345Sdim  case ET_IsLValueExpr:      return "__is_lvalue_expr";
2187221345Sdim  case ET_IsRValueExpr:      return "__is_rvalue_expr";
2188221345Sdim  }
2189221345Sdim  llvm_unreachable("Expression type trait not covered by switch");
2190221345Sdim}
2191221345Sdim
2192234353Sdimvoid StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) {
2193234353Sdim  OS << getTypeTraitName(E->getTrait()) << "(";
2194234353Sdim  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
2195234353Sdim    if (I > 0)
2196234353Sdim      OS << ", ";
2197249423Sdim    E->getArg(I)->getType().print(OS, Policy);
2198234353Sdim  }
2199234353Sdim  OS << ")";
2200234353Sdim}
2201234353Sdim
2202221345Sdimvoid StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
2203249423Sdim  OS << getTypeTraitName(E->getTrait()) << '(';
2204249423Sdim  E->getQueriedType().print(OS, Policy);
2205249423Sdim  OS << ')';
2206221345Sdim}
2207221345Sdim
2208221345Sdimvoid StmtPrinter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
2209249423Sdim  OS << getExpressionTraitName(E->getTrait()) << '(';
2210249423Sdim  PrintExpr(E->getQueriedExpression());
2211249423Sdim  OS << ')';
2212221345Sdim}
2213221345Sdim
2214218893Sdimvoid StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
2215218893Sdim  OS << "noexcept(";
2216218893Sdim  PrintExpr(E->getOperand());
2217218893Sdim  OS << ")";
2218218893Sdim}
2219218893Sdim
2220218893Sdimvoid StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) {
2221218893Sdim  PrintExpr(E->getPattern());
2222218893Sdim  OS << "...";
2223218893Sdim}
2224218893Sdim
2225218893Sdimvoid StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2226234353Sdim  OS << "sizeof...(" << *E->getPack() << ")";
2227218893Sdim}
2228218893Sdim
2229218893Sdimvoid StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr(
2230218893Sdim                                       SubstNonTypeTemplateParmPackExpr *Node) {
2231234353Sdim  OS << *Node->getParameterPack();
2232218893Sdim}
2233218893Sdim
2234224145Sdimvoid StmtPrinter::VisitSubstNonTypeTemplateParmExpr(
2235224145Sdim                                       SubstNonTypeTemplateParmExpr *Node) {
2236224145Sdim  Visit(Node->getReplacement());
2237224145Sdim}
2238224145Sdim
2239243830Sdimvoid StmtPrinter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
2240243830Sdim  OS << *E->getParameterPack();
2241243830Sdim}
2242243830Sdim
2243224145Sdimvoid StmtPrinter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *Node){
2244360784Sdim  PrintExpr(Node->getSubExpr());
2245224145Sdim}
2246224145Sdim
2247280031Sdimvoid StmtPrinter::VisitCXXFoldExpr(CXXFoldExpr *E) {
2248280031Sdim  OS << "(";
2249280031Sdim  if (E->getLHS()) {
2250280031Sdim    PrintExpr(E->getLHS());
2251280031Sdim    OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2252280031Sdim  }
2253280031Sdim  OS << "...";
2254280031Sdim  if (E->getRHS()) {
2255280031Sdim    OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2256280031Sdim    PrintExpr(E->getRHS());
2257280031Sdim  }
2258280031Sdim  OS << ")";
2259280031Sdim}
2260280031Sdim
2261360784Sdimvoid StmtPrinter::VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) {
2262360784Sdim  NestedNameSpecifierLoc NNS = E->getNestedNameSpecifierLoc();
2263360784Sdim  if (NNS)
2264360784Sdim    NNS.getNestedNameSpecifier()->print(OS, Policy);
2265360784Sdim  if (E->getTemplateKWLoc().isValid())
2266360784Sdim    OS << "template ";
2267360784Sdim  OS << E->getFoundDecl()->getName();
2268360784Sdim  printTemplateArgumentList(OS, E->getTemplateArgsAsWritten()->arguments(),
2269360784Sdim                            Policy);
2270360784Sdim}
2271360784Sdim
2272360784Sdimvoid StmtPrinter::VisitRequiresExpr(RequiresExpr *E) {
2273360784Sdim  OS << "requires ";
2274360784Sdim  auto LocalParameters = E->getLocalParameters();
2275360784Sdim  if (!LocalParameters.empty()) {
2276360784Sdim    OS << "(";
2277360784Sdim    for (ParmVarDecl *LocalParam : LocalParameters) {
2278360784Sdim      PrintRawDecl(LocalParam);
2279360784Sdim      if (LocalParam != LocalParameters.back())
2280360784Sdim        OS << ", ";
2281360784Sdim    }
2282360784Sdim
2283360784Sdim    OS << ") ";
2284360784Sdim  }
2285360784Sdim  OS << "{ ";
2286360784Sdim  auto Requirements = E->getRequirements();
2287360784Sdim  for (concepts::Requirement *Req : Requirements) {
2288360784Sdim    if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
2289360784Sdim      if (TypeReq->isSubstitutionFailure())
2290360784Sdim        OS << "<<error-type>>";
2291360784Sdim      else
2292360784Sdim        TypeReq->getType()->getType().print(OS, Policy);
2293360784Sdim    } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
2294360784Sdim      if (ExprReq->isCompound())
2295360784Sdim        OS << "{ ";
2296360784Sdim      if (ExprReq->isExprSubstitutionFailure())
2297360784Sdim        OS << "<<error-expression>>";
2298360784Sdim      else
2299360784Sdim        PrintExpr(ExprReq->getExpr());
2300360784Sdim      if (ExprReq->isCompound()) {
2301360784Sdim        OS << " }";
2302360784Sdim        if (ExprReq->getNoexceptLoc().isValid())
2303360784Sdim          OS << " noexcept";
2304360784Sdim        const auto &RetReq = ExprReq->getReturnTypeRequirement();
2305360784Sdim        if (!RetReq.isEmpty()) {
2306360784Sdim          OS << " -> ";
2307360784Sdim          if (RetReq.isSubstitutionFailure())
2308360784Sdim            OS << "<<error-type>>";
2309360784Sdim          else if (RetReq.isTypeConstraint())
2310360784Sdim            RetReq.getTypeConstraint()->print(OS, Policy);
2311360784Sdim        }
2312360784Sdim      }
2313360784Sdim    } else {
2314360784Sdim      auto *NestedReq = cast<concepts::NestedRequirement>(Req);
2315360784Sdim      OS << "requires ";
2316360784Sdim      if (NestedReq->isSubstitutionFailure())
2317360784Sdim        OS << "<<error-expression>>";
2318360784Sdim      else
2319360784Sdim        PrintExpr(NestedReq->getConstraintExpr());
2320360784Sdim    }
2321360784Sdim    OS << "; ";
2322360784Sdim  }
2323360784Sdim  OS << "}";
2324360784Sdim}
2325360784Sdim
2326296417Sdim// C++ Coroutines TS
2327296417Sdim
2328296417Sdimvoid StmtPrinter::VisitCoroutineBodyStmt(CoroutineBodyStmt *S) {
2329296417Sdim  Visit(S->getBody());
2330296417Sdim}
2331296417Sdim
2332296417Sdimvoid StmtPrinter::VisitCoreturnStmt(CoreturnStmt *S) {
2333296417Sdim  OS << "co_return";
2334296417Sdim  if (S->getOperand()) {
2335296417Sdim    OS << " ";
2336296417Sdim    Visit(S->getOperand());
2337296417Sdim  }
2338296417Sdim  OS << ";";
2339296417Sdim}
2340296417Sdim
2341296417Sdimvoid StmtPrinter::VisitCoawaitExpr(CoawaitExpr *S) {
2342296417Sdim  OS << "co_await ";
2343296417Sdim  PrintExpr(S->getOperand());
2344296417Sdim}
2345296417Sdim
2346321369Sdimvoid StmtPrinter::VisitDependentCoawaitExpr(DependentCoawaitExpr *S) {
2347321369Sdim  OS << "co_await ";
2348321369Sdim  PrintExpr(S->getOperand());
2349321369Sdim}
2350321369Sdim
2351296417Sdimvoid StmtPrinter::VisitCoyieldExpr(CoyieldExpr *S) {
2352296417Sdim  OS << "co_yield ";
2353296417Sdim  PrintExpr(S->getOperand());
2354296417Sdim}
2355296417Sdim
2356198092Srdivacky// Obj-C
2357193326Sed
2358193326Sedvoid StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
2359193326Sed  OS << "@";
2360193326Sed  VisitStringLiteral(Node->getString());
2361193326Sed}
2362193326Sed
2363239462Sdimvoid StmtPrinter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
2364234353Sdim  OS << "@";
2365239462Sdim  Visit(E->getSubExpr());
2366234353Sdim}
2367234353Sdim
2368234353Sdimvoid StmtPrinter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
2369234353Sdim  OS << "@[ ";
2370296417Sdim  ObjCArrayLiteral::child_range Ch = E->children();
2371296417Sdim  for (auto I = Ch.begin(), E = Ch.end(); I != E; ++I) {
2372296417Sdim    if (I != Ch.begin())
2373234353Sdim      OS << ", ";
2374296417Sdim    Visit(*I);
2375234353Sdim  }
2376234353Sdim  OS << " ]";
2377234353Sdim}
2378234353Sdim
2379234353Sdimvoid StmtPrinter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
2380234353Sdim  OS << "@{ ";
2381234353Sdim  for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
2382234353Sdim    if (I > 0)
2383234353Sdim      OS << ", ";
2384341825Sdim
2385234353Sdim    ObjCDictionaryElement Element = E->getKeyValueElement(I);
2386234353Sdim    Visit(Element.Key);
2387234353Sdim    OS << " : ";
2388234353Sdim    Visit(Element.Value);
2389234353Sdim    if (Element.isPackExpansion())
2390234353Sdim      OS << "...";
2391234353Sdim  }
2392234353Sdim  OS << " }";
2393234353Sdim}
2394234353Sdim
2395193326Sedvoid StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
2396249423Sdim  OS << "@encode(";
2397249423Sdim  Node->getEncodedType().print(OS, Policy);
2398249423Sdim  OS << ')';
2399193326Sed}
2400193326Sed
2401193326Sedvoid StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
2402276479Sdim  OS << "@selector(";
2403276479Sdim  Node->getSelector().print(OS);
2404276479Sdim  OS << ')';
2405193326Sed}
2406193326Sed
2407193326Sedvoid StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
2408226633Sdim  OS << "@protocol(" << *Node->getProtocol() << ')';
2409193326Sed}
2410193326Sed
2411193326Sedvoid StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
2412193326Sed  OS << "[";
2413207619Srdivacky  switch (Mess->getReceiverKind()) {
2414207619Srdivacky  case ObjCMessageExpr::Instance:
2415207619Srdivacky    PrintExpr(Mess->getInstanceReceiver());
2416207619Srdivacky    break;
2417207619Srdivacky
2418207619Srdivacky  case ObjCMessageExpr::Class:
2419249423Sdim    Mess->getClassReceiver().print(OS, Policy);
2420207619Srdivacky    break;
2421207619Srdivacky
2422207619Srdivacky  case ObjCMessageExpr::SuperInstance:
2423207619Srdivacky  case ObjCMessageExpr::SuperClass:
2424207619Srdivacky    OS << "Super";
2425207619Srdivacky    break;
2426207619Srdivacky  }
2427207619Srdivacky
2428193326Sed  OS << ' ';
2429193326Sed  Selector selector = Mess->getSelector();
2430193326Sed  if (selector.isUnarySelector()) {
2431218893Sdim    OS << selector.getNameForSlot(0);
2432193326Sed  } else {
2433193326Sed    for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
2434193326Sed      if (i < selector.getNumArgs()) {
2435193326Sed        if (i > 0) OS << ' ';
2436193326Sed        if (selector.getIdentifierInfoForSlot(i))
2437193326Sed          OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';
2438193326Sed        else
2439193326Sed           OS << ":";
2440193326Sed      }
2441193326Sed      else OS << ", "; // Handle variadic methods.
2442198092Srdivacky
2443193326Sed      PrintExpr(Mess->getArg(i));
2444193326Sed    }
2445193326Sed  }
2446193326Sed  OS << "]";
2447193326Sed}
2448193326Sed
2449234353Sdimvoid StmtPrinter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) {
2450234353Sdim  OS << (Node->getValue() ? "__objc_yes" : "__objc_no");
2451234353Sdim}
2452234353Sdim
2453224145Sdimvoid
2454224145SdimStmtPrinter::VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
2455224145Sdim  PrintExpr(E->getSubExpr());
2456224145Sdim}
2457193326Sed
2458224145Sdimvoid
2459224145SdimStmtPrinter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
2460249423Sdim  OS << '(' << E->getBridgeKindName();
2461249423Sdim  E->getType().print(OS, Policy);
2462249423Sdim  OS << ')';
2463224145Sdim  PrintExpr(E->getSubExpr());
2464224145Sdim}
2465224145Sdim
2466193326Sedvoid StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
2467193326Sed  BlockDecl *BD = Node->getBlockDecl();
2468193326Sed  OS << "^";
2469198092Srdivacky
2470193326Sed  const FunctionType *AFT = Node->getFunctionType();
2471198092Srdivacky
2472193326Sed  if (isa<FunctionNoProtoType>(AFT)) {
2473193326Sed    OS << "()";
2474193326Sed  } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
2475193326Sed    OS << '(';
2476193326Sed    for (BlockDecl::param_iterator AI = BD->param_begin(),
2477193326Sed         E = BD->param_end(); AI != E; ++AI) {
2478193326Sed      if (AI != BD->param_begin()) OS << ", ";
2479249423Sdim      std::string ParamStr = (*AI)->getNameAsString();
2480249423Sdim      (*AI)->getType().print(OS, Policy, ParamStr);
2481193326Sed    }
2482198092Srdivacky
2483341825Sdim    const auto *FT = cast<FunctionProtoType>(AFT);
2484193326Sed    if (FT->isVariadic()) {
2485193326Sed      if (!BD->param_empty()) OS << ", ";
2486193326Sed      OS << "...";
2487193326Sed    }
2488193326Sed    OS << ')';
2489193326Sed  }
2490249423Sdim  OS << "{ }";
2491193326Sed}
2492193326Sed
2493341825Sdimvoid StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {
2494234353Sdim  PrintExpr(Node->getSourceExpr());
2495193326Sed}
2496218893Sdim
2497280031Sdimvoid StmtPrinter::VisitTypoExpr(TypoExpr *Node) {
2498280031Sdim  // TODO: Print something reasonable for a TypoExpr, if necessary.
2499309124Sdim  llvm_unreachable("Cannot print TypoExpr nodes");
2500280031Sdim}
2501280031Sdim
2502223017Sdimvoid StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) {
2503223017Sdim  OS << "__builtin_astype(";
2504223017Sdim  PrintExpr(Node->getSrcExpr());
2505249423Sdim  OS << ", ";
2506249423Sdim  Node->getType().print(OS, Policy);
2507223017Sdim  OS << ")";
2508223017Sdim}
2509223017Sdim
2510193326Sed//===----------------------------------------------------------------------===//
2511193326Sed// Stmt method implementations
2512193326Sed//===----------------------------------------------------------------------===//
2513193326Sed
2514261991Sdimvoid Stmt::dumpPretty(const ASTContext &Context) const {
2515276479Sdim  printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts()));
2516193326Sed}
2517193326Sed
2518353358Sdimvoid Stmt::printPretty(raw_ostream &Out, PrinterHelper *Helper,
2519327952Sdim                       const PrintingPolicy &Policy, unsigned Indentation,
2520353358Sdim                       StringRef NL, const ASTContext *Context) const {
2521353358Sdim  StmtPrinter P(Out, Helper, Policy, Indentation, NL, Context);
2522353358Sdim  P.Visit(const_cast<Stmt *>(this));
2523193326Sed}
2524193326Sed
2525353358Sdimvoid Stmt::printJson(raw_ostream &Out, PrinterHelper *Helper,
2526353358Sdim                     const PrintingPolicy &Policy, bool AddQuotes) const {
2527353358Sdim  std::string Buf;
2528353358Sdim  llvm::raw_string_ostream TempOut(Buf);
2529353358Sdim
2530353358Sdim  printPretty(TempOut, Helper, Policy);
2531353358Sdim
2532353358Sdim  Out << JsonFormat(TempOut.str(), AddQuotes);
2533353358Sdim}
2534353358Sdim
2535193326Sed//===----------------------------------------------------------------------===//
2536193326Sed// PrinterHelper
2537193326Sed//===----------------------------------------------------------------------===//
2538193326Sed
2539193326Sed// Implement virtual destructor.
2540341825SdimPrinterHelper::~PrinterHelper() = default;
2541