1 //===- StmtPrinter.cpp - Printing implementation for Stmt ASTs ------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the Stmt::dumpPretty/Stmt::printPretty methods, which
11 // pretty print the AST back out to C code.
13 //===----------------------------------------------------------------------===//
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/Attr.h"
17 #include "clang/AST/Decl.h"
18 #include "clang/AST/DeclBase.h"
19 #include "clang/AST/DeclCXX.h"
20 #include "clang/AST/DeclObjC.h"
21 #include "clang/AST/DeclOpenMP.h"
22 #include "clang/AST/DeclTemplate.h"
23 #include "clang/AST/Expr.h"
24 #include "clang/AST/ExprCXX.h"
25 #include "clang/AST/ExprObjC.h"
26 #include "clang/AST/ExprOpenMP.h"
27 #include "clang/AST/NestedNameSpecifier.h"
28 #include "clang/AST/OpenMPClause.h"
29 #include "clang/AST/PrettyPrinter.h"
30 #include "clang/AST/Stmt.h"
31 #include "clang/AST/StmtCXX.h"
32 #include "clang/AST/StmtObjC.h"
33 #include "clang/AST/StmtOpenMP.h"
34 #include "clang/AST/StmtVisitor.h"
35 #include "clang/AST/TemplateBase.h"
36 #include "clang/AST/Type.h"
37 #include "clang/Basic/CharInfo.h"
38 #include "clang/Basic/ExpressionTraits.h"
39 #include "clang/Basic/IdentifierTable.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/StringRef.h"
51 #include "llvm/Support/Casting.h"
52 #include "llvm/Support/Compiler.h"
53 #include "llvm/Support/ErrorHandling.h"
54 #include "llvm/Support/Format.h"
55 #include "llvm/Support/raw_ostream.h"
59 using namespace clang;
61 //===----------------------------------------------------------------------===//
62 // StmtPrinter Visitor
63 //===----------------------------------------------------------------------===//
67 class StmtPrinter : public StmtVisitor<StmtPrinter> {
70 PrinterHelper* Helper;
71 PrintingPolicy Policy;
73 const ASTContext *Context;
76 StmtPrinter(raw_ostream &os, PrinterHelper *helper,
77 const PrintingPolicy &Policy, unsigned Indentation = 0,
79 const ASTContext *Context = nullptr)
80 : OS(os), IndentLevel(Indentation), Helper(helper), Policy(Policy),
81 NL(NL), Context(Context) {}
83 void PrintStmt(Stmt *S) {
84 PrintStmt(S, Policy.Indentation);
87 void PrintStmt(Stmt *S, int SubIndent) {
88 IndentLevel += SubIndent;
89 if (S && isa<Expr>(S)) {
90 // If this is an expr used in a stmt context, indent and newline it.
97 Indent() << "<<<NULL STATEMENT>>>" << NL;
99 IndentLevel -= SubIndent;
102 void PrintInitStmt(Stmt *S, unsigned PrefixWidth) {
103 // FIXME: Cope better with odd prefix widths.
104 IndentLevel += (PrefixWidth + 1) / 2;
105 if (auto *DS = dyn_cast<DeclStmt>(S))
106 PrintRawDeclStmt(DS);
108 PrintExpr(cast<Expr>(S));
110 IndentLevel -= (PrefixWidth + 1) / 2;
113 void PrintControlledStmt(Stmt *S) {
114 if (auto *CS = dyn_cast<CompoundStmt>(S)) {
116 PrintRawCompoundStmt(CS);
124 void PrintRawCompoundStmt(CompoundStmt *S);
125 void PrintRawDecl(Decl *D);
126 void PrintRawDeclStmt(const DeclStmt *S);
127 void PrintRawIfStmt(IfStmt *If);
128 void PrintRawCXXCatchStmt(CXXCatchStmt *Catch);
129 void PrintCallArgs(CallExpr *E);
130 void PrintRawSEHExceptHandler(SEHExceptStmt *S);
131 void PrintRawSEHFinallyStmt(SEHFinallyStmt *S);
132 void PrintOMPExecutableDirective(OMPExecutableDirective *S,
133 bool ForceNoStmt = false);
135 void PrintExpr(Expr *E) {
142 raw_ostream &Indent(int Delta = 0) {
143 for (int i = 0, e = IndentLevel+Delta; i < e; ++i)
148 void Visit(Stmt* S) {
149 if (Helper && Helper->handledStmt(S,OS))
151 else StmtVisitor<StmtPrinter>::Visit(S);
154 void VisitStmt(Stmt *Node) LLVM_ATTRIBUTE_UNUSED {
155 Indent() << "<<unknown stmt type>>" << NL;
158 void VisitExpr(Expr *Node) LLVM_ATTRIBUTE_UNUSED {
159 OS << "<<unknown expr type>>";
162 void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node);
164 #define ABSTRACT_STMT(CLASS)
165 #define STMT(CLASS, PARENT) \
166 void Visit##CLASS(CLASS *Node);
167 #include "clang/AST/StmtNodes.inc"
172 //===----------------------------------------------------------------------===//
173 // Stmt printing methods.
174 //===----------------------------------------------------------------------===//
176 /// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and
177 /// with no newline after the }.
178 void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
180 for (auto *I : Node->body())
186 void StmtPrinter::PrintRawDecl(Decl *D) {
187 D->print(OS, Policy, IndentLevel);
190 void StmtPrinter::PrintRawDeclStmt(const DeclStmt *S) {
191 SmallVector<Decl *, 2> Decls(S->decls());
192 Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel);
195 void StmtPrinter::VisitNullStmt(NullStmt *Node) {
196 Indent() << ";" << NL;
199 void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
201 PrintRawDeclStmt(Node);
205 void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
207 PrintRawCompoundStmt(Node);
211 void StmtPrinter::VisitCaseStmt(CaseStmt *Node) {
212 Indent(-1) << "case ";
213 PrintExpr(Node->getLHS());
214 if (Node->getRHS()) {
216 PrintExpr(Node->getRHS());
220 PrintStmt(Node->getSubStmt(), 0);
223 void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) {
224 Indent(-1) << "default:" << NL;
225 PrintStmt(Node->getSubStmt(), 0);
228 void StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
229 Indent(-1) << Node->getName() << ":" << NL;
230 PrintStmt(Node->getSubStmt(), 0);
233 void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) {
234 for (const auto *Attr : Node->getAttrs()) {
235 Attr->printPretty(OS, Policy);
238 PrintStmt(Node->getSubStmt(), 0);
241 void StmtPrinter::PrintRawIfStmt(IfStmt *If) {
244 PrintInitStmt(If->getInit(), 4);
245 if (const DeclStmt *DS = If->getConditionVariableDeclStmt())
246 PrintRawDeclStmt(DS);
248 PrintExpr(If->getCond());
251 if (auto *CS = dyn_cast<CompoundStmt>(If->getThen())) {
253 PrintRawCompoundStmt(CS);
254 OS << (If->getElse() ? " " : NL);
257 PrintStmt(If->getThen());
258 if (If->getElse()) Indent();
261 if (Stmt *Else = If->getElse()) {
264 if (auto *CS = dyn_cast<CompoundStmt>(Else)) {
266 PrintRawCompoundStmt(CS);
268 } else if (auto *ElseIf = dyn_cast<IfStmt>(Else)) {
270 PrintRawIfStmt(ElseIf);
273 PrintStmt(If->getElse());
278 void StmtPrinter::VisitIfStmt(IfStmt *If) {
283 void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) {
284 Indent() << "switch (";
286 PrintInitStmt(Node->getInit(), 8);
287 if (const DeclStmt *DS = Node->getConditionVariableDeclStmt())
288 PrintRawDeclStmt(DS);
290 PrintExpr(Node->getCond());
292 PrintControlledStmt(Node->getBody());
295 void StmtPrinter::VisitWhileStmt(WhileStmt *Node) {
296 Indent() << "while (";
297 if (const DeclStmt *DS = Node->getConditionVariableDeclStmt())
298 PrintRawDeclStmt(DS);
300 PrintExpr(Node->getCond());
302 PrintStmt(Node->getBody());
305 void StmtPrinter::VisitDoStmt(DoStmt *Node) {
307 if (auto *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
308 PrintRawCompoundStmt(CS);
312 PrintStmt(Node->getBody());
317 PrintExpr(Node->getCond());
321 void StmtPrinter::VisitForStmt(ForStmt *Node) {
324 PrintInitStmt(Node->getInit(), 5);
326 OS << (Node->getCond() ? "; " : ";");
328 PrintExpr(Node->getCond());
330 if (Node->getInc()) {
332 PrintExpr(Node->getInc());
335 PrintControlledStmt(Node->getBody());
338 void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) {
340 if (auto *DS = dyn_cast<DeclStmt>(Node->getElement()))
341 PrintRawDeclStmt(DS);
343 PrintExpr(cast<Expr>(Node->getElement()));
345 PrintExpr(Node->getCollection());
347 PrintControlledStmt(Node->getBody());
350 void StmtPrinter::VisitCXXForRangeStmt(CXXForRangeStmt *Node) {
353 PrintInitStmt(Node->getInit(), 5);
354 PrintingPolicy SubPolicy(Policy);
355 SubPolicy.SuppressInitializers = true;
356 Node->getLoopVariable()->print(OS, SubPolicy, IndentLevel);
358 PrintExpr(Node->getRangeInit());
360 PrintControlledStmt(Node->getBody());
363 void StmtPrinter::VisitMSDependentExistsStmt(MSDependentExistsStmt *Node) {
365 if (Node->isIfExists())
366 OS << "__if_exists (";
368 OS << "__if_not_exists (";
370 if (NestedNameSpecifier *Qualifier
371 = Node->getQualifierLoc().getNestedNameSpecifier())
372 Qualifier->print(OS, Policy);
374 OS << Node->getNameInfo() << ") ";
376 PrintRawCompoundStmt(Node->getSubStmt());
379 void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
380 Indent() << "goto " << Node->getLabel()->getName() << ";";
381 if (Policy.IncludeNewlines) OS << NL;
384 void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
385 Indent() << "goto *";
386 PrintExpr(Node->getTarget());
388 if (Policy.IncludeNewlines) OS << NL;
391 void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
392 Indent() << "continue;";
393 if (Policy.IncludeNewlines) OS << NL;
396 void StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
397 Indent() << "break;";
398 if (Policy.IncludeNewlines) OS << NL;
401 void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
402 Indent() << "return";
403 if (Node->getRetValue()) {
405 PrintExpr(Node->getRetValue());
408 if (Policy.IncludeNewlines) OS << NL;
411 void StmtPrinter::VisitGCCAsmStmt(GCCAsmStmt *Node) {
414 if (Node->isVolatile())
418 VisitStringLiteral(Node->getAsmString());
421 if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 ||
422 Node->getNumClobbers() != 0)
425 for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) {
429 if (!Node->getOutputName(i).empty()) {
431 OS << Node->getOutputName(i);
435 VisitStringLiteral(Node->getOutputConstraintLiteral(i));
437 Visit(Node->getOutputExpr(i));
442 if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0)
445 for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) {
449 if (!Node->getInputName(i).empty()) {
451 OS << Node->getInputName(i);
455 VisitStringLiteral(Node->getInputConstraintLiteral(i));
457 Visit(Node->getInputExpr(i));
462 if (Node->getNumClobbers() != 0)
465 for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) {
469 VisitStringLiteral(Node->getClobberStringLiteral(i));
473 if (Policy.IncludeNewlines) OS << NL;
476 void StmtPrinter::VisitMSAsmStmt(MSAsmStmt *Node) {
477 // FIXME: Implement MS style inline asm statement printer.
478 Indent() << "__asm ";
479 if (Node->hasBraces())
481 OS << Node->getAsmString() << NL;
482 if (Node->hasBraces())
483 Indent() << "}" << NL;
486 void StmtPrinter::VisitCapturedStmt(CapturedStmt *Node) {
487 PrintStmt(Node->getCapturedDecl()->getBody());
490 void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) {
492 if (auto *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) {
493 PrintRawCompoundStmt(TS);
497 for (unsigned I = 0, N = Node->getNumCatchStmts(); I != N; ++I) {
498 ObjCAtCatchStmt *catchStmt = Node->getCatchStmt(I);
499 Indent() << "@catch(";
500 if (catchStmt->getCatchParamDecl()) {
501 if (Decl *DS = catchStmt->getCatchParamDecl())
505 if (auto *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) {
506 PrintRawCompoundStmt(CS);
511 if (auto *FS = static_cast<ObjCAtFinallyStmt *>(Node->getFinallyStmt())) {
512 Indent() << "@finally";
513 PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody()));
518 void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) {
521 void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) {
522 Indent() << "@catch (...) { /* todo */ } " << NL;
525 void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) {
526 Indent() << "@throw";
527 if (Node->getThrowExpr()) {
529 PrintExpr(Node->getThrowExpr());
534 void StmtPrinter::VisitObjCAvailabilityCheckExpr(
535 ObjCAvailabilityCheckExpr *Node) {
536 OS << "@available(...)";
539 void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) {
540 Indent() << "@synchronized (";
541 PrintExpr(Node->getSynchExpr());
543 PrintRawCompoundStmt(Node->getSynchBody());
547 void StmtPrinter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *Node) {
548 Indent() << "@autoreleasepool";
549 PrintRawCompoundStmt(dyn_cast<CompoundStmt>(Node->getSubStmt()));
553 void StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) {
555 if (Decl *ExDecl = Node->getExceptionDecl())
556 PrintRawDecl(ExDecl);
560 PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock()));
563 void StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) {
565 PrintRawCXXCatchStmt(Node);
569 void StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) {
571 PrintRawCompoundStmt(Node->getTryBlock());
572 for (unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) {
574 PrintRawCXXCatchStmt(Node->getHandler(i));
579 void StmtPrinter::VisitSEHTryStmt(SEHTryStmt *Node) {
580 Indent() << (Node->getIsCXXTry() ? "try " : "__try ");
581 PrintRawCompoundStmt(Node->getTryBlock());
582 SEHExceptStmt *E = Node->getExceptHandler();
583 SEHFinallyStmt *F = Node->getFinallyHandler();
585 PrintRawSEHExceptHandler(E);
587 assert(F && "Must have a finally block...");
588 PrintRawSEHFinallyStmt(F);
593 void StmtPrinter::PrintRawSEHFinallyStmt(SEHFinallyStmt *Node) {
595 PrintRawCompoundStmt(Node->getBlock());
599 void StmtPrinter::PrintRawSEHExceptHandler(SEHExceptStmt *Node) {
601 VisitExpr(Node->getFilterExpr());
603 PrintRawCompoundStmt(Node->getBlock());
607 void StmtPrinter::VisitSEHExceptStmt(SEHExceptStmt *Node) {
609 PrintRawSEHExceptHandler(Node);
613 void StmtPrinter::VisitSEHFinallyStmt(SEHFinallyStmt *Node) {
615 PrintRawSEHFinallyStmt(Node);
619 void StmtPrinter::VisitSEHLeaveStmt(SEHLeaveStmt *Node) {
620 Indent() << "__leave;";
621 if (Policy.IncludeNewlines) OS << NL;
624 //===----------------------------------------------------------------------===//
625 // OpenMP directives printing methods
626 //===----------------------------------------------------------------------===//
628 void StmtPrinter::PrintOMPExecutableDirective(OMPExecutableDirective *S,
630 OMPClausePrinter Printer(OS, Policy);
631 ArrayRef<OMPClause *> Clauses = S->clauses();
632 for (auto *Clause : Clauses)
633 if (Clause && !Clause->isImplicit()) {
635 Printer.Visit(Clause);
638 if (!ForceNoStmt && S->hasAssociatedStmt())
639 PrintStmt(S->getInnermostCapturedStmt()->getCapturedStmt());
642 void StmtPrinter::VisitOMPParallelDirective(OMPParallelDirective *Node) {
643 Indent() << "#pragma omp parallel";
644 PrintOMPExecutableDirective(Node);
647 void StmtPrinter::VisitOMPSimdDirective(OMPSimdDirective *Node) {
648 Indent() << "#pragma omp simd";
649 PrintOMPExecutableDirective(Node);
652 void StmtPrinter::VisitOMPForDirective(OMPForDirective *Node) {
653 Indent() << "#pragma omp for";
654 PrintOMPExecutableDirective(Node);
657 void StmtPrinter::VisitOMPForSimdDirective(OMPForSimdDirective *Node) {
658 Indent() << "#pragma omp for simd";
659 PrintOMPExecutableDirective(Node);
662 void StmtPrinter::VisitOMPSectionsDirective(OMPSectionsDirective *Node) {
663 Indent() << "#pragma omp sections";
664 PrintOMPExecutableDirective(Node);
667 void StmtPrinter::VisitOMPSectionDirective(OMPSectionDirective *Node) {
668 Indent() << "#pragma omp section";
669 PrintOMPExecutableDirective(Node);
672 void StmtPrinter::VisitOMPSingleDirective(OMPSingleDirective *Node) {
673 Indent() << "#pragma omp single";
674 PrintOMPExecutableDirective(Node);
677 void StmtPrinter::VisitOMPMasterDirective(OMPMasterDirective *Node) {
678 Indent() << "#pragma omp master";
679 PrintOMPExecutableDirective(Node);
682 void StmtPrinter::VisitOMPCriticalDirective(OMPCriticalDirective *Node) {
683 Indent() << "#pragma omp critical";
684 if (Node->getDirectiveName().getName()) {
686 Node->getDirectiveName().printName(OS);
689 PrintOMPExecutableDirective(Node);
692 void StmtPrinter::VisitOMPParallelForDirective(OMPParallelForDirective *Node) {
693 Indent() << "#pragma omp parallel for";
694 PrintOMPExecutableDirective(Node);
697 void StmtPrinter::VisitOMPParallelForSimdDirective(
698 OMPParallelForSimdDirective *Node) {
699 Indent() << "#pragma omp parallel for simd";
700 PrintOMPExecutableDirective(Node);
703 void StmtPrinter::VisitOMPParallelSectionsDirective(
704 OMPParallelSectionsDirective *Node) {
705 Indent() << "#pragma omp parallel sections";
706 PrintOMPExecutableDirective(Node);
709 void StmtPrinter::VisitOMPTaskDirective(OMPTaskDirective *Node) {
710 Indent() << "#pragma omp task";
711 PrintOMPExecutableDirective(Node);
714 void StmtPrinter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *Node) {
715 Indent() << "#pragma omp taskyield";
716 PrintOMPExecutableDirective(Node);
719 void StmtPrinter::VisitOMPBarrierDirective(OMPBarrierDirective *Node) {
720 Indent() << "#pragma omp barrier";
721 PrintOMPExecutableDirective(Node);
724 void StmtPrinter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *Node) {
725 Indent() << "#pragma omp taskwait";
726 PrintOMPExecutableDirective(Node);
729 void StmtPrinter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *Node) {
730 Indent() << "#pragma omp taskgroup";
731 PrintOMPExecutableDirective(Node);
734 void StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) {
735 Indent() << "#pragma omp flush";
736 PrintOMPExecutableDirective(Node);
739 void StmtPrinter::VisitOMPOrderedDirective(OMPOrderedDirective *Node) {
740 Indent() << "#pragma omp ordered";
741 PrintOMPExecutableDirective(Node, Node->hasClausesOfKind<OMPDependClause>());
744 void StmtPrinter::VisitOMPAtomicDirective(OMPAtomicDirective *Node) {
745 Indent() << "#pragma omp atomic";
746 PrintOMPExecutableDirective(Node);
749 void StmtPrinter::VisitOMPTargetDirective(OMPTargetDirective *Node) {
750 Indent() << "#pragma omp target";
751 PrintOMPExecutableDirective(Node);
754 void StmtPrinter::VisitOMPTargetDataDirective(OMPTargetDataDirective *Node) {
755 Indent() << "#pragma omp target data";
756 PrintOMPExecutableDirective(Node);
759 void StmtPrinter::VisitOMPTargetEnterDataDirective(
760 OMPTargetEnterDataDirective *Node) {
761 Indent() << "#pragma omp target enter data";
762 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
765 void StmtPrinter::VisitOMPTargetExitDataDirective(
766 OMPTargetExitDataDirective *Node) {
767 Indent() << "#pragma omp target exit data";
768 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
771 void StmtPrinter::VisitOMPTargetParallelDirective(
772 OMPTargetParallelDirective *Node) {
773 Indent() << "#pragma omp target parallel";
774 PrintOMPExecutableDirective(Node);
777 void StmtPrinter::VisitOMPTargetParallelForDirective(
778 OMPTargetParallelForDirective *Node) {
779 Indent() << "#pragma omp target parallel for";
780 PrintOMPExecutableDirective(Node);
783 void StmtPrinter::VisitOMPTeamsDirective(OMPTeamsDirective *Node) {
784 Indent() << "#pragma omp teams";
785 PrintOMPExecutableDirective(Node);
788 void StmtPrinter::VisitOMPCancellationPointDirective(
789 OMPCancellationPointDirective *Node) {
790 Indent() << "#pragma omp cancellation point "
791 << getOpenMPDirectiveName(Node->getCancelRegion());
792 PrintOMPExecutableDirective(Node);
795 void StmtPrinter::VisitOMPCancelDirective(OMPCancelDirective *Node) {
796 Indent() << "#pragma omp cancel "
797 << getOpenMPDirectiveName(Node->getCancelRegion());
798 PrintOMPExecutableDirective(Node);
801 void StmtPrinter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *Node) {
802 Indent() << "#pragma omp taskloop";
803 PrintOMPExecutableDirective(Node);
806 void StmtPrinter::VisitOMPTaskLoopSimdDirective(
807 OMPTaskLoopSimdDirective *Node) {
808 Indent() << "#pragma omp taskloop simd";
809 PrintOMPExecutableDirective(Node);
812 void StmtPrinter::VisitOMPDistributeDirective(OMPDistributeDirective *Node) {
813 Indent() << "#pragma omp distribute";
814 PrintOMPExecutableDirective(Node);
817 void StmtPrinter::VisitOMPTargetUpdateDirective(
818 OMPTargetUpdateDirective *Node) {
819 Indent() << "#pragma omp target update";
820 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
823 void StmtPrinter::VisitOMPDistributeParallelForDirective(
824 OMPDistributeParallelForDirective *Node) {
825 Indent() << "#pragma omp distribute parallel for";
826 PrintOMPExecutableDirective(Node);
829 void StmtPrinter::VisitOMPDistributeParallelForSimdDirective(
830 OMPDistributeParallelForSimdDirective *Node) {
831 Indent() << "#pragma omp distribute parallel for simd";
832 PrintOMPExecutableDirective(Node);
835 void StmtPrinter::VisitOMPDistributeSimdDirective(
836 OMPDistributeSimdDirective *Node) {
837 Indent() << "#pragma omp distribute simd";
838 PrintOMPExecutableDirective(Node);
841 void StmtPrinter::VisitOMPTargetParallelForSimdDirective(
842 OMPTargetParallelForSimdDirective *Node) {
843 Indent() << "#pragma omp target parallel for simd";
844 PrintOMPExecutableDirective(Node);
847 void StmtPrinter::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *Node) {
848 Indent() << "#pragma omp target simd";
849 PrintOMPExecutableDirective(Node);
852 void StmtPrinter::VisitOMPTeamsDistributeDirective(
853 OMPTeamsDistributeDirective *Node) {
854 Indent() << "#pragma omp teams distribute";
855 PrintOMPExecutableDirective(Node);
858 void StmtPrinter::VisitOMPTeamsDistributeSimdDirective(
859 OMPTeamsDistributeSimdDirective *Node) {
860 Indent() << "#pragma omp teams distribute simd";
861 PrintOMPExecutableDirective(Node);
864 void StmtPrinter::VisitOMPTeamsDistributeParallelForSimdDirective(
865 OMPTeamsDistributeParallelForSimdDirective *Node) {
866 Indent() << "#pragma omp teams distribute parallel for simd";
867 PrintOMPExecutableDirective(Node);
870 void StmtPrinter::VisitOMPTeamsDistributeParallelForDirective(
871 OMPTeamsDistributeParallelForDirective *Node) {
872 Indent() << "#pragma omp teams distribute parallel for";
873 PrintOMPExecutableDirective(Node);
876 void StmtPrinter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *Node) {
877 Indent() << "#pragma omp target teams";
878 PrintOMPExecutableDirective(Node);
881 void StmtPrinter::VisitOMPTargetTeamsDistributeDirective(
882 OMPTargetTeamsDistributeDirective *Node) {
883 Indent() << "#pragma omp target teams distribute";
884 PrintOMPExecutableDirective(Node);
887 void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForDirective(
888 OMPTargetTeamsDistributeParallelForDirective *Node) {
889 Indent() << "#pragma omp target teams distribute parallel for";
890 PrintOMPExecutableDirective(Node);
893 void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
894 OMPTargetTeamsDistributeParallelForSimdDirective *Node) {
895 Indent() << "#pragma omp target teams distribute parallel for simd";
896 PrintOMPExecutableDirective(Node);
899 void StmtPrinter::VisitOMPTargetTeamsDistributeSimdDirective(
900 OMPTargetTeamsDistributeSimdDirective *Node) {
901 Indent() << "#pragma omp target teams distribute simd";
902 PrintOMPExecutableDirective(Node);
905 //===----------------------------------------------------------------------===//
906 // Expr printing methods.
907 //===----------------------------------------------------------------------===//
909 void StmtPrinter::VisitConstantExpr(ConstantExpr *Node) {
910 PrintExpr(Node->getSubExpr());
913 void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
914 if (const auto *OCED = dyn_cast<OMPCapturedExprDecl>(Node->getDecl())) {
915 OCED->getInit()->IgnoreImpCasts()->printPretty(OS, nullptr, Policy);
918 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
919 Qualifier->print(OS, Policy);
920 if (Node->hasTemplateKeyword())
922 OS << Node->getNameInfo();
923 if (Node->hasExplicitTemplateArgs())
924 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
927 void StmtPrinter::VisitDependentScopeDeclRefExpr(
928 DependentScopeDeclRefExpr *Node) {
929 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
930 Qualifier->print(OS, Policy);
931 if (Node->hasTemplateKeyword())
933 OS << Node->getNameInfo();
934 if (Node->hasExplicitTemplateArgs())
935 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
938 void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
939 if (Node->getQualifier())
940 Node->getQualifier()->print(OS, Policy);
941 if (Node->hasTemplateKeyword())
943 OS << Node->getNameInfo();
944 if (Node->hasExplicitTemplateArgs())
945 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
948 static bool isImplicitSelf(const Expr *E) {
949 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
950 if (const auto *PD = dyn_cast<ImplicitParamDecl>(DRE->getDecl())) {
951 if (PD->getParameterKind() == ImplicitParamDecl::ObjCSelf &&
952 DRE->getBeginLoc().isInvalid())
959 void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
960 if (Node->getBase()) {
961 if (!Policy.SuppressImplicitBase ||
962 !isImplicitSelf(Node->getBase()->IgnoreImpCasts())) {
963 PrintExpr(Node->getBase());
964 OS << (Node->isArrow() ? "->" : ".");
967 OS << *Node->getDecl();
970 void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
971 if (Node->isSuperReceiver())
973 else if (Node->isObjectReceiver() && Node->getBase()) {
974 PrintExpr(Node->getBase());
976 } else if (Node->isClassReceiver() && Node->getClassReceiver()) {
977 OS << Node->getClassReceiver()->getName() << ".";
980 if (Node->isImplicitProperty()) {
981 if (const auto *Getter = Node->getImplicitPropertyGetter())
982 Getter->getSelector().print(OS);
984 OS << SelectorTable::getPropertyNameFromSetterSelector(
985 Node->getImplicitPropertySetter()->getSelector());
987 OS << Node->getExplicitProperty()->getName();
990 void StmtPrinter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node) {
991 PrintExpr(Node->getBaseExpr());
993 PrintExpr(Node->getKeyExpr());
997 void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
998 OS << PredefinedExpr::getIdentKindName(Node->getIdentKind());
1001 void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
1002 unsigned value = Node->getValue();
1004 switch (Node->getKind()) {
1005 case CharacterLiteral::Ascii: break; // no prefix.
1006 case CharacterLiteral::Wide: OS << 'L'; break;
1007 case CharacterLiteral::UTF8: OS << "u8"; break;
1008 case CharacterLiteral::UTF16: OS << 'u'; break;
1009 case CharacterLiteral::UTF32: OS << 'U'; break;
1020 // TODO: K&R: the meaning of '\\a' is different in traditional C
1026 // Nonstandard escape sequence.
1046 // A character literal might be sign-extended, which
1047 // would result in an invalid \U escape sequence.
1048 // FIXME: multicharacter literals such as '\xFF\xFF\xFF\xFF'
1049 // are not correctly handled.
1050 if ((value & ~0xFFu) == ~0xFFu && Node->getKind() == CharacterLiteral::Ascii)
1052 if (value < 256 && isPrintable((unsigned char)value))
1053 OS << "'" << (char)value << "'";
1054 else if (value < 256)
1055 OS << "'\\x" << llvm::format("%02x", value) << "'";
1056 else if (value <= 0xFFFF)
1057 OS << "'\\u" << llvm::format("%04x", value) << "'";
1059 OS << "'\\U" << llvm::format("%08x", value) << "'";
1063 /// Prints the given expression using the original source text. Returns true on
1064 /// success, false otherwise.
1065 static bool printExprAsWritten(raw_ostream &OS, Expr *E,
1066 const ASTContext *Context) {
1069 bool Invalid = false;
1070 StringRef Source = Lexer::getSourceText(
1071 CharSourceRange::getTokenRange(E->getSourceRange()),
1072 Context->getSourceManager(), Context->getLangOpts(), &Invalid);
1080 void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
1081 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1083 bool isSigned = Node->getType()->isSignedIntegerType();
1084 OS << Node->getValue().toString(10, isSigned);
1086 // Emit suffixes. Integer literals are always a builtin integer type.
1087 switch (Node->getType()->getAs<BuiltinType>()->getKind()) {
1088 default: llvm_unreachable("Unexpected type for integer literal!");
1089 case BuiltinType::Char_S:
1090 case BuiltinType::Char_U: OS << "i8"; break;
1091 case BuiltinType::UChar: OS << "Ui8"; break;
1092 case BuiltinType::Short: OS << "i16"; break;
1093 case BuiltinType::UShort: OS << "Ui16"; break;
1094 case BuiltinType::Int: break; // no suffix.
1095 case BuiltinType::UInt: OS << 'U'; break;
1096 case BuiltinType::Long: OS << 'L'; break;
1097 case BuiltinType::ULong: OS << "UL"; break;
1098 case BuiltinType::LongLong: OS << "LL"; break;
1099 case BuiltinType::ULongLong: OS << "ULL"; break;
1103 void StmtPrinter::VisitFixedPointLiteral(FixedPointLiteral *Node) {
1104 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1106 OS << Node->getValueAsString(/*Radix=*/10);
1108 switch (Node->getType()->getAs<BuiltinType>()->getKind()) {
1109 default: llvm_unreachable("Unexpected type for fixed point literal!");
1110 case BuiltinType::ShortFract: OS << "hr"; break;
1111 case BuiltinType::ShortAccum: OS << "hk"; break;
1112 case BuiltinType::UShortFract: OS << "uhr"; break;
1113 case BuiltinType::UShortAccum: OS << "uhk"; break;
1114 case BuiltinType::Fract: OS << "r"; break;
1115 case BuiltinType::Accum: OS << "k"; break;
1116 case BuiltinType::UFract: OS << "ur"; break;
1117 case BuiltinType::UAccum: OS << "uk"; break;
1118 case BuiltinType::LongFract: OS << "lr"; break;
1119 case BuiltinType::LongAccum: OS << "lk"; break;
1120 case BuiltinType::ULongFract: OS << "ulr"; break;
1121 case BuiltinType::ULongAccum: OS << "ulk"; break;
1125 static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node,
1127 SmallString<16> Str;
1128 Node->getValue().toString(Str);
1130 if (Str.find_first_not_of("-0123456789") == StringRef::npos)
1131 OS << '.'; // Trailing dot in order to separate from ints.
1136 // Emit suffixes. Float literals are always a builtin float type.
1137 switch (Node->getType()->getAs<BuiltinType>()->getKind()) {
1138 default: llvm_unreachable("Unexpected type for float literal!");
1139 case BuiltinType::Half: break; // FIXME: suffix?
1140 case BuiltinType::Double: break; // no suffix.
1141 case BuiltinType::Float16: OS << "F16"; break;
1142 case BuiltinType::Float: OS << 'F'; break;
1143 case BuiltinType::LongDouble: OS << 'L'; break;
1144 case BuiltinType::Float128: OS << 'Q'; break;
1148 void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
1149 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1151 PrintFloatingLiteral(OS, Node, /*PrintSuffix=*/true);
1154 void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
1155 PrintExpr(Node->getSubExpr());
1159 void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
1160 Str->outputString(OS);
1163 void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
1165 PrintExpr(Node->getSubExpr());
1169 void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
1170 if (!Node->isPostfix()) {
1171 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
1173 // Print a space if this is an "identifier operator" like __real, or if
1174 // it might be concatenated incorrectly like '+'.
1175 switch (Node->getOpcode()) {
1184 if (isa<UnaryOperator>(Node->getSubExpr()))
1189 PrintExpr(Node->getSubExpr());
1191 if (Node->isPostfix())
1192 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
1195 void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {
1196 OS << "__builtin_offsetof(";
1197 Node->getTypeSourceInfo()->getType().print(OS, Policy);
1199 bool PrintedSomething = false;
1200 for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) {
1201 OffsetOfNode ON = Node->getComponent(i);
1202 if (ON.getKind() == OffsetOfNode::Array) {
1205 PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex()));
1207 PrintedSomething = true;
1211 // Skip implicit base indirections.
1212 if (ON.getKind() == OffsetOfNode::Base)
1215 // Field or identifier node.
1216 IdentifierInfo *Id = ON.getFieldName();
1220 if (PrintedSomething)
1223 PrintedSomething = true;
1224 OS << Id->getName();
1229 void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node){
1230 switch(Node->getKind()) {
1237 else if (Policy.UnderscoreAlignof)
1242 case UETT_PreferredAlignOf:
1248 case UETT_OpenMPRequiredSimdAlign:
1249 OS << "__builtin_omp_required_simd_align";
1252 if (Node->isArgumentType()) {
1254 Node->getArgumentType().print(OS, Policy);
1258 PrintExpr(Node->getArgumentExpr());
1262 void StmtPrinter::VisitGenericSelectionExpr(GenericSelectionExpr *Node) {
1264 PrintExpr(Node->getControllingExpr());
1265 for (unsigned i = 0; i != Node->getNumAssocs(); ++i) {
1267 QualType T = Node->getAssocType(i);
1271 T.print(OS, Policy);
1273 PrintExpr(Node->getAssocExpr(i));
1278 void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
1279 PrintExpr(Node->getLHS());
1281 PrintExpr(Node->getRHS());
1285 void StmtPrinter::VisitOMPArraySectionExpr(OMPArraySectionExpr *Node) {
1286 PrintExpr(Node->getBase());
1288 if (Node->getLowerBound())
1289 PrintExpr(Node->getLowerBound());
1290 if (Node->getColonLoc().isValid()) {
1292 if (Node->getLength())
1293 PrintExpr(Node->getLength());
1298 void StmtPrinter::PrintCallArgs(CallExpr *Call) {
1299 for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
1300 if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
1301 // Don't print any defaulted arguments
1306 PrintExpr(Call->getArg(i));
1310 void StmtPrinter::VisitCallExpr(CallExpr *Call) {
1311 PrintExpr(Call->getCallee());
1313 PrintCallArgs(Call);
1317 static bool isImplicitThis(const Expr *E) {
1318 if (const auto *TE = dyn_cast<CXXThisExpr>(E))
1319 return TE->isImplicit();
1323 void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
1324 if (!Policy.SuppressImplicitBase || !isImplicitThis(Node->getBase())) {
1325 PrintExpr(Node->getBase());
1327 auto *ParentMember = dyn_cast<MemberExpr>(Node->getBase());
1328 FieldDecl *ParentDecl =
1329 ParentMember ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl())
1332 if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion())
1333 OS << (Node->isArrow() ? "->" : ".");
1336 if (auto *FD = dyn_cast<FieldDecl>(Node->getMemberDecl()))
1337 if (FD->isAnonymousStructOrUnion())
1340 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1341 Qualifier->print(OS, Policy);
1342 if (Node->hasTemplateKeyword())
1344 OS << Node->getMemberNameInfo();
1345 if (Node->hasExplicitTemplateArgs())
1346 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
1349 void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
1350 PrintExpr(Node->getBase());
1351 OS << (Node->isArrow() ? "->isa" : ".isa");
1354 void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
1355 PrintExpr(Node->getBase());
1357 OS << Node->getAccessor().getName();
1360 void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
1362 Node->getTypeAsWritten().print(OS, Policy);
1364 PrintExpr(Node->getSubExpr());
1367 void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
1369 Node->getType().print(OS, Policy);
1371 PrintExpr(Node->getInitializer());
1374 void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
1375 // No need to print anything, simply forward to the subexpression.
1376 PrintExpr(Node->getSubExpr());
1379 void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
1380 PrintExpr(Node->getLHS());
1381 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
1382 PrintExpr(Node->getRHS());
1385 void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
1386 PrintExpr(Node->getLHS());
1387 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
1388 PrintExpr(Node->getRHS());
1391 void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
1392 PrintExpr(Node->getCond());
1394 PrintExpr(Node->getLHS());
1396 PrintExpr(Node->getRHS());
1402 StmtPrinter::VisitBinaryConditionalOperator(BinaryConditionalOperator *Node) {
1403 PrintExpr(Node->getCommon());
1405 PrintExpr(Node->getFalseExpr());
1408 void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
1409 OS << "&&" << Node->getLabel()->getName();
1412 void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
1414 PrintRawCompoundStmt(E->getSubStmt());
1418 void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
1419 OS << "__builtin_choose_expr(";
1420 PrintExpr(Node->getCond());
1422 PrintExpr(Node->getLHS());
1424 PrintExpr(Node->getRHS());
1428 void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
1432 void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
1433 OS << "__builtin_shufflevector(";
1434 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
1436 PrintExpr(Node->getExpr(i));
1441 void StmtPrinter::VisitConvertVectorExpr(ConvertVectorExpr *Node) {
1442 OS << "__builtin_convertvector(";
1443 PrintExpr(Node->getSrcExpr());
1445 Node->getType().print(OS, Policy);
1449 void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
1450 if (Node->getSyntacticForm()) {
1451 Visit(Node->getSyntacticForm());
1456 for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
1458 if (Node->getInit(i))
1459 PrintExpr(Node->getInit(i));
1466 void StmtPrinter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *Node) {
1467 // There's no way to express this expression in any of our supported
1468 // languages, so just emit something terse and (hopefully) clear.
1470 PrintExpr(Node->getSubExpr());
1474 void StmtPrinter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *Node) {
1478 void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
1480 for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {
1482 PrintExpr(Node->getExpr(i));
1487 void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
1488 bool NeedsEquals = true;
1489 for (const DesignatedInitExpr::Designator &D : Node->designators()) {
1490 if (D.isFieldDesignator()) {
1491 if (D.getDotLoc().isInvalid()) {
1492 if (IdentifierInfo *II = D.getFieldName()) {
1493 OS << II->getName() << ":";
1494 NeedsEquals = false;
1497 OS << "." << D.getFieldName()->getName();
1501 if (D.isArrayDesignator()) {
1502 PrintExpr(Node->getArrayIndex(D));
1504 PrintExpr(Node->getArrayRangeStart(D));
1506 PrintExpr(Node->getArrayRangeEnd(D));
1516 PrintExpr(Node->getInit());
1519 void StmtPrinter::VisitDesignatedInitUpdateExpr(
1520 DesignatedInitUpdateExpr *Node) {
1523 PrintExpr(Node->getBase());
1526 OS << "/*updater*/";
1527 PrintExpr(Node->getUpdater());
1531 void StmtPrinter::VisitNoInitExpr(NoInitExpr *Node) {
1532 OS << "/*no init*/";
1535 void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
1536 if (Node->getType()->getAsCXXRecordDecl()) {
1537 OS << "/*implicit*/";
1538 Node->getType().print(OS, Policy);
1541 OS << "/*implicit*/(";
1542 Node->getType().print(OS, Policy);
1544 if (Node->getType()->isRecordType())
1551 void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
1552 OS << "__builtin_va_arg(";
1553 PrintExpr(Node->getSubExpr());
1555 Node->getType().print(OS, Policy);
1559 void StmtPrinter::VisitPseudoObjectExpr(PseudoObjectExpr *Node) {
1560 PrintExpr(Node->getSyntacticForm());
1563 void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) {
1564 const char *Name = nullptr;
1565 switch (Node->getOp()) {
1566 #define BUILTIN(ID, TYPE, ATTRS)
1567 #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
1568 case AtomicExpr::AO ## ID: \
1571 #include "clang/Basic/Builtins.def"
1575 // AtomicExpr stores its subexpressions in a permuted order.
1576 PrintExpr(Node->getPtr());
1577 if (Node->getOp() != AtomicExpr::AO__c11_atomic_load &&
1578 Node->getOp() != AtomicExpr::AO__atomic_load_n &&
1579 Node->getOp() != AtomicExpr::AO__opencl_atomic_load) {
1581 PrintExpr(Node->getVal1());
1583 if (Node->getOp() == AtomicExpr::AO__atomic_exchange ||
1584 Node->isCmpXChg()) {
1586 PrintExpr(Node->getVal2());
1588 if (Node->getOp() == AtomicExpr::AO__atomic_compare_exchange ||
1589 Node->getOp() == AtomicExpr::AO__atomic_compare_exchange_n) {
1591 PrintExpr(Node->getWeak());
1593 if (Node->getOp() != AtomicExpr::AO__c11_atomic_init &&
1594 Node->getOp() != AtomicExpr::AO__opencl_atomic_init) {
1596 PrintExpr(Node->getOrder());
1598 if (Node->isCmpXChg()) {
1600 PrintExpr(Node->getOrderFail());
1606 void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
1607 const char *OpStrings[NUM_OVERLOADED_OPERATORS] = {
1609 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
1611 #include "clang/Basic/OperatorKinds.def"
1614 OverloadedOperatorKind Kind = Node->getOperator();
1615 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
1616 if (Node->getNumArgs() == 1) {
1617 OS << OpStrings[Kind] << ' ';
1618 PrintExpr(Node->getArg(0));
1620 PrintExpr(Node->getArg(0));
1621 OS << ' ' << OpStrings[Kind];
1623 } else if (Kind == OO_Arrow) {
1624 PrintExpr(Node->getArg(0));
1625 } else if (Kind == OO_Call) {
1626 PrintExpr(Node->getArg(0));
1628 for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) {
1631 if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx)))
1632 PrintExpr(Node->getArg(ArgIdx));
1635 } else if (Kind == OO_Subscript) {
1636 PrintExpr(Node->getArg(0));
1638 PrintExpr(Node->getArg(1));
1640 } else if (Node->getNumArgs() == 1) {
1641 OS << OpStrings[Kind] << ' ';
1642 PrintExpr(Node->getArg(0));
1643 } else if (Node->getNumArgs() == 2) {
1644 PrintExpr(Node->getArg(0));
1645 OS << ' ' << OpStrings[Kind] << ' ';
1646 PrintExpr(Node->getArg(1));
1648 llvm_unreachable("unknown overloaded operator");
1652 void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
1653 // If we have a conversion operator call only print the argument.
1654 CXXMethodDecl *MD = Node->getMethodDecl();
1655 if (MD && isa<CXXConversionDecl>(MD)) {
1656 PrintExpr(Node->getImplicitObjectArgument());
1659 VisitCallExpr(cast<CallExpr>(Node));
1662 void StmtPrinter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *Node) {
1663 PrintExpr(Node->getCallee());
1665 PrintCallArgs(Node->getConfig());
1667 PrintCallArgs(Node);
1671 void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
1672 OS << Node->getCastName() << '<';
1673 Node->getTypeAsWritten().print(OS, Policy);
1675 PrintExpr(Node->getSubExpr());
1679 void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {
1680 VisitCXXNamedCastExpr(Node);
1683 void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {
1684 VisitCXXNamedCastExpr(Node);
1687 void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {
1688 VisitCXXNamedCastExpr(Node);
1691 void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
1692 VisitCXXNamedCastExpr(Node);
1695 void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
1697 if (Node->isTypeOperand()) {
1698 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
1700 PrintExpr(Node->getExprOperand());
1705 void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) {
1707 if (Node->isTypeOperand()) {
1708 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
1710 PrintExpr(Node->getExprOperand());
1715 void StmtPrinter::VisitMSPropertyRefExpr(MSPropertyRefExpr *Node) {
1716 PrintExpr(Node->getBaseExpr());
1717 if (Node->isArrow())
1721 if (NestedNameSpecifier *Qualifier =
1722 Node->getQualifierLoc().getNestedNameSpecifier())
1723 Qualifier->print(OS, Policy);
1724 OS << Node->getPropertyDecl()->getDeclName();
1727 void StmtPrinter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *Node) {
1728 PrintExpr(Node->getBase());
1730 PrintExpr(Node->getIdx());
1734 void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) {
1735 switch (Node->getLiteralOperatorKind()) {
1736 case UserDefinedLiteral::LOK_Raw:
1737 OS << cast<StringLiteral>(Node->getArg(0)->IgnoreImpCasts())->getString();
1739 case UserDefinedLiteral::LOK_Template: {
1740 const auto *DRE = cast<DeclRefExpr>(Node->getCallee()->IgnoreImpCasts());
1741 const TemplateArgumentList *Args =
1742 cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs();
1745 if (Args->size() != 1) {
1746 OS << "operator\"\"" << Node->getUDSuffix()->getName();
1747 printTemplateArgumentList(OS, Args->asArray(), Policy);
1752 const TemplateArgument &Pack = Args->get(0);
1753 for (const auto &P : Pack.pack_elements()) {
1754 char C = (char)P.getAsIntegral().getZExtValue();
1759 case UserDefinedLiteral::LOK_Integer: {
1760 // Print integer literal without suffix.
1761 const auto *Int = cast<IntegerLiteral>(Node->getCookedLiteral());
1762 OS << Int->getValue().toString(10, /*isSigned*/false);
1765 case UserDefinedLiteral::LOK_Floating: {
1766 // Print floating literal without suffix.
1767 auto *Float = cast<FloatingLiteral>(Node->getCookedLiteral());
1768 PrintFloatingLiteral(OS, Float, /*PrintSuffix=*/false);
1771 case UserDefinedLiteral::LOK_String:
1772 case UserDefinedLiteral::LOK_Character:
1773 PrintExpr(Node->getCookedLiteral());
1776 OS << Node->getUDSuffix()->getName();
1779 void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
1780 OS << (Node->getValue() ? "true" : "false");
1783 void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
1787 void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
1791 void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
1792 if (!Node->getSubExpr())
1796 PrintExpr(Node->getSubExpr());
1800 void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
1801 // Nothing to print: we picked up the default argument.
1804 void StmtPrinter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Node) {
1805 // Nothing to print: we picked up the default initializer.
1808 void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
1809 Node->getType().print(OS, Policy);
1810 // If there are no parens, this is list-initialization, and the braces are
1811 // part of the syntax of the inner construct.
1812 if (Node->getLParenLoc().isValid())
1814 PrintExpr(Node->getSubExpr());
1815 if (Node->getLParenLoc().isValid())
1819 void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
1820 PrintExpr(Node->getSubExpr());
1823 void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
1824 Node->getType().print(OS, Policy);
1825 if (Node->isStdInitListInitialization())
1826 /* Nothing to do; braces are part of creating the std::initializer_list. */;
1827 else if (Node->isListInitialization())
1831 for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),
1832 ArgEnd = Node->arg_end();
1833 Arg != ArgEnd; ++Arg) {
1834 if ((*Arg)->isDefaultArgument())
1836 if (Arg != Node->arg_begin())
1840 if (Node->isStdInitListInitialization())
1842 else if (Node->isListInitialization())
1848 void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {
1850 bool NeedComma = false;
1851 switch (Node->getCaptureDefault()) {
1865 for (LambdaExpr::capture_iterator C = Node->explicit_capture_begin(),
1866 CEnd = Node->explicit_capture_end();
1869 if (C->capturesVLAType())
1876 switch (C->getCaptureKind()) {
1886 if (Node->getCaptureDefault() != LCD_ByRef || Node->isInitCapture(C))
1888 OS << C->getCapturedVar()->getName();
1892 OS << C->getCapturedVar()->getName();
1896 llvm_unreachable("VLA type in explicit captures.");
1899 if (Node->isInitCapture(C))
1900 PrintExpr(C->getCapturedVar()->getInit());
1904 if (Node->hasExplicitParameters()) {
1906 CXXMethodDecl *Method = Node->getCallOperator();
1908 for (const auto *P : Method->parameters()) {
1914 std::string ParamStr = P->getNameAsString();
1915 P->getOriginalType().print(OS, Policy, ParamStr);
1917 if (Method->isVariadic()) {
1924 if (Node->isMutable())
1927 auto *Proto = Method->getType()->getAs<FunctionProtoType>();
1928 Proto->printExceptionSpecification(OS, Policy);
1930 // FIXME: Attributes
1932 // Print the trailing return type if it was specified in the source.
1933 if (Node->hasExplicitResultType()) {
1935 Proto->getReturnType().print(OS, Policy);
1940 CompoundStmt *Body = Node->getBody();
1945 void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) {
1946 if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo())
1947 TSInfo->getType().print(OS, Policy);
1949 Node->getType().print(OS, Policy);
1953 void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
1954 if (E->isGlobalNew())
1957 unsigned NumPlace = E->getNumPlacementArgs();
1958 if (NumPlace > 0 && !isa<CXXDefaultArgExpr>(E->getPlacementArg(0))) {
1960 PrintExpr(E->getPlacementArg(0));
1961 for (unsigned i = 1; i < NumPlace; ++i) {
1962 if (isa<CXXDefaultArgExpr>(E->getPlacementArg(i)))
1965 PrintExpr(E->getPlacementArg(i));
1969 if (E->isParenTypeId())
1972 if (Expr *Size = E->getArraySize()) {
1973 llvm::raw_string_ostream s(TypeS);
1975 Size->printPretty(s, Helper, Policy);
1978 E->getAllocatedType().print(OS, Policy, TypeS);
1979 if (E->isParenTypeId())
1982 CXXNewExpr::InitializationStyle InitStyle = E->getInitializationStyle();
1984 if (InitStyle == CXXNewExpr::CallInit)
1986 PrintExpr(E->getInitializer());
1987 if (InitStyle == CXXNewExpr::CallInit)
1992 void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
1993 if (E->isGlobalDelete())
1996 if (E->isArrayForm())
1998 PrintExpr(E->getArgument());
2001 void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
2002 PrintExpr(E->getBase());
2007 if (E->getQualifier())
2008 E->getQualifier()->print(OS, Policy);
2011 if (IdentifierInfo *II = E->getDestroyedTypeIdentifier())
2012 OS << II->getName();
2014 E->getDestroyedType().print(OS, Policy);
2017 void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
2018 if (E->isListInitialization() && !E->isStdInitListInitialization())
2021 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
2022 if (isa<CXXDefaultArgExpr>(E->getArg(i))) {
2023 // Don't print any defaulted arguments
2028 PrintExpr(E->getArg(i));
2031 if (E->isListInitialization() && !E->isStdInitListInitialization())
2035 void StmtPrinter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {
2036 // Parens are printed by the surrounding context.
2037 OS << "<forwarded>";
2040 void StmtPrinter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
2041 PrintExpr(E->getSubExpr());
2044 void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) {
2045 // Just forward to the subexpression.
2046 PrintExpr(E->getSubExpr());
2050 StmtPrinter::VisitCXXUnresolvedConstructExpr(
2051 CXXUnresolvedConstructExpr *Node) {
2052 Node->getTypeAsWritten().print(OS, Policy);
2054 for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(),
2055 ArgEnd = Node->arg_end();
2056 Arg != ArgEnd; ++Arg) {
2057 if (Arg != Node->arg_begin())
2064 void StmtPrinter::VisitCXXDependentScopeMemberExpr(
2065 CXXDependentScopeMemberExpr *Node) {
2066 if (!Node->isImplicitAccess()) {
2067 PrintExpr(Node->getBase());
2068 OS << (Node->isArrow() ? "->" : ".");
2070 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
2071 Qualifier->print(OS, Policy);
2072 if (Node->hasTemplateKeyword())
2074 OS << Node->getMemberNameInfo();
2075 if (Node->hasExplicitTemplateArgs())
2076 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2079 void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
2080 if (!Node->isImplicitAccess()) {
2081 PrintExpr(Node->getBase());
2082 OS << (Node->isArrow() ? "->" : ".");
2084 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
2085 Qualifier->print(OS, Policy);
2086 if (Node->hasTemplateKeyword())
2088 OS << Node->getMemberNameInfo();
2089 if (Node->hasExplicitTemplateArgs())
2090 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2093 static const char *getTypeTraitName(TypeTrait TT) {
2095 #define TYPE_TRAIT_1(Spelling, Name, Key) \
2096 case clang::UTT_##Name: return #Spelling;
2097 #define TYPE_TRAIT_2(Spelling, Name, Key) \
2098 case clang::BTT_##Name: return #Spelling;
2099 #define TYPE_TRAIT_N(Spelling, Name, Key) \
2100 case clang::TT_##Name: return #Spelling;
2101 #include "clang/Basic/TokenKinds.def"
2103 llvm_unreachable("Type trait not covered by switch");
2106 static const char *getTypeTraitName(ArrayTypeTrait ATT) {
2108 case ATT_ArrayRank: return "__array_rank";
2109 case ATT_ArrayExtent: return "__array_extent";
2111 llvm_unreachable("Array type trait not covered by switch");
2114 static const char *getExpressionTraitName(ExpressionTrait ET) {
2116 case ET_IsLValueExpr: return "__is_lvalue_expr";
2117 case ET_IsRValueExpr: return "__is_rvalue_expr";
2119 llvm_unreachable("Expression type trait not covered by switch");
2122 void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) {
2123 OS << getTypeTraitName(E->getTrait()) << "(";
2124 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
2127 E->getArg(I)->getType().print(OS, Policy);
2132 void StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
2133 OS << getTypeTraitName(E->getTrait()) << '(';
2134 E->getQueriedType().print(OS, Policy);
2138 void StmtPrinter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
2139 OS << getExpressionTraitName(E->getTrait()) << '(';
2140 PrintExpr(E->getQueriedExpression());
2144 void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
2146 PrintExpr(E->getOperand());
2150 void StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) {
2151 PrintExpr(E->getPattern());
2155 void StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2156 OS << "sizeof...(" << *E->getPack() << ")";
2159 void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr(
2160 SubstNonTypeTemplateParmPackExpr *Node) {
2161 OS << *Node->getParameterPack();
2164 void StmtPrinter::VisitSubstNonTypeTemplateParmExpr(
2165 SubstNonTypeTemplateParmExpr *Node) {
2166 Visit(Node->getReplacement());
2169 void StmtPrinter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
2170 OS << *E->getParameterPack();
2173 void StmtPrinter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *Node){
2174 PrintExpr(Node->GetTemporaryExpr());
2177 void StmtPrinter::VisitCXXFoldExpr(CXXFoldExpr *E) {
2180 PrintExpr(E->getLHS());
2181 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2185 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2186 PrintExpr(E->getRHS());
2191 // C++ Coroutines TS
2193 void StmtPrinter::VisitCoroutineBodyStmt(CoroutineBodyStmt *S) {
2194 Visit(S->getBody());
2197 void StmtPrinter::VisitCoreturnStmt(CoreturnStmt *S) {
2199 if (S->getOperand()) {
2201 Visit(S->getOperand());
2206 void StmtPrinter::VisitCoawaitExpr(CoawaitExpr *S) {
2208 PrintExpr(S->getOperand());
2211 void StmtPrinter::VisitDependentCoawaitExpr(DependentCoawaitExpr *S) {
2213 PrintExpr(S->getOperand());
2216 void StmtPrinter::VisitCoyieldExpr(CoyieldExpr *S) {
2218 PrintExpr(S->getOperand());
2223 void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
2225 VisitStringLiteral(Node->getString());
2228 void StmtPrinter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
2230 Visit(E->getSubExpr());
2233 void StmtPrinter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
2235 ObjCArrayLiteral::child_range Ch = E->children();
2236 for (auto I = Ch.begin(), E = Ch.end(); I != E; ++I) {
2237 if (I != Ch.begin())
2244 void StmtPrinter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
2246 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
2250 ObjCDictionaryElement Element = E->getKeyValueElement(I);
2253 Visit(Element.Value);
2254 if (Element.isPackExpansion())
2260 void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
2262 Node->getEncodedType().print(OS, Policy);
2266 void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
2268 Node->getSelector().print(OS);
2272 void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
2273 OS << "@protocol(" << *Node->getProtocol() << ')';
2276 void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
2278 switch (Mess->getReceiverKind()) {
2279 case ObjCMessageExpr::Instance:
2280 PrintExpr(Mess->getInstanceReceiver());
2283 case ObjCMessageExpr::Class:
2284 Mess->getClassReceiver().print(OS, Policy);
2287 case ObjCMessageExpr::SuperInstance:
2288 case ObjCMessageExpr::SuperClass:
2294 Selector selector = Mess->getSelector();
2295 if (selector.isUnarySelector()) {
2296 OS << selector.getNameForSlot(0);
2298 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
2299 if (i < selector.getNumArgs()) {
2300 if (i > 0) OS << ' ';
2301 if (selector.getIdentifierInfoForSlot(i))
2302 OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';
2306 else OS << ", "; // Handle variadic methods.
2308 PrintExpr(Mess->getArg(i));
2314 void StmtPrinter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) {
2315 OS << (Node->getValue() ? "__objc_yes" : "__objc_no");
2319 StmtPrinter::VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
2320 PrintExpr(E->getSubExpr());
2324 StmtPrinter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
2325 OS << '(' << E->getBridgeKindName();
2326 E->getType().print(OS, Policy);
2328 PrintExpr(E->getSubExpr());
2331 void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
2332 BlockDecl *BD = Node->getBlockDecl();
2335 const FunctionType *AFT = Node->getFunctionType();
2337 if (isa<FunctionNoProtoType>(AFT)) {
2339 } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
2341 for (BlockDecl::param_iterator AI = BD->param_begin(),
2342 E = BD->param_end(); AI != E; ++AI) {
2343 if (AI != BD->param_begin()) OS << ", ";
2344 std::string ParamStr = (*AI)->getNameAsString();
2345 (*AI)->getType().print(OS, Policy, ParamStr);
2348 const auto *FT = cast<FunctionProtoType>(AFT);
2349 if (FT->isVariadic()) {
2350 if (!BD->param_empty()) OS << ", ";
2358 void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {
2359 PrintExpr(Node->getSourceExpr());
2362 void StmtPrinter::VisitTypoExpr(TypoExpr *Node) {
2363 // TODO: Print something reasonable for a TypoExpr, if necessary.
2364 llvm_unreachable("Cannot print TypoExpr nodes");
2367 void StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) {
2368 OS << "__builtin_astype(";
2369 PrintExpr(Node->getSrcExpr());
2371 Node->getType().print(OS, Policy);
2375 //===----------------------------------------------------------------------===//
2376 // Stmt method implementations
2377 //===----------------------------------------------------------------------===//
2379 void Stmt::dumpPretty(const ASTContext &Context) const {
2380 printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts()));
2383 void Stmt::printPretty(raw_ostream &OS, PrinterHelper *Helper,
2384 const PrintingPolicy &Policy, unsigned Indentation,
2386 const ASTContext *Context) const {
2387 StmtPrinter P(OS, Helper, Policy, Indentation, NL, Context);
2388 P.Visit(const_cast<Stmt*>(this));
2391 //===----------------------------------------------------------------------===//
2393 //===----------------------------------------------------------------------===//
2395 // Implement virtual destructor.
2396 PrinterHelper::~PrinterHelper() = default;