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