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/DeclCXX.h"
18 #include "clang/AST/DeclObjC.h"
19 #include "clang/AST/DeclOpenMP.h"
20 #include "clang/AST/DeclTemplate.h"
21 #include "clang/AST/Expr.h"
22 #include "clang/AST/ExprCXX.h"
23 #include "clang/AST/ExprOpenMP.h"
24 #include "clang/AST/PrettyPrinter.h"
25 #include "clang/AST/StmtVisitor.h"
26 #include "clang/Basic/CharInfo.h"
27 #include "clang/Lex/Lexer.h"
28 #include "llvm/ADT/SmallString.h"
29 #include "llvm/Support/Format.h"
30 using namespace clang;
32 //===----------------------------------------------------------------------===//
33 // StmtPrinter Visitor
34 //===----------------------------------------------------------------------===//
37 class StmtPrinter : public StmtVisitor<StmtPrinter> {
40 clang::PrinterHelper* Helper;
41 PrintingPolicy Policy;
42 const ASTContext *Context;
45 StmtPrinter(raw_ostream &os, PrinterHelper *helper,
46 const PrintingPolicy &Policy, unsigned Indentation = 0,
47 const ASTContext *Context = nullptr)
48 : OS(os), IndentLevel(Indentation), Helper(helper), Policy(Policy),
51 void PrintStmt(Stmt *S) {
52 PrintStmt(S, Policy.Indentation);
55 void PrintStmt(Stmt *S, int SubIndent) {
56 IndentLevel += SubIndent;
57 if (S && isa<Expr>(S)) {
58 // If this is an expr used in a stmt context, indent and newline it.
65 Indent() << "<<<NULL STATEMENT>>>\n";
67 IndentLevel -= SubIndent;
70 void PrintRawCompoundStmt(CompoundStmt *S);
71 void PrintRawDecl(Decl *D);
72 void PrintRawDeclStmt(const DeclStmt *S);
73 void PrintRawIfStmt(IfStmt *If);
74 void PrintRawCXXCatchStmt(CXXCatchStmt *Catch);
75 void PrintCallArgs(CallExpr *E);
76 void PrintRawSEHExceptHandler(SEHExceptStmt *S);
77 void PrintRawSEHFinallyStmt(SEHFinallyStmt *S);
78 void PrintOMPExecutableDirective(OMPExecutableDirective *S,
79 bool ForceNoStmt = false);
81 void PrintExpr(Expr *E) {
88 raw_ostream &Indent(int Delta = 0) {
89 for (int i = 0, e = IndentLevel+Delta; i < e; ++i)
95 if (Helper && Helper->handledStmt(S,OS))
97 else StmtVisitor<StmtPrinter>::Visit(S);
100 void VisitStmt(Stmt *Node) LLVM_ATTRIBUTE_UNUSED {
101 Indent() << "<<unknown stmt type>>\n";
103 void VisitExpr(Expr *Node) LLVM_ATTRIBUTE_UNUSED {
104 OS << "<<unknown expr type>>";
106 void VisitCXXNamedCastExpr(CXXNamedCastExpr *Node);
108 #define ABSTRACT_STMT(CLASS)
109 #define STMT(CLASS, PARENT) \
110 void Visit##CLASS(CLASS *Node);
111 #include "clang/AST/StmtNodes.inc"
115 //===----------------------------------------------------------------------===//
116 // Stmt printing methods.
117 //===----------------------------------------------------------------------===//
119 /// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and
120 /// with no newline after the }.
121 void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
123 for (auto *I : Node->body())
129 void StmtPrinter::PrintRawDecl(Decl *D) {
130 D->print(OS, Policy, IndentLevel);
133 void StmtPrinter::PrintRawDeclStmt(const DeclStmt *S) {
134 SmallVector<Decl*, 2> Decls(S->decls());
135 Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel);
138 void StmtPrinter::VisitNullStmt(NullStmt *Node) {
142 void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
144 PrintRawDeclStmt(Node);
148 void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
150 PrintRawCompoundStmt(Node);
154 void StmtPrinter::VisitCaseStmt(CaseStmt *Node) {
155 Indent(-1) << "case ";
156 PrintExpr(Node->getLHS());
157 if (Node->getRHS()) {
159 PrintExpr(Node->getRHS());
163 PrintStmt(Node->getSubStmt(), 0);
166 void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) {
167 Indent(-1) << "default:\n";
168 PrintStmt(Node->getSubStmt(), 0);
171 void StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
172 Indent(-1) << Node->getName() << ":\n";
173 PrintStmt(Node->getSubStmt(), 0);
176 void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) {
177 for (const auto *Attr : Node->getAttrs()) {
178 Attr->printPretty(OS, Policy);
181 PrintStmt(Node->getSubStmt(), 0);
184 void StmtPrinter::PrintRawIfStmt(IfStmt *If) {
186 if (const DeclStmt *DS = If->getConditionVariableDeclStmt())
187 PrintRawDeclStmt(DS);
189 PrintExpr(If->getCond());
192 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(If->getThen())) {
194 PrintRawCompoundStmt(CS);
195 OS << (If->getElse() ? ' ' : '\n');
198 PrintStmt(If->getThen());
199 if (If->getElse()) Indent();
202 if (Stmt *Else = If->getElse()) {
205 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Else)) {
207 PrintRawCompoundStmt(CS);
209 } else if (IfStmt *ElseIf = dyn_cast<IfStmt>(Else)) {
211 PrintRawIfStmt(ElseIf);
214 PrintStmt(If->getElse());
219 void StmtPrinter::VisitIfStmt(IfStmt *If) {
224 void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) {
225 Indent() << "switch (";
226 if (const DeclStmt *DS = Node->getConditionVariableDeclStmt())
227 PrintRawDeclStmt(DS);
229 PrintExpr(Node->getCond());
232 // Pretty print compoundstmt bodies (very common).
233 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
235 PrintRawCompoundStmt(CS);
239 PrintStmt(Node->getBody());
243 void StmtPrinter::VisitWhileStmt(WhileStmt *Node) {
244 Indent() << "while (";
245 if (const DeclStmt *DS = Node->getConditionVariableDeclStmt())
246 PrintRawDeclStmt(DS);
248 PrintExpr(Node->getCond());
250 PrintStmt(Node->getBody());
253 void StmtPrinter::VisitDoStmt(DoStmt *Node) {
255 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
256 PrintRawCompoundStmt(CS);
260 PrintStmt(Node->getBody());
265 PrintExpr(Node->getCond());
269 void StmtPrinter::VisitForStmt(ForStmt *Node) {
271 if (Node->getInit()) {
272 if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getInit()))
273 PrintRawDeclStmt(DS);
275 PrintExpr(cast<Expr>(Node->getInit()));
278 if (Node->getCond()) {
280 PrintExpr(Node->getCond());
283 if (Node->getInc()) {
285 PrintExpr(Node->getInc());
289 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
290 PrintRawCompoundStmt(CS);
294 PrintStmt(Node->getBody());
298 void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) {
300 if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getElement()))
301 PrintRawDeclStmt(DS);
303 PrintExpr(cast<Expr>(Node->getElement()));
305 PrintExpr(Node->getCollection());
308 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
309 PrintRawCompoundStmt(CS);
313 PrintStmt(Node->getBody());
317 void StmtPrinter::VisitCXXForRangeStmt(CXXForRangeStmt *Node) {
319 PrintingPolicy SubPolicy(Policy);
320 SubPolicy.SuppressInitializers = true;
321 Node->getLoopVariable()->print(OS, SubPolicy, IndentLevel);
323 PrintExpr(Node->getRangeInit());
325 PrintStmt(Node->getBody());
327 if (Policy.IncludeNewlines) OS << "\n";
330 void StmtPrinter::VisitMSDependentExistsStmt(MSDependentExistsStmt *Node) {
332 if (Node->isIfExists())
333 OS << "__if_exists (";
335 OS << "__if_not_exists (";
337 if (NestedNameSpecifier *Qualifier
338 = Node->getQualifierLoc().getNestedNameSpecifier())
339 Qualifier->print(OS, Policy);
341 OS << Node->getNameInfo() << ") ";
343 PrintRawCompoundStmt(Node->getSubStmt());
346 void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
347 Indent() << "goto " << Node->getLabel()->getName() << ";";
348 if (Policy.IncludeNewlines) OS << "\n";
351 void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
352 Indent() << "goto *";
353 PrintExpr(Node->getTarget());
355 if (Policy.IncludeNewlines) OS << "\n";
358 void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
359 Indent() << "continue;";
360 if (Policy.IncludeNewlines) OS << "\n";
363 void StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
364 Indent() << "break;";
365 if (Policy.IncludeNewlines) OS << "\n";
369 void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
370 Indent() << "return";
371 if (Node->getRetValue()) {
373 PrintExpr(Node->getRetValue());
376 if (Policy.IncludeNewlines) OS << "\n";
380 void StmtPrinter::VisitGCCAsmStmt(GCCAsmStmt *Node) {
383 if (Node->isVolatile())
387 VisitStringLiteral(Node->getAsmString());
390 if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 ||
391 Node->getNumClobbers() != 0)
394 for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) {
398 if (!Node->getOutputName(i).empty()) {
400 OS << Node->getOutputName(i);
404 VisitStringLiteral(Node->getOutputConstraintLiteral(i));
406 Visit(Node->getOutputExpr(i));
411 if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0)
414 for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) {
418 if (!Node->getInputName(i).empty()) {
420 OS << Node->getInputName(i);
424 VisitStringLiteral(Node->getInputConstraintLiteral(i));
426 Visit(Node->getInputExpr(i));
431 if (Node->getNumClobbers() != 0)
434 for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) {
438 VisitStringLiteral(Node->getClobberStringLiteral(i));
442 if (Policy.IncludeNewlines) OS << "\n";
445 void StmtPrinter::VisitMSAsmStmt(MSAsmStmt *Node) {
446 // FIXME: Implement MS style inline asm statement printer.
447 Indent() << "__asm ";
448 if (Node->hasBraces())
450 OS << Node->getAsmString() << "\n";
451 if (Node->hasBraces())
455 void StmtPrinter::VisitCapturedStmt(CapturedStmt *Node) {
456 PrintStmt(Node->getCapturedDecl()->getBody());
459 void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) {
461 if (CompoundStmt *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) {
462 PrintRawCompoundStmt(TS);
466 for (unsigned I = 0, N = Node->getNumCatchStmts(); I != N; ++I) {
467 ObjCAtCatchStmt *catchStmt = Node->getCatchStmt(I);
468 Indent() << "@catch(";
469 if (catchStmt->getCatchParamDecl()) {
470 if (Decl *DS = catchStmt->getCatchParamDecl())
474 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) {
475 PrintRawCompoundStmt(CS);
480 if (ObjCAtFinallyStmt *FS = static_cast<ObjCAtFinallyStmt *>(
481 Node->getFinallyStmt())) {
482 Indent() << "@finally";
483 PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody()));
488 void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) {
491 void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) {
492 Indent() << "@catch (...) { /* todo */ } \n";
495 void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) {
496 Indent() << "@throw";
497 if (Node->getThrowExpr()) {
499 PrintExpr(Node->getThrowExpr());
504 void StmtPrinter::VisitObjCAvailabilityCheckExpr(
505 ObjCAvailabilityCheckExpr *Node) {
506 OS << "@available(...)";
509 void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) {
510 Indent() << "@synchronized (";
511 PrintExpr(Node->getSynchExpr());
513 PrintRawCompoundStmt(Node->getSynchBody());
517 void StmtPrinter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *Node) {
518 Indent() << "@autoreleasepool";
519 PrintRawCompoundStmt(dyn_cast<CompoundStmt>(Node->getSubStmt()));
523 void StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) {
525 if (Decl *ExDecl = Node->getExceptionDecl())
526 PrintRawDecl(ExDecl);
530 PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock()));
533 void StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) {
535 PrintRawCXXCatchStmt(Node);
539 void StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) {
541 PrintRawCompoundStmt(Node->getTryBlock());
542 for (unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) {
544 PrintRawCXXCatchStmt(Node->getHandler(i));
549 void StmtPrinter::VisitSEHTryStmt(SEHTryStmt *Node) {
550 Indent() << (Node->getIsCXXTry() ? "try " : "__try ");
551 PrintRawCompoundStmt(Node->getTryBlock());
552 SEHExceptStmt *E = Node->getExceptHandler();
553 SEHFinallyStmt *F = Node->getFinallyHandler();
555 PrintRawSEHExceptHandler(E);
557 assert(F && "Must have a finally block...");
558 PrintRawSEHFinallyStmt(F);
563 void StmtPrinter::PrintRawSEHFinallyStmt(SEHFinallyStmt *Node) {
565 PrintRawCompoundStmt(Node->getBlock());
569 void StmtPrinter::PrintRawSEHExceptHandler(SEHExceptStmt *Node) {
571 VisitExpr(Node->getFilterExpr());
573 PrintRawCompoundStmt(Node->getBlock());
577 void StmtPrinter::VisitSEHExceptStmt(SEHExceptStmt *Node) {
579 PrintRawSEHExceptHandler(Node);
583 void StmtPrinter::VisitSEHFinallyStmt(SEHFinallyStmt *Node) {
585 PrintRawSEHFinallyStmt(Node);
589 void StmtPrinter::VisitSEHLeaveStmt(SEHLeaveStmt *Node) {
590 Indent() << "__leave;";
591 if (Policy.IncludeNewlines) OS << "\n";
594 //===----------------------------------------------------------------------===//
595 // OpenMP clauses printing methods
596 //===----------------------------------------------------------------------===//
599 class OMPClausePrinter : public OMPClauseVisitor<OMPClausePrinter> {
601 const PrintingPolicy &Policy;
602 /// \brief Process clauses with list of variables.
603 template <typename T>
604 void VisitOMPClauseList(T *Node, char StartSym);
606 OMPClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy)
607 : OS(OS), Policy(Policy) { }
608 #define OPENMP_CLAUSE(Name, Class) \
609 void Visit##Class(Class *S);
610 #include "clang/Basic/OpenMPKinds.def"
613 void OMPClausePrinter::VisitOMPIfClause(OMPIfClause *Node) {
615 if (Node->getNameModifier() != OMPD_unknown)
616 OS << getOpenMPDirectiveName(Node->getNameModifier()) << ": ";
617 Node->getCondition()->printPretty(OS, nullptr, Policy, 0);
621 void OMPClausePrinter::VisitOMPFinalClause(OMPFinalClause *Node) {
623 Node->getCondition()->printPretty(OS, nullptr, Policy, 0);
627 void OMPClausePrinter::VisitOMPNumThreadsClause(OMPNumThreadsClause *Node) {
628 OS << "num_threads(";
629 Node->getNumThreads()->printPretty(OS, nullptr, Policy, 0);
633 void OMPClausePrinter::VisitOMPSafelenClause(OMPSafelenClause *Node) {
635 Node->getSafelen()->printPretty(OS, nullptr, Policy, 0);
639 void OMPClausePrinter::VisitOMPSimdlenClause(OMPSimdlenClause *Node) {
641 Node->getSimdlen()->printPretty(OS, nullptr, Policy, 0);
645 void OMPClausePrinter::VisitOMPCollapseClause(OMPCollapseClause *Node) {
647 Node->getNumForLoops()->printPretty(OS, nullptr, Policy, 0);
651 void OMPClausePrinter::VisitOMPDefaultClause(OMPDefaultClause *Node) {
653 << getOpenMPSimpleClauseTypeName(OMPC_default, Node->getDefaultKind())
657 void OMPClausePrinter::VisitOMPProcBindClause(OMPProcBindClause *Node) {
659 << getOpenMPSimpleClauseTypeName(OMPC_proc_bind, Node->getProcBindKind())
663 void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) {
665 if (Node->getFirstScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) {
666 OS << getOpenMPSimpleClauseTypeName(OMPC_schedule,
667 Node->getFirstScheduleModifier());
668 if (Node->getSecondScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) {
670 OS << getOpenMPSimpleClauseTypeName(OMPC_schedule,
671 Node->getSecondScheduleModifier());
675 OS << getOpenMPSimpleClauseTypeName(OMPC_schedule, Node->getScheduleKind());
676 if (auto *E = Node->getChunkSize()) {
678 E->printPretty(OS, nullptr, Policy);
683 void OMPClausePrinter::VisitOMPOrderedClause(OMPOrderedClause *Node) {
685 if (auto *Num = Node->getNumForLoops()) {
687 Num->printPretty(OS, nullptr, Policy, 0);
692 void OMPClausePrinter::VisitOMPNowaitClause(OMPNowaitClause *) {
696 void OMPClausePrinter::VisitOMPUntiedClause(OMPUntiedClause *) {
700 void OMPClausePrinter::VisitOMPNogroupClause(OMPNogroupClause *) {
704 void OMPClausePrinter::VisitOMPMergeableClause(OMPMergeableClause *) {
708 void OMPClausePrinter::VisitOMPReadClause(OMPReadClause *) { OS << "read"; }
710 void OMPClausePrinter::VisitOMPWriteClause(OMPWriteClause *) { OS << "write"; }
712 void OMPClausePrinter::VisitOMPUpdateClause(OMPUpdateClause *) {
716 void OMPClausePrinter::VisitOMPCaptureClause(OMPCaptureClause *) {
720 void OMPClausePrinter::VisitOMPSeqCstClause(OMPSeqCstClause *) {
724 void OMPClausePrinter::VisitOMPThreadsClause(OMPThreadsClause *) {
728 void OMPClausePrinter::VisitOMPSIMDClause(OMPSIMDClause *) { OS << "simd"; }
730 void OMPClausePrinter::VisitOMPDeviceClause(OMPDeviceClause *Node) {
732 Node->getDevice()->printPretty(OS, nullptr, Policy, 0);
736 void OMPClausePrinter::VisitOMPNumTeamsClause(OMPNumTeamsClause *Node) {
738 Node->getNumTeams()->printPretty(OS, nullptr, Policy, 0);
742 void OMPClausePrinter::VisitOMPThreadLimitClause(OMPThreadLimitClause *Node) {
743 OS << "thread_limit(";
744 Node->getThreadLimit()->printPretty(OS, nullptr, Policy, 0);
748 void OMPClausePrinter::VisitOMPPriorityClause(OMPPriorityClause *Node) {
750 Node->getPriority()->printPretty(OS, nullptr, Policy, 0);
754 void OMPClausePrinter::VisitOMPGrainsizeClause(OMPGrainsizeClause *Node) {
756 Node->getGrainsize()->printPretty(OS, nullptr, Policy, 0);
760 void OMPClausePrinter::VisitOMPNumTasksClause(OMPNumTasksClause *Node) {
762 Node->getNumTasks()->printPretty(OS, nullptr, Policy, 0);
766 void OMPClausePrinter::VisitOMPHintClause(OMPHintClause *Node) {
768 Node->getHint()->printPretty(OS, nullptr, Policy, 0);
773 void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) {
774 for (typename T::varlist_iterator I = Node->varlist_begin(),
775 E = Node->varlist_end();
777 assert(*I && "Expected non-null Stmt");
778 OS << (I == Node->varlist_begin() ? StartSym : ',');
779 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(*I)) {
780 if (isa<OMPCapturedExprDecl>(DRE->getDecl()))
781 DRE->printPretty(OS, nullptr, Policy, 0);
783 DRE->getDecl()->printQualifiedName(OS);
785 (*I)->printPretty(OS, nullptr, Policy, 0);
789 void OMPClausePrinter::VisitOMPPrivateClause(OMPPrivateClause *Node) {
790 if (!Node->varlist_empty()) {
792 VisitOMPClauseList(Node, '(');
797 void OMPClausePrinter::VisitOMPFirstprivateClause(OMPFirstprivateClause *Node) {
798 if (!Node->varlist_empty()) {
799 OS << "firstprivate";
800 VisitOMPClauseList(Node, '(');
805 void OMPClausePrinter::VisitOMPLastprivateClause(OMPLastprivateClause *Node) {
806 if (!Node->varlist_empty()) {
808 VisitOMPClauseList(Node, '(');
813 void OMPClausePrinter::VisitOMPSharedClause(OMPSharedClause *Node) {
814 if (!Node->varlist_empty()) {
816 VisitOMPClauseList(Node, '(');
821 void OMPClausePrinter::VisitOMPReductionClause(OMPReductionClause *Node) {
822 if (!Node->varlist_empty()) {
824 NestedNameSpecifier *QualifierLoc =
825 Node->getQualifierLoc().getNestedNameSpecifier();
826 OverloadedOperatorKind OOK =
827 Node->getNameInfo().getName().getCXXOverloadedOperator();
828 if (QualifierLoc == nullptr && OOK != OO_None) {
829 // Print reduction identifier in C format
830 OS << getOperatorSpelling(OOK);
833 if (QualifierLoc != nullptr)
834 QualifierLoc->print(OS, Policy);
835 OS << Node->getNameInfo();
838 VisitOMPClauseList(Node, ' ');
843 void OMPClausePrinter::VisitOMPTaskReductionClause(
844 OMPTaskReductionClause *Node) {
845 if (!Node->varlist_empty()) {
846 OS << "task_reduction(";
847 NestedNameSpecifier *QualifierLoc =
848 Node->getQualifierLoc().getNestedNameSpecifier();
849 OverloadedOperatorKind OOK =
850 Node->getNameInfo().getName().getCXXOverloadedOperator();
851 if (QualifierLoc == nullptr && OOK != OO_None) {
852 // Print reduction identifier in C format
853 OS << getOperatorSpelling(OOK);
856 if (QualifierLoc != nullptr)
857 QualifierLoc->print(OS, Policy);
858 OS << Node->getNameInfo();
861 VisitOMPClauseList(Node, ' ');
866 void OMPClausePrinter::VisitOMPInReductionClause(OMPInReductionClause *Node) {
867 if (!Node->varlist_empty()) {
868 OS << "in_reduction(";
869 NestedNameSpecifier *QualifierLoc =
870 Node->getQualifierLoc().getNestedNameSpecifier();
871 OverloadedOperatorKind OOK =
872 Node->getNameInfo().getName().getCXXOverloadedOperator();
873 if (QualifierLoc == nullptr && OOK != OO_None) {
874 // Print reduction identifier in C format
875 OS << getOperatorSpelling(OOK);
878 if (QualifierLoc != nullptr)
879 QualifierLoc->print(OS, Policy);
880 OS << Node->getNameInfo();
883 VisitOMPClauseList(Node, ' ');
888 void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) {
889 if (!Node->varlist_empty()) {
891 if (Node->getModifierLoc().isValid()) {
893 << getOpenMPSimpleClauseTypeName(OMPC_linear, Node->getModifier());
895 VisitOMPClauseList(Node, '(');
896 if (Node->getModifierLoc().isValid())
898 if (Node->getStep() != nullptr) {
900 Node->getStep()->printPretty(OS, nullptr, Policy, 0);
906 void OMPClausePrinter::VisitOMPAlignedClause(OMPAlignedClause *Node) {
907 if (!Node->varlist_empty()) {
909 VisitOMPClauseList(Node, '(');
910 if (Node->getAlignment() != nullptr) {
912 Node->getAlignment()->printPretty(OS, nullptr, Policy, 0);
918 void OMPClausePrinter::VisitOMPCopyinClause(OMPCopyinClause *Node) {
919 if (!Node->varlist_empty()) {
921 VisitOMPClauseList(Node, '(');
926 void OMPClausePrinter::VisitOMPCopyprivateClause(OMPCopyprivateClause *Node) {
927 if (!Node->varlist_empty()) {
929 VisitOMPClauseList(Node, '(');
934 void OMPClausePrinter::VisitOMPFlushClause(OMPFlushClause *Node) {
935 if (!Node->varlist_empty()) {
936 VisitOMPClauseList(Node, '(');
941 void OMPClausePrinter::VisitOMPDependClause(OMPDependClause *Node) {
943 OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(),
944 Node->getDependencyKind());
945 if (!Node->varlist_empty()) {
947 VisitOMPClauseList(Node, ' ');
952 void OMPClausePrinter::VisitOMPMapClause(OMPMapClause *Node) {
953 if (!Node->varlist_empty()) {
955 if (Node->getMapType() != OMPC_MAP_unknown) {
956 if (Node->getMapTypeModifier() != OMPC_MAP_unknown) {
957 OS << getOpenMPSimpleClauseTypeName(OMPC_map,
958 Node->getMapTypeModifier());
961 OS << getOpenMPSimpleClauseTypeName(OMPC_map, Node->getMapType());
964 VisitOMPClauseList(Node, ' ');
969 void OMPClausePrinter::VisitOMPToClause(OMPToClause *Node) {
970 if (!Node->varlist_empty()) {
972 VisitOMPClauseList(Node, '(');
977 void OMPClausePrinter::VisitOMPFromClause(OMPFromClause *Node) {
978 if (!Node->varlist_empty()) {
980 VisitOMPClauseList(Node, '(');
985 void OMPClausePrinter::VisitOMPDistScheduleClause(OMPDistScheduleClause *Node) {
986 OS << "dist_schedule(" << getOpenMPSimpleClauseTypeName(
987 OMPC_dist_schedule, Node->getDistScheduleKind());
988 if (auto *E = Node->getChunkSize()) {
990 E->printPretty(OS, nullptr, Policy);
995 void OMPClausePrinter::VisitOMPDefaultmapClause(OMPDefaultmapClause *Node) {
997 OS << getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
998 Node->getDefaultmapModifier());
1000 OS << getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
1001 Node->getDefaultmapKind());
1005 void OMPClausePrinter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *Node) {
1006 if (!Node->varlist_empty()) {
1007 OS << "use_device_ptr";
1008 VisitOMPClauseList(Node, '(');
1013 void OMPClausePrinter::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *Node) {
1014 if (!Node->varlist_empty()) {
1015 OS << "is_device_ptr";
1016 VisitOMPClauseList(Node, '(');
1022 //===----------------------------------------------------------------------===//
1023 // OpenMP directives printing methods
1024 //===----------------------------------------------------------------------===//
1026 void StmtPrinter::PrintOMPExecutableDirective(OMPExecutableDirective *S,
1028 OMPClausePrinter Printer(OS, Policy);
1029 ArrayRef<OMPClause *> Clauses = S->clauses();
1030 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
1032 if (*I && !(*I)->isImplicit()) {
1037 if (S->hasAssociatedStmt() && S->getAssociatedStmt() && !ForceNoStmt) {
1038 assert(isa<CapturedStmt>(S->getAssociatedStmt()) &&
1039 "Expected captured statement!");
1040 Stmt *CS = cast<CapturedStmt>(S->getAssociatedStmt())->getCapturedStmt();
1045 void StmtPrinter::VisitOMPParallelDirective(OMPParallelDirective *Node) {
1046 Indent() << "#pragma omp parallel ";
1047 PrintOMPExecutableDirective(Node);
1050 void StmtPrinter::VisitOMPSimdDirective(OMPSimdDirective *Node) {
1051 Indent() << "#pragma omp simd ";
1052 PrintOMPExecutableDirective(Node);
1055 void StmtPrinter::VisitOMPForDirective(OMPForDirective *Node) {
1056 Indent() << "#pragma omp for ";
1057 PrintOMPExecutableDirective(Node);
1060 void StmtPrinter::VisitOMPForSimdDirective(OMPForSimdDirective *Node) {
1061 Indent() << "#pragma omp for simd ";
1062 PrintOMPExecutableDirective(Node);
1065 void StmtPrinter::VisitOMPSectionsDirective(OMPSectionsDirective *Node) {
1066 Indent() << "#pragma omp sections ";
1067 PrintOMPExecutableDirective(Node);
1070 void StmtPrinter::VisitOMPSectionDirective(OMPSectionDirective *Node) {
1071 Indent() << "#pragma omp section";
1072 PrintOMPExecutableDirective(Node);
1075 void StmtPrinter::VisitOMPSingleDirective(OMPSingleDirective *Node) {
1076 Indent() << "#pragma omp single ";
1077 PrintOMPExecutableDirective(Node);
1080 void StmtPrinter::VisitOMPMasterDirective(OMPMasterDirective *Node) {
1081 Indent() << "#pragma omp master";
1082 PrintOMPExecutableDirective(Node);
1085 void StmtPrinter::VisitOMPCriticalDirective(OMPCriticalDirective *Node) {
1086 Indent() << "#pragma omp critical";
1087 if (Node->getDirectiveName().getName()) {
1089 Node->getDirectiveName().printName(OS);
1093 PrintOMPExecutableDirective(Node);
1096 void StmtPrinter::VisitOMPParallelForDirective(OMPParallelForDirective *Node) {
1097 Indent() << "#pragma omp parallel for ";
1098 PrintOMPExecutableDirective(Node);
1101 void StmtPrinter::VisitOMPParallelForSimdDirective(
1102 OMPParallelForSimdDirective *Node) {
1103 Indent() << "#pragma omp parallel for simd ";
1104 PrintOMPExecutableDirective(Node);
1107 void StmtPrinter::VisitOMPParallelSectionsDirective(
1108 OMPParallelSectionsDirective *Node) {
1109 Indent() << "#pragma omp parallel sections ";
1110 PrintOMPExecutableDirective(Node);
1113 void StmtPrinter::VisitOMPTaskDirective(OMPTaskDirective *Node) {
1114 Indent() << "#pragma omp task ";
1115 PrintOMPExecutableDirective(Node);
1118 void StmtPrinter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *Node) {
1119 Indent() << "#pragma omp taskyield";
1120 PrintOMPExecutableDirective(Node);
1123 void StmtPrinter::VisitOMPBarrierDirective(OMPBarrierDirective *Node) {
1124 Indent() << "#pragma omp barrier";
1125 PrintOMPExecutableDirective(Node);
1128 void StmtPrinter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *Node) {
1129 Indent() << "#pragma omp taskwait";
1130 PrintOMPExecutableDirective(Node);
1133 void StmtPrinter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *Node) {
1134 Indent() << "#pragma omp taskgroup ";
1135 PrintOMPExecutableDirective(Node);
1138 void StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) {
1139 Indent() << "#pragma omp flush ";
1140 PrintOMPExecutableDirective(Node);
1143 void StmtPrinter::VisitOMPOrderedDirective(OMPOrderedDirective *Node) {
1144 Indent() << "#pragma omp ordered ";
1145 PrintOMPExecutableDirective(Node);
1148 void StmtPrinter::VisitOMPAtomicDirective(OMPAtomicDirective *Node) {
1149 Indent() << "#pragma omp atomic ";
1150 PrintOMPExecutableDirective(Node);
1153 void StmtPrinter::VisitOMPTargetDirective(OMPTargetDirective *Node) {
1154 Indent() << "#pragma omp target ";
1155 PrintOMPExecutableDirective(Node);
1158 void StmtPrinter::VisitOMPTargetDataDirective(OMPTargetDataDirective *Node) {
1159 Indent() << "#pragma omp target data ";
1160 PrintOMPExecutableDirective(Node);
1163 void StmtPrinter::VisitOMPTargetEnterDataDirective(
1164 OMPTargetEnterDataDirective *Node) {
1165 Indent() << "#pragma omp target enter data ";
1166 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
1169 void StmtPrinter::VisitOMPTargetExitDataDirective(
1170 OMPTargetExitDataDirective *Node) {
1171 Indent() << "#pragma omp target exit data ";
1172 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
1175 void StmtPrinter::VisitOMPTargetParallelDirective(
1176 OMPTargetParallelDirective *Node) {
1177 Indent() << "#pragma omp target parallel ";
1178 PrintOMPExecutableDirective(Node);
1181 void StmtPrinter::VisitOMPTargetParallelForDirective(
1182 OMPTargetParallelForDirective *Node) {
1183 Indent() << "#pragma omp target parallel for ";
1184 PrintOMPExecutableDirective(Node);
1187 void StmtPrinter::VisitOMPTeamsDirective(OMPTeamsDirective *Node) {
1188 Indent() << "#pragma omp teams ";
1189 PrintOMPExecutableDirective(Node);
1192 void StmtPrinter::VisitOMPCancellationPointDirective(
1193 OMPCancellationPointDirective *Node) {
1194 Indent() << "#pragma omp cancellation point "
1195 << getOpenMPDirectiveName(Node->getCancelRegion());
1196 PrintOMPExecutableDirective(Node);
1199 void StmtPrinter::VisitOMPCancelDirective(OMPCancelDirective *Node) {
1200 Indent() << "#pragma omp cancel "
1201 << getOpenMPDirectiveName(Node->getCancelRegion()) << " ";
1202 PrintOMPExecutableDirective(Node);
1205 void StmtPrinter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *Node) {
1206 Indent() << "#pragma omp taskloop ";
1207 PrintOMPExecutableDirective(Node);
1210 void StmtPrinter::VisitOMPTaskLoopSimdDirective(
1211 OMPTaskLoopSimdDirective *Node) {
1212 Indent() << "#pragma omp taskloop simd ";
1213 PrintOMPExecutableDirective(Node);
1216 void StmtPrinter::VisitOMPDistributeDirective(OMPDistributeDirective *Node) {
1217 Indent() << "#pragma omp distribute ";
1218 PrintOMPExecutableDirective(Node);
1221 void StmtPrinter::VisitOMPTargetUpdateDirective(
1222 OMPTargetUpdateDirective *Node) {
1223 Indent() << "#pragma omp target update ";
1224 PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
1227 void StmtPrinter::VisitOMPDistributeParallelForDirective(
1228 OMPDistributeParallelForDirective *Node) {
1229 Indent() << "#pragma omp distribute parallel for ";
1230 PrintOMPExecutableDirective(Node);
1233 void StmtPrinter::VisitOMPDistributeParallelForSimdDirective(
1234 OMPDistributeParallelForSimdDirective *Node) {
1235 Indent() << "#pragma omp distribute parallel for simd ";
1236 PrintOMPExecutableDirective(Node);
1239 void StmtPrinter::VisitOMPDistributeSimdDirective(
1240 OMPDistributeSimdDirective *Node) {
1241 Indent() << "#pragma omp distribute simd ";
1242 PrintOMPExecutableDirective(Node);
1245 void StmtPrinter::VisitOMPTargetParallelForSimdDirective(
1246 OMPTargetParallelForSimdDirective *Node) {
1247 Indent() << "#pragma omp target parallel for simd ";
1248 PrintOMPExecutableDirective(Node);
1251 void StmtPrinter::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *Node) {
1252 Indent() << "#pragma omp target simd ";
1253 PrintOMPExecutableDirective(Node);
1256 void StmtPrinter::VisitOMPTeamsDistributeDirective(
1257 OMPTeamsDistributeDirective *Node) {
1258 Indent() << "#pragma omp teams distribute ";
1259 PrintOMPExecutableDirective(Node);
1262 void StmtPrinter::VisitOMPTeamsDistributeSimdDirective(
1263 OMPTeamsDistributeSimdDirective *Node) {
1264 Indent() << "#pragma omp teams distribute simd ";
1265 PrintOMPExecutableDirective(Node);
1268 void StmtPrinter::VisitOMPTeamsDistributeParallelForSimdDirective(
1269 OMPTeamsDistributeParallelForSimdDirective *Node) {
1270 Indent() << "#pragma omp teams distribute parallel for simd ";
1271 PrintOMPExecutableDirective(Node);
1274 void StmtPrinter::VisitOMPTeamsDistributeParallelForDirective(
1275 OMPTeamsDistributeParallelForDirective *Node) {
1276 Indent() << "#pragma omp teams distribute parallel for ";
1277 PrintOMPExecutableDirective(Node);
1280 void StmtPrinter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *Node) {
1281 Indent() << "#pragma omp target teams ";
1282 PrintOMPExecutableDirective(Node);
1285 void StmtPrinter::VisitOMPTargetTeamsDistributeDirective(
1286 OMPTargetTeamsDistributeDirective *Node) {
1287 Indent() << "#pragma omp target teams distribute ";
1288 PrintOMPExecutableDirective(Node);
1291 void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForDirective(
1292 OMPTargetTeamsDistributeParallelForDirective *Node) {
1293 Indent() << "#pragma omp target teams distribute parallel for ";
1294 PrintOMPExecutableDirective(Node);
1297 void StmtPrinter::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
1298 OMPTargetTeamsDistributeParallelForSimdDirective *Node) {
1299 Indent() << "#pragma omp target teams distribute parallel for simd ";
1300 PrintOMPExecutableDirective(Node);
1303 void StmtPrinter::VisitOMPTargetTeamsDistributeSimdDirective(
1304 OMPTargetTeamsDistributeSimdDirective *Node) {
1305 Indent() << "#pragma omp target teams distribute simd ";
1306 PrintOMPExecutableDirective(Node);
1309 //===----------------------------------------------------------------------===//
1310 // Expr printing methods.
1311 //===----------------------------------------------------------------------===//
1313 void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
1314 if (auto *OCED = dyn_cast<OMPCapturedExprDecl>(Node->getDecl())) {
1315 OCED->getInit()->IgnoreImpCasts()->printPretty(OS, nullptr, Policy);
1318 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1319 Qualifier->print(OS, Policy);
1320 if (Node->hasTemplateKeyword())
1322 OS << Node->getNameInfo();
1323 if (Node->hasExplicitTemplateArgs())
1324 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
1327 void StmtPrinter::VisitDependentScopeDeclRefExpr(
1328 DependentScopeDeclRefExpr *Node) {
1329 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1330 Qualifier->print(OS, Policy);
1331 if (Node->hasTemplateKeyword())
1333 OS << Node->getNameInfo();
1334 if (Node->hasExplicitTemplateArgs())
1335 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
1338 void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
1339 if (Node->getQualifier())
1340 Node->getQualifier()->print(OS, Policy);
1341 if (Node->hasTemplateKeyword())
1343 OS << Node->getNameInfo();
1344 if (Node->hasExplicitTemplateArgs())
1345 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
1348 static bool isImplicitSelf(const Expr *E) {
1349 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
1350 if (const ImplicitParamDecl *PD =
1351 dyn_cast<ImplicitParamDecl>(DRE->getDecl())) {
1352 if (PD->getParameterKind() == ImplicitParamDecl::ObjCSelf &&
1353 DRE->getLocStart().isInvalid())
1360 void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
1361 if (Node->getBase()) {
1362 if (!Policy.SuppressImplicitBase ||
1363 !isImplicitSelf(Node->getBase()->IgnoreImpCasts())) {
1364 PrintExpr(Node->getBase());
1365 OS << (Node->isArrow() ? "->" : ".");
1368 OS << *Node->getDecl();
1371 void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
1372 if (Node->isSuperReceiver())
1374 else if (Node->isObjectReceiver() && Node->getBase()) {
1375 PrintExpr(Node->getBase());
1377 } else if (Node->isClassReceiver() && Node->getClassReceiver()) {
1378 OS << Node->getClassReceiver()->getName() << ".";
1381 if (Node->isImplicitProperty())
1382 Node->getImplicitPropertyGetter()->getSelector().print(OS);
1384 OS << Node->getExplicitProperty()->getName();
1387 void StmtPrinter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node) {
1389 PrintExpr(Node->getBaseExpr());
1391 PrintExpr(Node->getKeyExpr());
1395 void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
1396 OS << PredefinedExpr::getIdentTypeName(Node->getIdentType());
1399 void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
1400 unsigned value = Node->getValue();
1402 switch (Node->getKind()) {
1403 case CharacterLiteral::Ascii: break; // no prefix.
1404 case CharacterLiteral::Wide: OS << 'L'; break;
1405 case CharacterLiteral::UTF8: OS << "u8"; break;
1406 case CharacterLiteral::UTF16: OS << 'u'; break;
1407 case CharacterLiteral::UTF32: OS << 'U'; break;
1418 // TODO: K&R: the meaning of '\\a' is different in traditional C
1424 // Nonstandard escape sequence.
1444 // A character literal might be sign-extended, which
1445 // would result in an invalid \U escape sequence.
1446 // FIXME: multicharacter literals such as '\xFF\xFF\xFF\xFF'
1447 // are not correctly handled.
1448 if ((value & ~0xFFu) == ~0xFFu && Node->getKind() == CharacterLiteral::Ascii)
1450 if (value < 256 && isPrintable((unsigned char)value))
1451 OS << "'" << (char)value << "'";
1452 else if (value < 256)
1453 OS << "'\\x" << llvm::format("%02x", value) << "'";
1454 else if (value <= 0xFFFF)
1455 OS << "'\\u" << llvm::format("%04x", value) << "'";
1457 OS << "'\\U" << llvm::format("%08x", value) << "'";
1461 /// Prints the given expression using the original source text. Returns true on
1462 /// success, false otherwise.
1463 static bool printExprAsWritten(raw_ostream &OS, Expr *E,
1464 const ASTContext *Context) {
1467 bool Invalid = false;
1468 StringRef Source = Lexer::getSourceText(
1469 CharSourceRange::getTokenRange(E->getSourceRange()),
1470 Context->getSourceManager(), Context->getLangOpts(), &Invalid);
1478 void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
1479 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1481 bool isSigned = Node->getType()->isSignedIntegerType();
1482 OS << Node->getValue().toString(10, isSigned);
1484 // Emit suffixes. Integer literals are always a builtin integer type.
1485 switch (Node->getType()->getAs<BuiltinType>()->getKind()) {
1486 default: llvm_unreachable("Unexpected type for integer literal!");
1487 case BuiltinType::Char_S:
1488 case BuiltinType::Char_U: OS << "i8"; break;
1489 case BuiltinType::UChar: OS << "Ui8"; break;
1490 case BuiltinType::Short: OS << "i16"; break;
1491 case BuiltinType::UShort: OS << "Ui16"; break;
1492 case BuiltinType::Int: break; // no suffix.
1493 case BuiltinType::UInt: OS << 'U'; break;
1494 case BuiltinType::Long: OS << 'L'; break;
1495 case BuiltinType::ULong: OS << "UL"; break;
1496 case BuiltinType::LongLong: OS << "LL"; break;
1497 case BuiltinType::ULongLong: OS << "ULL"; break;
1501 static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node,
1503 SmallString<16> Str;
1504 Node->getValue().toString(Str);
1506 if (Str.find_first_not_of("-0123456789") == StringRef::npos)
1507 OS << '.'; // Trailing dot in order to separate from ints.
1512 // Emit suffixes. Float literals are always a builtin float type.
1513 switch (Node->getType()->getAs<BuiltinType>()->getKind()) {
1514 default: llvm_unreachable("Unexpected type for float literal!");
1515 case BuiltinType::Half: break; // FIXME: suffix?
1516 case BuiltinType::Double: break; // no suffix.
1517 case BuiltinType::Float16: OS << "F16"; break;
1518 case BuiltinType::Float: OS << 'F'; break;
1519 case BuiltinType::LongDouble: OS << 'L'; break;
1520 case BuiltinType::Float128: OS << 'Q'; break;
1524 void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
1525 if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
1527 PrintFloatingLiteral(OS, Node, /*PrintSuffix=*/true);
1530 void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
1531 PrintExpr(Node->getSubExpr());
1535 void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
1536 Str->outputString(OS);
1538 void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
1540 PrintExpr(Node->getSubExpr());
1543 void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
1544 if (!Node->isPostfix()) {
1545 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
1547 // Print a space if this is an "identifier operator" like __real, or if
1548 // it might be concatenated incorrectly like '+'.
1549 switch (Node->getOpcode()) {
1558 if (isa<UnaryOperator>(Node->getSubExpr()))
1563 PrintExpr(Node->getSubExpr());
1565 if (Node->isPostfix())
1566 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
1569 void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {
1570 OS << "__builtin_offsetof(";
1571 Node->getTypeSourceInfo()->getType().print(OS, Policy);
1573 bool PrintedSomething = false;
1574 for (unsigned i = 0, n = Node->getNumComponents(); i < n; ++i) {
1575 OffsetOfNode ON = Node->getComponent(i);
1576 if (ON.getKind() == OffsetOfNode::Array) {
1579 PrintExpr(Node->getIndexExpr(ON.getArrayExprIndex()));
1581 PrintedSomething = true;
1585 // Skip implicit base indirections.
1586 if (ON.getKind() == OffsetOfNode::Base)
1589 // Field or identifier node.
1590 IdentifierInfo *Id = ON.getFieldName();
1594 if (PrintedSomething)
1597 PrintedSomething = true;
1598 OS << Id->getName();
1603 void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node){
1604 switch(Node->getKind()) {
1611 else if (Policy.UnderscoreAlignof)
1619 case UETT_OpenMPRequiredSimdAlign:
1620 OS << "__builtin_omp_required_simd_align";
1623 if (Node->isArgumentType()) {
1625 Node->getArgumentType().print(OS, Policy);
1629 PrintExpr(Node->getArgumentExpr());
1633 void StmtPrinter::VisitGenericSelectionExpr(GenericSelectionExpr *Node) {
1635 PrintExpr(Node->getControllingExpr());
1636 for (unsigned i = 0; i != Node->getNumAssocs(); ++i) {
1638 QualType T = Node->getAssocType(i);
1642 T.print(OS, Policy);
1644 PrintExpr(Node->getAssocExpr(i));
1649 void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
1650 PrintExpr(Node->getLHS());
1652 PrintExpr(Node->getRHS());
1656 void StmtPrinter::VisitOMPArraySectionExpr(OMPArraySectionExpr *Node) {
1657 PrintExpr(Node->getBase());
1659 if (Node->getLowerBound())
1660 PrintExpr(Node->getLowerBound());
1661 if (Node->getColonLoc().isValid()) {
1663 if (Node->getLength())
1664 PrintExpr(Node->getLength());
1669 void StmtPrinter::PrintCallArgs(CallExpr *Call) {
1670 for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
1671 if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
1672 // Don't print any defaulted arguments
1677 PrintExpr(Call->getArg(i));
1681 void StmtPrinter::VisitCallExpr(CallExpr *Call) {
1682 PrintExpr(Call->getCallee());
1684 PrintCallArgs(Call);
1688 static bool isImplicitThis(const Expr *E) {
1689 if (const auto *TE = dyn_cast<CXXThisExpr>(E))
1690 return TE->isImplicit();
1694 void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
1695 if (!Policy.SuppressImplicitBase || !isImplicitThis(Node->getBase())) {
1696 PrintExpr(Node->getBase());
1698 MemberExpr *ParentMember = dyn_cast<MemberExpr>(Node->getBase());
1699 FieldDecl *ParentDecl =
1700 ParentMember ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl())
1703 if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion())
1704 OS << (Node->isArrow() ? "->" : ".");
1707 if (FieldDecl *FD = dyn_cast<FieldDecl>(Node->getMemberDecl()))
1708 if (FD->isAnonymousStructOrUnion())
1711 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1712 Qualifier->print(OS, Policy);
1713 if (Node->hasTemplateKeyword())
1715 OS << Node->getMemberNameInfo();
1716 if (Node->hasExplicitTemplateArgs())
1717 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
1719 void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
1720 PrintExpr(Node->getBase());
1721 OS << (Node->isArrow() ? "->isa" : ".isa");
1724 void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
1725 PrintExpr(Node->getBase());
1727 OS << Node->getAccessor().getName();
1729 void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
1731 Node->getTypeAsWritten().print(OS, Policy);
1733 PrintExpr(Node->getSubExpr());
1735 void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
1737 Node->getType().print(OS, Policy);
1739 PrintExpr(Node->getInitializer());
1741 void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
1742 // No need to print anything, simply forward to the subexpression.
1743 PrintExpr(Node->getSubExpr());
1745 void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
1746 PrintExpr(Node->getLHS());
1747 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
1748 PrintExpr(Node->getRHS());
1750 void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
1751 PrintExpr(Node->getLHS());
1752 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
1753 PrintExpr(Node->getRHS());
1755 void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
1756 PrintExpr(Node->getCond());
1758 PrintExpr(Node->getLHS());
1760 PrintExpr(Node->getRHS());
1766 StmtPrinter::VisitBinaryConditionalOperator(BinaryConditionalOperator *Node) {
1767 PrintExpr(Node->getCommon());
1769 PrintExpr(Node->getFalseExpr());
1771 void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
1772 OS << "&&" << Node->getLabel()->getName();
1775 void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
1777 PrintRawCompoundStmt(E->getSubStmt());
1781 void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
1782 OS << "__builtin_choose_expr(";
1783 PrintExpr(Node->getCond());
1785 PrintExpr(Node->getLHS());
1787 PrintExpr(Node->getRHS());
1791 void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
1795 void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
1796 OS << "__builtin_shufflevector(";
1797 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
1799 PrintExpr(Node->getExpr(i));
1804 void StmtPrinter::VisitConvertVectorExpr(ConvertVectorExpr *Node) {
1805 OS << "__builtin_convertvector(";
1806 PrintExpr(Node->getSrcExpr());
1808 Node->getType().print(OS, Policy);
1812 void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
1813 if (Node->getSyntacticForm()) {
1814 Visit(Node->getSyntacticForm());
1819 for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
1821 if (Node->getInit(i))
1822 PrintExpr(Node->getInit(i));
1829 void StmtPrinter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *Node) {
1830 // There's no way to express this expression in any of our supported
1831 // languages, so just emit something terse and (hopefully) clear.
1833 PrintExpr(Node->getSubExpr());
1837 void StmtPrinter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *Node) {
1841 void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
1843 for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {
1845 PrintExpr(Node->getExpr(i));
1850 void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
1851 bool NeedsEquals = true;
1852 for (const DesignatedInitExpr::Designator &D : Node->designators()) {
1853 if (D.isFieldDesignator()) {
1854 if (D.getDotLoc().isInvalid()) {
1855 if (IdentifierInfo *II = D.getFieldName()) {
1856 OS << II->getName() << ":";
1857 NeedsEquals = false;
1860 OS << "." << D.getFieldName()->getName();
1864 if (D.isArrayDesignator()) {
1865 PrintExpr(Node->getArrayIndex(D));
1867 PrintExpr(Node->getArrayRangeStart(D));
1869 PrintExpr(Node->getArrayRangeEnd(D));
1879 PrintExpr(Node->getInit());
1882 void StmtPrinter::VisitDesignatedInitUpdateExpr(
1883 DesignatedInitUpdateExpr *Node) {
1886 PrintExpr(Node->getBase());
1889 OS << "/*updater*/";
1890 PrintExpr(Node->getUpdater());
1894 void StmtPrinter::VisitNoInitExpr(NoInitExpr *Node) {
1895 OS << "/*no init*/";
1898 void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
1899 if (Node->getType()->getAsCXXRecordDecl()) {
1900 OS << "/*implicit*/";
1901 Node->getType().print(OS, Policy);
1904 OS << "/*implicit*/(";
1905 Node->getType().print(OS, Policy);
1907 if (Node->getType()->isRecordType())
1914 void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
1915 OS << "__builtin_va_arg(";
1916 PrintExpr(Node->getSubExpr());
1918 Node->getType().print(OS, Policy);
1922 void StmtPrinter::VisitPseudoObjectExpr(PseudoObjectExpr *Node) {
1923 PrintExpr(Node->getSyntacticForm());
1926 void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) {
1927 const char *Name = nullptr;
1928 switch (Node->getOp()) {
1929 #define BUILTIN(ID, TYPE, ATTRS)
1930 #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
1931 case AtomicExpr::AO ## ID: \
1934 #include "clang/Basic/Builtins.def"
1938 // AtomicExpr stores its subexpressions in a permuted order.
1939 PrintExpr(Node->getPtr());
1940 if (Node->getOp() != AtomicExpr::AO__c11_atomic_load &&
1941 Node->getOp() != AtomicExpr::AO__atomic_load_n &&
1942 Node->getOp() != AtomicExpr::AO__opencl_atomic_load) {
1944 PrintExpr(Node->getVal1());
1946 if (Node->getOp() == AtomicExpr::AO__atomic_exchange ||
1947 Node->isCmpXChg()) {
1949 PrintExpr(Node->getVal2());
1951 if (Node->getOp() == AtomicExpr::AO__atomic_compare_exchange ||
1952 Node->getOp() == AtomicExpr::AO__atomic_compare_exchange_n) {
1954 PrintExpr(Node->getWeak());
1956 if (Node->getOp() != AtomicExpr::AO__c11_atomic_init &&
1957 Node->getOp() != AtomicExpr::AO__opencl_atomic_init) {
1959 PrintExpr(Node->getOrder());
1961 if (Node->isCmpXChg()) {
1963 PrintExpr(Node->getOrderFail());
1969 void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
1970 const char *OpStrings[NUM_OVERLOADED_OPERATORS] = {
1972 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
1974 #include "clang/Basic/OperatorKinds.def"
1977 OverloadedOperatorKind Kind = Node->getOperator();
1978 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
1979 if (Node->getNumArgs() == 1) {
1980 OS << OpStrings[Kind] << ' ';
1981 PrintExpr(Node->getArg(0));
1983 PrintExpr(Node->getArg(0));
1984 OS << ' ' << OpStrings[Kind];
1986 } else if (Kind == OO_Arrow) {
1987 PrintExpr(Node->getArg(0));
1988 } else if (Kind == OO_Call) {
1989 PrintExpr(Node->getArg(0));
1991 for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) {
1994 if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx)))
1995 PrintExpr(Node->getArg(ArgIdx));
1998 } else if (Kind == OO_Subscript) {
1999 PrintExpr(Node->getArg(0));
2001 PrintExpr(Node->getArg(1));
2003 } else if (Node->getNumArgs() == 1) {
2004 OS << OpStrings[Kind] << ' ';
2005 PrintExpr(Node->getArg(0));
2006 } else if (Node->getNumArgs() == 2) {
2007 PrintExpr(Node->getArg(0));
2008 OS << ' ' << OpStrings[Kind] << ' ';
2009 PrintExpr(Node->getArg(1));
2011 llvm_unreachable("unknown overloaded operator");
2015 void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
2016 // If we have a conversion operator call only print the argument.
2017 CXXMethodDecl *MD = Node->getMethodDecl();
2018 if (MD && isa<CXXConversionDecl>(MD)) {
2019 PrintExpr(Node->getImplicitObjectArgument());
2022 VisitCallExpr(cast<CallExpr>(Node));
2025 void StmtPrinter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *Node) {
2026 PrintExpr(Node->getCallee());
2028 PrintCallArgs(Node->getConfig());
2030 PrintCallArgs(Node);
2034 void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
2035 OS << Node->getCastName() << '<';
2036 Node->getTypeAsWritten().print(OS, Policy);
2038 PrintExpr(Node->getSubExpr());
2042 void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {
2043 VisitCXXNamedCastExpr(Node);
2046 void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {
2047 VisitCXXNamedCastExpr(Node);
2050 void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {
2051 VisitCXXNamedCastExpr(Node);
2054 void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
2055 VisitCXXNamedCastExpr(Node);
2058 void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
2060 if (Node->isTypeOperand()) {
2061 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
2063 PrintExpr(Node->getExprOperand());
2068 void StmtPrinter::VisitCXXUuidofExpr(CXXUuidofExpr *Node) {
2070 if (Node->isTypeOperand()) {
2071 Node->getTypeOperandSourceInfo()->getType().print(OS, Policy);
2073 PrintExpr(Node->getExprOperand());
2078 void StmtPrinter::VisitMSPropertyRefExpr(MSPropertyRefExpr *Node) {
2079 PrintExpr(Node->getBaseExpr());
2080 if (Node->isArrow())
2084 if (NestedNameSpecifier *Qualifier =
2085 Node->getQualifierLoc().getNestedNameSpecifier())
2086 Qualifier->print(OS, Policy);
2087 OS << Node->getPropertyDecl()->getDeclName();
2090 void StmtPrinter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *Node) {
2091 PrintExpr(Node->getBase());
2093 PrintExpr(Node->getIdx());
2097 void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) {
2098 switch (Node->getLiteralOperatorKind()) {
2099 case UserDefinedLiteral::LOK_Raw:
2100 OS << cast<StringLiteral>(Node->getArg(0)->IgnoreImpCasts())->getString();
2102 case UserDefinedLiteral::LOK_Template: {
2103 DeclRefExpr *DRE = cast<DeclRefExpr>(Node->getCallee()->IgnoreImpCasts());
2104 const TemplateArgumentList *Args =
2105 cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs();
2108 if (Args->size() != 1) {
2109 OS << "operator\"\"" << Node->getUDSuffix()->getName();
2110 printTemplateArgumentList(OS, Args->asArray(), Policy);
2115 const TemplateArgument &Pack = Args->get(0);
2116 for (const auto &P : Pack.pack_elements()) {
2117 char C = (char)P.getAsIntegral().getZExtValue();
2122 case UserDefinedLiteral::LOK_Integer: {
2123 // Print integer literal without suffix.
2124 IntegerLiteral *Int = cast<IntegerLiteral>(Node->getCookedLiteral());
2125 OS << Int->getValue().toString(10, /*isSigned*/false);
2128 case UserDefinedLiteral::LOK_Floating: {
2129 // Print floating literal without suffix.
2130 FloatingLiteral *Float = cast<FloatingLiteral>(Node->getCookedLiteral());
2131 PrintFloatingLiteral(OS, Float, /*PrintSuffix=*/false);
2134 case UserDefinedLiteral::LOK_String:
2135 case UserDefinedLiteral::LOK_Character:
2136 PrintExpr(Node->getCookedLiteral());
2139 OS << Node->getUDSuffix()->getName();
2142 void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
2143 OS << (Node->getValue() ? "true" : "false");
2146 void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
2150 void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
2154 void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
2155 if (!Node->getSubExpr())
2159 PrintExpr(Node->getSubExpr());
2163 void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
2164 // Nothing to print: we picked up the default argument.
2167 void StmtPrinter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *Node) {
2168 // Nothing to print: we picked up the default initializer.
2171 void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
2172 Node->getType().print(OS, Policy);
2173 // If there are no parens, this is list-initialization, and the braces are
2174 // part of the syntax of the inner construct.
2175 if (Node->getLParenLoc().isValid())
2177 PrintExpr(Node->getSubExpr());
2178 if (Node->getLParenLoc().isValid())
2182 void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
2183 PrintExpr(Node->getSubExpr());
2186 void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
2187 Node->getType().print(OS, Policy);
2188 if (Node->isStdInitListInitialization())
2189 /* Nothing to do; braces are part of creating the std::initializer_list. */;
2190 else if (Node->isListInitialization())
2194 for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),
2195 ArgEnd = Node->arg_end();
2196 Arg != ArgEnd; ++Arg) {
2197 if ((*Arg)->isDefaultArgument())
2199 if (Arg != Node->arg_begin())
2203 if (Node->isStdInitListInitialization())
2205 else if (Node->isListInitialization())
2211 void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {
2213 bool NeedComma = false;
2214 switch (Node->getCaptureDefault()) {
2228 for (LambdaExpr::capture_iterator C = Node->explicit_capture_begin(),
2229 CEnd = Node->explicit_capture_end();
2232 if (C->capturesVLAType())
2239 switch (C->getCaptureKind()) {
2247 if (Node->getCaptureDefault() != LCD_ByRef || Node->isInitCapture(C))
2249 OS << C->getCapturedVar()->getName();
2253 OS << C->getCapturedVar()->getName();
2256 llvm_unreachable("VLA type in explicit captures.");
2259 if (Node->isInitCapture(C))
2260 PrintExpr(C->getCapturedVar()->getInit());
2264 if (Node->hasExplicitParameters()) {
2266 CXXMethodDecl *Method = Node->getCallOperator();
2268 for (auto P : Method->parameters()) {
2274 std::string ParamStr = P->getNameAsString();
2275 P->getOriginalType().print(OS, Policy, ParamStr);
2277 if (Method->isVariadic()) {
2284 if (Node->isMutable())
2287 const FunctionProtoType *Proto
2288 = Method->getType()->getAs<FunctionProtoType>();
2289 Proto->printExceptionSpecification(OS, Policy);
2291 // FIXME: Attributes
2293 // Print the trailing return type if it was specified in the source.
2294 if (Node->hasExplicitResultType()) {
2296 Proto->getReturnType().print(OS, Policy);
2301 CompoundStmt *Body = Node->getBody();
2306 void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) {
2307 if (TypeSourceInfo *TSInfo = Node->getTypeSourceInfo())
2308 TSInfo->getType().print(OS, Policy);
2310 Node->getType().print(OS, Policy);
2314 void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
2315 if (E->isGlobalNew())
2318 unsigned NumPlace = E->getNumPlacementArgs();
2319 if (NumPlace > 0 && !isa<CXXDefaultArgExpr>(E->getPlacementArg(0))) {
2321 PrintExpr(E->getPlacementArg(0));
2322 for (unsigned i = 1; i < NumPlace; ++i) {
2323 if (isa<CXXDefaultArgExpr>(E->getPlacementArg(i)))
2326 PrintExpr(E->getPlacementArg(i));
2330 if (E->isParenTypeId())
2333 if (Expr *Size = E->getArraySize()) {
2334 llvm::raw_string_ostream s(TypeS);
2336 Size->printPretty(s, Helper, Policy);
2339 E->getAllocatedType().print(OS, Policy, TypeS);
2340 if (E->isParenTypeId())
2343 CXXNewExpr::InitializationStyle InitStyle = E->getInitializationStyle();
2345 if (InitStyle == CXXNewExpr::CallInit)
2347 PrintExpr(E->getInitializer());
2348 if (InitStyle == CXXNewExpr::CallInit)
2353 void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
2354 if (E->isGlobalDelete())
2357 if (E->isArrayForm())
2359 PrintExpr(E->getArgument());
2362 void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
2363 PrintExpr(E->getBase());
2368 if (E->getQualifier())
2369 E->getQualifier()->print(OS, Policy);
2372 if (IdentifierInfo *II = E->getDestroyedTypeIdentifier())
2373 OS << II->getName();
2375 E->getDestroyedType().print(OS, Policy);
2378 void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
2379 if (E->isListInitialization() && !E->isStdInitListInitialization())
2382 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
2383 if (isa<CXXDefaultArgExpr>(E->getArg(i))) {
2384 // Don't print any defaulted arguments
2389 PrintExpr(E->getArg(i));
2392 if (E->isListInitialization() && !E->isStdInitListInitialization())
2396 void StmtPrinter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {
2397 // Parens are printed by the surrounding context.
2398 OS << "<forwarded>";
2401 void StmtPrinter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
2402 PrintExpr(E->getSubExpr());
2405 void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) {
2406 // Just forward to the subexpression.
2407 PrintExpr(E->getSubExpr());
2411 StmtPrinter::VisitCXXUnresolvedConstructExpr(
2412 CXXUnresolvedConstructExpr *Node) {
2413 Node->getTypeAsWritten().print(OS, Policy);
2415 for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(),
2416 ArgEnd = Node->arg_end();
2417 Arg != ArgEnd; ++Arg) {
2418 if (Arg != Node->arg_begin())
2425 void StmtPrinter::VisitCXXDependentScopeMemberExpr(
2426 CXXDependentScopeMemberExpr *Node) {
2427 if (!Node->isImplicitAccess()) {
2428 PrintExpr(Node->getBase());
2429 OS << (Node->isArrow() ? "->" : ".");
2431 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
2432 Qualifier->print(OS, Policy);
2433 if (Node->hasTemplateKeyword())
2435 OS << Node->getMemberNameInfo();
2436 if (Node->hasExplicitTemplateArgs())
2437 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2440 void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
2441 if (!Node->isImplicitAccess()) {
2442 PrintExpr(Node->getBase());
2443 OS << (Node->isArrow() ? "->" : ".");
2445 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
2446 Qualifier->print(OS, Policy);
2447 if (Node->hasTemplateKeyword())
2449 OS << Node->getMemberNameInfo();
2450 if (Node->hasExplicitTemplateArgs())
2451 printTemplateArgumentList(OS, Node->template_arguments(), Policy);
2454 static const char *getTypeTraitName(TypeTrait TT) {
2456 #define TYPE_TRAIT_1(Spelling, Name, Key) \
2457 case clang::UTT_##Name: return #Spelling;
2458 #define TYPE_TRAIT_2(Spelling, Name, Key) \
2459 case clang::BTT_##Name: return #Spelling;
2460 #define TYPE_TRAIT_N(Spelling, Name, Key) \
2461 case clang::TT_##Name: return #Spelling;
2462 #include "clang/Basic/TokenKinds.def"
2464 llvm_unreachable("Type trait not covered by switch");
2467 static const char *getTypeTraitName(ArrayTypeTrait ATT) {
2469 case ATT_ArrayRank: return "__array_rank";
2470 case ATT_ArrayExtent: return "__array_extent";
2472 llvm_unreachable("Array type trait not covered by switch");
2475 static const char *getExpressionTraitName(ExpressionTrait ET) {
2477 case ET_IsLValueExpr: return "__is_lvalue_expr";
2478 case ET_IsRValueExpr: return "__is_rvalue_expr";
2480 llvm_unreachable("Expression type trait not covered by switch");
2483 void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) {
2484 OS << getTypeTraitName(E->getTrait()) << "(";
2485 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
2488 E->getArg(I)->getType().print(OS, Policy);
2493 void StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
2494 OS << getTypeTraitName(E->getTrait()) << '(';
2495 E->getQueriedType().print(OS, Policy);
2499 void StmtPrinter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
2500 OS << getExpressionTraitName(E->getTrait()) << '(';
2501 PrintExpr(E->getQueriedExpression());
2505 void StmtPrinter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
2507 PrintExpr(E->getOperand());
2511 void StmtPrinter::VisitPackExpansionExpr(PackExpansionExpr *E) {
2512 PrintExpr(E->getPattern());
2516 void StmtPrinter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
2517 OS << "sizeof...(" << *E->getPack() << ")";
2520 void StmtPrinter::VisitSubstNonTypeTemplateParmPackExpr(
2521 SubstNonTypeTemplateParmPackExpr *Node) {
2522 OS << *Node->getParameterPack();
2525 void StmtPrinter::VisitSubstNonTypeTemplateParmExpr(
2526 SubstNonTypeTemplateParmExpr *Node) {
2527 Visit(Node->getReplacement());
2530 void StmtPrinter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
2531 OS << *E->getParameterPack();
2534 void StmtPrinter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *Node){
2535 PrintExpr(Node->GetTemporaryExpr());
2538 void StmtPrinter::VisitCXXFoldExpr(CXXFoldExpr *E) {
2541 PrintExpr(E->getLHS());
2542 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2546 OS << " " << BinaryOperator::getOpcodeStr(E->getOperator()) << " ";
2547 PrintExpr(E->getRHS());
2552 // C++ Coroutines TS
2554 void StmtPrinter::VisitCoroutineBodyStmt(CoroutineBodyStmt *S) {
2555 Visit(S->getBody());
2558 void StmtPrinter::VisitCoreturnStmt(CoreturnStmt *S) {
2560 if (S->getOperand()) {
2562 Visit(S->getOperand());
2567 void StmtPrinter::VisitCoawaitExpr(CoawaitExpr *S) {
2569 PrintExpr(S->getOperand());
2573 void StmtPrinter::VisitDependentCoawaitExpr(DependentCoawaitExpr *S) {
2575 PrintExpr(S->getOperand());
2579 void StmtPrinter::VisitCoyieldExpr(CoyieldExpr *S) {
2581 PrintExpr(S->getOperand());
2586 void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
2588 VisitStringLiteral(Node->getString());
2591 void StmtPrinter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
2593 Visit(E->getSubExpr());
2596 void StmtPrinter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
2598 ObjCArrayLiteral::child_range Ch = E->children();
2599 for (auto I = Ch.begin(), E = Ch.end(); I != E; ++I) {
2600 if (I != Ch.begin())
2607 void StmtPrinter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
2609 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
2613 ObjCDictionaryElement Element = E->getKeyValueElement(I);
2616 Visit(Element.Value);
2617 if (Element.isPackExpansion())
2623 void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
2625 Node->getEncodedType().print(OS, Policy);
2629 void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
2631 Node->getSelector().print(OS);
2635 void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
2636 OS << "@protocol(" << *Node->getProtocol() << ')';
2639 void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
2641 switch (Mess->getReceiverKind()) {
2642 case ObjCMessageExpr::Instance:
2643 PrintExpr(Mess->getInstanceReceiver());
2646 case ObjCMessageExpr::Class:
2647 Mess->getClassReceiver().print(OS, Policy);
2650 case ObjCMessageExpr::SuperInstance:
2651 case ObjCMessageExpr::SuperClass:
2657 Selector selector = Mess->getSelector();
2658 if (selector.isUnarySelector()) {
2659 OS << selector.getNameForSlot(0);
2661 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
2662 if (i < selector.getNumArgs()) {
2663 if (i > 0) OS << ' ';
2664 if (selector.getIdentifierInfoForSlot(i))
2665 OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';
2669 else OS << ", "; // Handle variadic methods.
2671 PrintExpr(Mess->getArg(i));
2677 void StmtPrinter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) {
2678 OS << (Node->getValue() ? "__objc_yes" : "__objc_no");
2682 StmtPrinter::VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
2683 PrintExpr(E->getSubExpr());
2687 StmtPrinter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
2688 OS << '(' << E->getBridgeKindName();
2689 E->getType().print(OS, Policy);
2691 PrintExpr(E->getSubExpr());
2694 void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
2695 BlockDecl *BD = Node->getBlockDecl();
2698 const FunctionType *AFT = Node->getFunctionType();
2700 if (isa<FunctionNoProtoType>(AFT)) {
2702 } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
2704 for (BlockDecl::param_iterator AI = BD->param_begin(),
2705 E = BD->param_end(); AI != E; ++AI) {
2706 if (AI != BD->param_begin()) OS << ", ";
2707 std::string ParamStr = (*AI)->getNameAsString();
2708 (*AI)->getType().print(OS, Policy, ParamStr);
2711 const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
2712 if (FT->isVariadic()) {
2713 if (!BD->param_empty()) OS << ", ";
2721 void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {
2722 PrintExpr(Node->getSourceExpr());
2725 void StmtPrinter::VisitTypoExpr(TypoExpr *Node) {
2726 // TODO: Print something reasonable for a TypoExpr, if necessary.
2727 llvm_unreachable("Cannot print TypoExpr nodes");
2730 void StmtPrinter::VisitAsTypeExpr(AsTypeExpr *Node) {
2731 OS << "__builtin_astype(";
2732 PrintExpr(Node->getSrcExpr());
2734 Node->getType().print(OS, Policy);
2738 //===----------------------------------------------------------------------===//
2739 // Stmt method implementations
2740 //===----------------------------------------------------------------------===//
2742 void Stmt::dumpPretty(const ASTContext &Context) const {
2743 printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts()));
2746 void Stmt::printPretty(raw_ostream &OS, PrinterHelper *Helper,
2747 const PrintingPolicy &Policy, unsigned Indentation,
2748 const ASTContext *Context) const {
2749 StmtPrinter P(OS, Helper, Policy, Indentation, Context);
2750 P.Visit(const_cast<Stmt*>(this));
2753 //===----------------------------------------------------------------------===//
2755 //===----------------------------------------------------------------------===//
2757 // Implement virtual destructor.
2758 PrinterHelper::~PrinterHelper() {}