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/StmtVisitor.h"
16 #include "clang/AST/Decl.h"
17 #include "clang/AST/DeclObjC.h"
18 #include "clang/AST/ExprCXX.h"
19 #include "clang/AST/PrettyPrinter.h"
20 #include "clang/Basic/IdentifierTable.h"
21 #include "llvm/Support/Compiler.h"
22 #include "llvm/Support/Streams.h"
24 using namespace clang;
26 //===----------------------------------------------------------------------===//
27 // StmtPrinter Visitor
28 //===----------------------------------------------------------------------===//
31 class VISIBILITY_HIDDEN StmtPrinter : public StmtVisitor<StmtPrinter> {
34 clang::PrinterHelper* Helper;
36 StmtPrinter(std::ostream &os, PrinterHelper* helper) :
37 OS(os), IndentLevel(0), Helper(helper) {}
39 void PrintStmt(Stmt *S, int SubIndent = 1) {
40 IndentLevel += SubIndent;
41 if (S && isa<Expr>(S)) {
42 // If this is an expr used in a stmt context, indent and newline it.
49 Indent() << "<<<NULL STATEMENT>>>\n";
51 IndentLevel -= SubIndent;
54 void PrintRawCompoundStmt(CompoundStmt *S);
55 void PrintRawDecl(Decl *D);
56 void PrintRawIfStmt(IfStmt *If);
58 void PrintExpr(Expr *E) {
65 std::ostream &Indent(int Delta = 0) const {
66 for (int i = 0, e = IndentLevel+Delta; i < e; ++i)
71 bool PrintOffsetOfDesignator(Expr *E);
72 void VisitUnaryOffsetOf(UnaryOperator *Node);
75 if (Helper && Helper->handledStmt(S,OS))
77 else StmtVisitor<StmtPrinter>::Visit(S);
80 void VisitStmt(Stmt *Node);
81 #define STMT(N, CLASS, PARENT) \
82 void Visit##CLASS(CLASS *Node);
83 #include "clang/AST/StmtNodes.def"
87 //===----------------------------------------------------------------------===//
88 // Stmt printing methods.
89 //===----------------------------------------------------------------------===//
91 void StmtPrinter::VisitStmt(Stmt *Node) {
92 Indent() << "<<unknown stmt type>>\n";
95 /// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and
96 /// with no newline after the }.
97 void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
99 for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end();
106 void StmtPrinter::PrintRawDecl(Decl *D) {
107 // FIXME: Need to complete/beautify this... this code simply shows the
108 // nodes are where they need to be.
109 if (TypedefDecl *localType = dyn_cast<TypedefDecl>(D)) {
110 OS << "typedef " << localType->getUnderlyingType().getAsString();
111 OS << " " << localType->getName();
112 } else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
113 // Emit storage class for vardecls.
114 if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
115 switch (V->getStorageClass()) {
116 default: assert(0 && "Unknown storage class!");
117 case VarDecl::None: break;
118 case VarDecl::Extern: OS << "extern "; break;
119 case VarDecl::Static: OS << "static "; break;
120 case VarDecl::Auto: OS << "auto "; break;
121 case VarDecl::Register: OS << "register "; break;
125 std::string Name = VD->getName();
126 VD->getType().getAsStringInternal(Name);
129 // If this is a vardecl with an initializer, emit it.
130 if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
133 PrintExpr(V->getInit());
136 } else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
137 // print a free standing tag decl (e.g. "struct x;").
138 OS << TD->getKindName();
140 if (const IdentifierInfo *II = TD->getIdentifier())
144 // FIXME: print tag bodies.
146 assert(0 && "Unexpected decl");
151 void StmtPrinter::VisitNullStmt(NullStmt *Node) {
155 void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
156 for (ScopedDecl *D = Node->getDecl(); D; D = D->getNextDeclarator()) {
163 void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
165 PrintRawCompoundStmt(Node);
169 void StmtPrinter::VisitCaseStmt(CaseStmt *Node) {
170 Indent(-1) << "case ";
171 PrintExpr(Node->getLHS());
172 if (Node->getRHS()) {
174 PrintExpr(Node->getRHS());
178 PrintStmt(Node->getSubStmt(), 0);
181 void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) {
182 Indent(-1) << "default:\n";
183 PrintStmt(Node->getSubStmt(), 0);
186 void StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
187 Indent(-1) << Node->getName() << ":\n";
188 PrintStmt(Node->getSubStmt(), 0);
191 void StmtPrinter::PrintRawIfStmt(IfStmt *If) {
193 PrintExpr(If->getCond());
195 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(If->getThen())) {
197 PrintRawCompoundStmt(CS);
198 OS << (If->getElse() ? ' ' : '\n');
201 PrintStmt(If->getThen());
202 if (If->getElse()) Indent();
205 if (Stmt *Else = If->getElse()) {
208 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Else)) {
210 PrintRawCompoundStmt(CS);
212 } else if (IfStmt *ElseIf = dyn_cast<IfStmt>(Else)) {
214 PrintRawIfStmt(ElseIf);
217 PrintStmt(If->getElse());
222 void StmtPrinter::VisitIfStmt(IfStmt *If) {
227 void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) {
228 Indent() << "switch (";
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::VisitSwitchCase(SwitchCase*) {
244 assert(0 && "SwitchCase is an abstract class");
247 void StmtPrinter::VisitWhileStmt(WhileStmt *Node) {
248 Indent() << "while (";
249 PrintExpr(Node->getCond());
251 PrintStmt(Node->getBody());
254 void StmtPrinter::VisitDoStmt(DoStmt *Node) {
256 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
257 PrintRawCompoundStmt(CS);
261 PrintStmt(Node->getBody());
266 PrintExpr(Node->getCond());
270 void StmtPrinter::VisitForStmt(ForStmt *Node) {
272 if (Node->getInit()) {
273 if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getInit()))
274 PrintRawDecl(DS->getDecl());
276 PrintExpr(cast<Expr>(Node->getInit()));
279 if (Node->getCond()) {
281 PrintExpr(Node->getCond());
284 if (Node->getInc()) {
286 PrintExpr(Node->getInc());
290 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
291 PrintRawCompoundStmt(CS);
295 PrintStmt(Node->getBody());
299 void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) {
301 if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getElement()))
302 PrintRawDecl(DS->getDecl());
304 PrintExpr(cast<Expr>(Node->getElement()));
306 PrintExpr(Node->getCollection());
309 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
310 PrintRawCompoundStmt(CS);
314 PrintStmt(Node->getBody());
318 void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
319 Indent() << "goto " << Node->getLabel()->getName() << ";\n";
322 void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
323 Indent() << "goto *";
324 PrintExpr(Node->getTarget());
328 void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
329 Indent() << "continue;\n";
332 void StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
333 Indent() << "break;\n";
337 void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
338 Indent() << "return";
339 if (Node->getRetValue()) {
341 PrintExpr(Node->getRetValue());
347 void StmtPrinter::VisitAsmStmt(AsmStmt *Node) {
350 if (Node->isVolatile())
354 VisitStringLiteral(Node->getAsmString());
357 if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 ||
358 Node->getNumClobbers() != 0)
361 for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) {
365 if (!Node->getOutputName(i).empty()) {
367 OS << Node->getOutputName(i);
371 VisitStringLiteral(Node->getOutputConstraint(i));
373 Visit(Node->getOutputExpr(i));
377 if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0)
380 for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) {
384 if (!Node->getInputName(i).empty()) {
386 OS << Node->getInputName(i);
390 VisitStringLiteral(Node->getInputConstraint(i));
392 Visit(Node->getInputExpr(i));
396 if (Node->getNumClobbers() != 0)
399 for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) {
403 VisitStringLiteral(Node->getClobber(i));
409 void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) {
411 if (CompoundStmt *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) {
412 PrintRawCompoundStmt(TS);
416 for (ObjCAtCatchStmt *catchStmt =
417 static_cast<ObjCAtCatchStmt *>(Node->getCatchStmts());
420 static_cast<ObjCAtCatchStmt *>(catchStmt->getNextCatchStmt())) {
421 Indent() << "@catch(";
422 if (catchStmt->getCatchParamStmt()) {
423 if (DeclStmt *DS = dyn_cast<DeclStmt>(catchStmt->getCatchParamStmt()))
424 PrintRawDecl(DS->getDecl());
427 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody()))
429 PrintRawCompoundStmt(CS);
434 if (ObjCAtFinallyStmt *FS =static_cast<ObjCAtFinallyStmt *>(
435 Node->getFinallyStmt())) {
436 Indent() << "@finally";
437 PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody()));
442 void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) {
445 void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) {
446 Indent() << "@catch (...) { /* todo */ } \n";
449 void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) {
450 Indent() << "@throw";
451 if (Node->getThrowExpr()) {
453 PrintExpr(Node->getThrowExpr());
458 void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) {
459 Indent() << "@synchronized (";
460 PrintExpr(Node->getSynchExpr());
462 PrintRawCompoundStmt(Node->getSynchBody());
466 //===----------------------------------------------------------------------===//
467 // Expr printing methods.
468 //===----------------------------------------------------------------------===//
470 void StmtPrinter::VisitExpr(Expr *Node) {
471 OS << "<<unknown expr type>>";
474 void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
475 OS << Node->getDecl()->getName();
478 void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
479 if (Node->getBase()) {
480 PrintExpr(Node->getBase());
481 OS << (Node->isArrow() ? "->" : ".");
483 OS << Node->getDecl()->getName();
486 void StmtPrinter::VisitPreDefinedExpr(PreDefinedExpr *Node) {
487 switch (Node->getIdentType()) {
489 assert(0 && "unknown case");
490 case PreDefinedExpr::Func:
493 case PreDefinedExpr::Function:
494 OS << "__FUNCTION__";
496 case PreDefinedExpr::PrettyFunction:
497 OS << "__PRETTY_FUNCTION__";
502 void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
503 // FIXME should print an L for wchar_t constants
504 unsigned value = Node->getValue();
513 // TODO: K&R: the meaning of '\\a' is different in traditional C
519 // Nonstandard escape sequence.
539 if (value < 256 && isprint(value)) {
540 OS << "'" << (char)value << "'";
541 } else if (value < 256) {
542 OS << "'\\x" << std::hex << value << std::dec << "'";
544 // FIXME what to really do here?
550 void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
551 bool isSigned = Node->getType()->isSignedIntegerType();
552 OS << Node->getValue().toString(10, isSigned);
554 // Emit suffixes. Integer literals are always a builtin integer type.
555 switch (cast<BuiltinType>(Node->getType().getCanonicalType())->getKind()) {
556 default: assert(0 && "Unexpected type for integer literal!");
557 case BuiltinType::Int: break; // no suffix.
558 case BuiltinType::UInt: OS << 'U'; break;
559 case BuiltinType::Long: OS << 'L'; break;
560 case BuiltinType::ULong: OS << "UL"; break;
561 case BuiltinType::LongLong: OS << "LL"; break;
562 case BuiltinType::ULongLong: OS << "ULL"; break;
565 void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
566 // FIXME: print value more precisely.
567 OS << Node->getValueAsDouble();
570 void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
571 PrintExpr(Node->getSubExpr());
575 void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
576 if (Str->isWide()) OS << 'L';
579 // FIXME: this doesn't print wstrings right.
580 for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) {
581 switch (Str->getStrData()[i]) {
582 default: OS << Str->getStrData()[i]; break;
583 // Handle some common ones to make dumps prettier.
584 case '\\': OS << "\\\\"; break;
585 case '"': OS << "\\\""; break;
586 case '\n': OS << "\\n"; break;
587 case '\t': OS << "\\t"; break;
588 case '\a': OS << "\\a"; break;
589 case '\b': OS << "\\b"; break;
594 void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
596 PrintExpr(Node->getSubExpr());
599 void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
600 if (!Node->isPostfix()) {
601 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
603 // Print a space if this is an "identifier operator" like sizeof or __real.
604 switch (Node->getOpcode()) {
606 case UnaryOperator::SizeOf:
607 case UnaryOperator::AlignOf:
608 case UnaryOperator::Real:
609 case UnaryOperator::Imag:
610 case UnaryOperator::Extension:
615 PrintExpr(Node->getSubExpr());
617 if (Node->isPostfix())
618 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
621 bool StmtPrinter::PrintOffsetOfDesignator(Expr *E) {
622 if (isa<CompoundLiteralExpr>(E)) {
623 // Base case, print the type and comma.
624 OS << E->getType().getAsString() << ", ";
626 } else if (ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
627 PrintOffsetOfDesignator(ASE->getLHS());
629 PrintExpr(ASE->getRHS());
633 MemberExpr *ME = cast<MemberExpr>(E);
634 bool IsFirst = PrintOffsetOfDesignator(ME->getBase());
635 OS << (IsFirst ? "" : ".") << ME->getMemberDecl()->getName();
640 void StmtPrinter::VisitUnaryOffsetOf(UnaryOperator *Node) {
641 OS << "__builtin_offsetof(";
642 PrintOffsetOfDesignator(Node->getSubExpr());
646 void StmtPrinter::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr *Node) {
647 OS << (Node->isSizeOf() ? "sizeof(" : "__alignof(");
648 OS << Node->getArgumentType().getAsString() << ")";
650 void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
651 PrintExpr(Node->getLHS());
653 PrintExpr(Node->getRHS());
657 void StmtPrinter::VisitCallExpr(CallExpr *Call) {
658 PrintExpr(Call->getCallee());
660 for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
662 PrintExpr(Call->getArg(i));
666 void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
667 PrintExpr(Node->getBase());
668 OS << (Node->isArrow() ? "->" : ".");
670 FieldDecl *Field = Node->getMemberDecl();
671 assert(Field && "MemberExpr should alway reference a field!");
672 OS << Field->getName();
674 void StmtPrinter::VisitOCUVectorElementExpr(OCUVectorElementExpr *Node) {
675 PrintExpr(Node->getBase());
677 OS << Node->getAccessor().getName();
679 void StmtPrinter::VisitCastExpr(CastExpr *Node) {
680 OS << "(" << Node->getType().getAsString() << ")";
681 PrintExpr(Node->getSubExpr());
683 void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
684 OS << "(" << Node->getType().getAsString() << ")";
685 PrintExpr(Node->getInitializer());
687 void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
688 // No need to print anything, simply forward to the sub expression.
689 PrintExpr(Node->getSubExpr());
691 void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
692 PrintExpr(Node->getLHS());
693 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
694 PrintExpr(Node->getRHS());
696 void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
697 PrintExpr(Node->getLHS());
698 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
699 PrintExpr(Node->getRHS());
701 void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
702 PrintExpr(Node->getCond());
704 if (Node->getLHS()) {
706 PrintExpr(Node->getLHS());
709 else { // Handle GCC extention where LHS can be NULL.
713 PrintExpr(Node->getRHS());
718 void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
719 OS << "&&" << Node->getLabel()->getName();
722 void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
724 PrintRawCompoundStmt(E->getSubStmt());
728 void StmtPrinter::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
729 OS << "__builtin_types_compatible_p(";
730 OS << Node->getArgType1().getAsString() << ",";
731 OS << Node->getArgType2().getAsString() << ")";
734 void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
735 OS << "__builtin_choose_expr(";
736 PrintExpr(Node->getCond());
738 PrintExpr(Node->getLHS());
740 PrintExpr(Node->getRHS());
744 void StmtPrinter::VisitOverloadExpr(OverloadExpr *Node) {
745 OS << "__builtin_overload(";
746 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
748 PrintExpr(Node->getExpr(i));
753 void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
755 for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
757 PrintExpr(Node->getInit(i));
762 void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
764 PrintExpr(Node->getSubExpr());
766 OS << Node->getType().getAsString();
772 void StmtPrinter::VisitCXXCastExpr(CXXCastExpr *Node) {
773 OS << CXXCastExpr::getOpcodeStr(Node->getOpcode()) << '<';
774 OS << Node->getDestType().getAsString() << ">(";
775 PrintExpr(Node->getSubExpr());
779 void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
780 OS << (Node->getValue() ? "true" : "false");
783 void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
784 if (Node->getSubExpr() == 0)
788 PrintExpr(Node->getSubExpr());
794 void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
796 VisitStringLiteral(Node->getString());
799 void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
800 OS << "@encode(" << Node->getEncodedType().getAsString() << ")";
803 void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
804 OS << "@selector(" << Node->getSelector().getName() << ")";
807 void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
808 OS << "@protocol(" << Node->getProtocol()->getName() << ")";
811 void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
813 Expr *receiver = Mess->getReceiver();
814 if (receiver) PrintExpr(receiver);
815 else OS << Mess->getClassName()->getName();
816 Selector &selector = Mess->getSelector();
817 if (selector.isUnarySelector()) {
818 OS << " " << selector.getIdentifierInfoForSlot(0)->getName();
820 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
821 if (selector.getIdentifierInfoForSlot(i))
822 OS << selector.getIdentifierInfoForSlot(i)->getName() << ":";
825 PrintExpr(Mess->getArg(i));
831 //===----------------------------------------------------------------------===//
832 // Stmt method implementations
833 //===----------------------------------------------------------------------===//
835 void Stmt::dumpPretty() const {
836 printPretty(*llvm::cerr.stream());
839 void Stmt::printPretty(std::ostream &OS, PrinterHelper* Helper) const {
845 StmtPrinter P(OS, Helper);
846 P.Visit(const_cast<Stmt*>(this));
849 //===----------------------------------------------------------------------===//
851 //===----------------------------------------------------------------------===//
853 // Implement virtual destructor.
854 PrinterHelper::~PrinterHelper() {}