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/DeclCXX.h"
17 #include "clang/AST/DeclObjC.h"
18 #include "clang/AST/PrettyPrinter.h"
19 #include "llvm/Support/Format.h"
20 using namespace clang;
22 //===----------------------------------------------------------------------===//
23 // StmtPrinter Visitor
24 //===----------------------------------------------------------------------===//
27 class StmtPrinter : public StmtVisitor<StmtPrinter> {
28 llvm::raw_ostream &OS;
31 clang::PrinterHelper* Helper;
32 PrintingPolicy Policy;
35 StmtPrinter(llvm::raw_ostream &os, ASTContext &C, PrinterHelper* helper,
36 const PrintingPolicy &Policy,
37 unsigned Indentation = 0)
38 : OS(os), Context(C), IndentLevel(Indentation), Helper(helper),
41 void PrintStmt(Stmt *S) {
42 PrintStmt(S, Policy.Indentation);
45 void PrintStmt(Stmt *S, int SubIndent) {
46 IndentLevel += SubIndent;
47 if (S && isa<Expr>(S)) {
48 // If this is an expr used in a stmt context, indent and newline it.
55 Indent() << "<<<NULL STATEMENT>>>\n";
57 IndentLevel -= SubIndent;
60 void PrintRawCompoundStmt(CompoundStmt *S);
61 void PrintRawDecl(Decl *D);
62 void PrintRawDeclStmt(DeclStmt *S);
63 void PrintRawIfStmt(IfStmt *If);
64 void PrintRawCXXCatchStmt(CXXCatchStmt *Catch);
66 void PrintExpr(Expr *E) {
73 llvm::raw_ostream &Indent(int Delta = 0) {
74 for (int i = 0, e = IndentLevel+Delta; i < e; ++i)
79 bool PrintOffsetOfDesignator(Expr *E);
80 void VisitUnaryOffsetOf(UnaryOperator *Node);
83 if (Helper && Helper->handledStmt(S,OS))
85 else StmtVisitor<StmtPrinter>::Visit(S);
88 void VisitStmt(Stmt *Node);
89 #define STMT(CLASS, PARENT) \
90 void Visit##CLASS(CLASS *Node);
91 #include "clang/AST/StmtNodes.def"
95 //===----------------------------------------------------------------------===//
96 // Stmt printing methods.
97 //===----------------------------------------------------------------------===//
99 void StmtPrinter::VisitStmt(Stmt *Node) {
100 Indent() << "<<unknown stmt type>>\n";
103 /// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and
104 /// with no newline after the }.
105 void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
107 for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end();
114 void StmtPrinter::PrintRawDecl(Decl *D) {
115 D->print(OS, Policy, IndentLevel);
118 void StmtPrinter::PrintRawDeclStmt(DeclStmt *S) {
119 DeclStmt::decl_iterator Begin = S->decl_begin(), End = S->decl_end();
120 llvm::SmallVector<Decl*, 2> Decls;
121 for ( ; Begin != End; ++Begin)
122 Decls.push_back(*Begin);
124 Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel);
127 void StmtPrinter::VisitNullStmt(NullStmt *Node) {
131 void StmtPrinter::VisitDeclStmt(DeclStmt *Node) {
133 PrintRawDeclStmt(Node);
137 void StmtPrinter::VisitCompoundStmt(CompoundStmt *Node) {
139 PrintRawCompoundStmt(Node);
143 void StmtPrinter::VisitCaseStmt(CaseStmt *Node) {
144 Indent(-1) << "case ";
145 PrintExpr(Node->getLHS());
146 if (Node->getRHS()) {
148 PrintExpr(Node->getRHS());
152 PrintStmt(Node->getSubStmt(), 0);
155 void StmtPrinter::VisitDefaultStmt(DefaultStmt *Node) {
156 Indent(-1) << "default:\n";
157 PrintStmt(Node->getSubStmt(), 0);
160 void StmtPrinter::VisitLabelStmt(LabelStmt *Node) {
161 Indent(-1) << Node->getName() << ":\n";
162 PrintStmt(Node->getSubStmt(), 0);
165 void StmtPrinter::PrintRawIfStmt(IfStmt *If) {
167 PrintExpr(If->getCond());
170 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(If->getThen())) {
172 PrintRawCompoundStmt(CS);
173 OS << (If->getElse() ? ' ' : '\n');
176 PrintStmt(If->getThen());
177 if (If->getElse()) Indent();
180 if (Stmt *Else = If->getElse()) {
183 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Else)) {
185 PrintRawCompoundStmt(CS);
187 } else if (IfStmt *ElseIf = dyn_cast<IfStmt>(Else)) {
189 PrintRawIfStmt(ElseIf);
192 PrintStmt(If->getElse());
197 void StmtPrinter::VisitIfStmt(IfStmt *If) {
202 void StmtPrinter::VisitSwitchStmt(SwitchStmt *Node) {
203 Indent() << "switch (";
204 PrintExpr(Node->getCond());
207 // Pretty print compoundstmt bodies (very common).
208 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
210 PrintRawCompoundStmt(CS);
214 PrintStmt(Node->getBody());
218 void StmtPrinter::VisitSwitchCase(SwitchCase*) {
219 assert(0 && "SwitchCase is an abstract class");
222 void StmtPrinter::VisitWhileStmt(WhileStmt *Node) {
223 Indent() << "while (";
224 PrintExpr(Node->getCond());
226 PrintStmt(Node->getBody());
229 void StmtPrinter::VisitDoStmt(DoStmt *Node) {
231 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
232 PrintRawCompoundStmt(CS);
236 PrintStmt(Node->getBody());
241 PrintExpr(Node->getCond());
245 void StmtPrinter::VisitForStmt(ForStmt *Node) {
247 if (Node->getInit()) {
248 if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getInit()))
249 PrintRawDeclStmt(DS);
251 PrintExpr(cast<Expr>(Node->getInit()));
254 if (Node->getCond()) {
256 PrintExpr(Node->getCond());
259 if (Node->getInc()) {
261 PrintExpr(Node->getInc());
265 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
266 PrintRawCompoundStmt(CS);
270 PrintStmt(Node->getBody());
274 void StmtPrinter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *Node) {
276 if (DeclStmt *DS = dyn_cast<DeclStmt>(Node->getElement()))
277 PrintRawDeclStmt(DS);
279 PrintExpr(cast<Expr>(Node->getElement()));
281 PrintExpr(Node->getCollection());
284 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Node->getBody())) {
285 PrintRawCompoundStmt(CS);
289 PrintStmt(Node->getBody());
293 void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
294 Indent() << "goto " << Node->getLabel()->getName() << ";\n";
297 void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
298 Indent() << "goto *";
299 PrintExpr(Node->getTarget());
303 void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
304 Indent() << "continue;\n";
307 void StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
308 Indent() << "break;\n";
312 void StmtPrinter::VisitReturnStmt(ReturnStmt *Node) {
313 Indent() << "return";
314 if (Node->getRetValue()) {
316 PrintExpr(Node->getRetValue());
322 void StmtPrinter::VisitAsmStmt(AsmStmt *Node) {
325 if (Node->isVolatile())
329 VisitStringLiteral(Node->getAsmString());
332 if (Node->getNumOutputs() != 0 || Node->getNumInputs() != 0 ||
333 Node->getNumClobbers() != 0)
336 for (unsigned i = 0, e = Node->getNumOutputs(); i != e; ++i) {
340 if (!Node->getOutputName(i).empty()) {
342 OS << Node->getOutputName(i);
346 VisitStringLiteral(Node->getOutputConstraintLiteral(i));
348 Visit(Node->getOutputExpr(i));
352 if (Node->getNumInputs() != 0 || Node->getNumClobbers() != 0)
355 for (unsigned i = 0, e = Node->getNumInputs(); i != e; ++i) {
359 if (!Node->getInputName(i).empty()) {
361 OS << Node->getInputName(i);
365 VisitStringLiteral(Node->getInputConstraintLiteral(i));
367 Visit(Node->getInputExpr(i));
371 if (Node->getNumClobbers() != 0)
374 for (unsigned i = 0, e = Node->getNumClobbers(); i != e; ++i) {
378 VisitStringLiteral(Node->getClobber(i));
384 void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) {
386 if (CompoundStmt *TS = dyn_cast<CompoundStmt>(Node->getTryBody())) {
387 PrintRawCompoundStmt(TS);
391 for (ObjCAtCatchStmt *catchStmt =
392 static_cast<ObjCAtCatchStmt *>(Node->getCatchStmts());
395 static_cast<ObjCAtCatchStmt *>(catchStmt->getNextCatchStmt())) {
396 Indent() << "@catch(";
397 if (catchStmt->getCatchParamDecl()) {
398 if (Decl *DS = catchStmt->getCatchParamDecl())
402 if (CompoundStmt *CS = dyn_cast<CompoundStmt>(catchStmt->getCatchBody())) {
403 PrintRawCompoundStmt(CS);
408 if (ObjCAtFinallyStmt *FS = static_cast<ObjCAtFinallyStmt *>(
409 Node->getFinallyStmt())) {
410 Indent() << "@finally";
411 PrintRawCompoundStmt(dyn_cast<CompoundStmt>(FS->getFinallyBody()));
416 void StmtPrinter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Node) {
419 void StmtPrinter::VisitObjCAtCatchStmt (ObjCAtCatchStmt *Node) {
420 Indent() << "@catch (...) { /* todo */ } \n";
423 void StmtPrinter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *Node) {
424 Indent() << "@throw";
425 if (Node->getThrowExpr()) {
427 PrintExpr(Node->getThrowExpr());
432 void StmtPrinter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Node) {
433 Indent() << "@synchronized (";
434 PrintExpr(Node->getSynchExpr());
436 PrintRawCompoundStmt(Node->getSynchBody());
440 void StmtPrinter::PrintRawCXXCatchStmt(CXXCatchStmt *Node) {
442 if (Decl *ExDecl = Node->getExceptionDecl())
443 PrintRawDecl(ExDecl);
447 PrintRawCompoundStmt(cast<CompoundStmt>(Node->getHandlerBlock()));
450 void StmtPrinter::VisitCXXCatchStmt(CXXCatchStmt *Node) {
452 PrintRawCXXCatchStmt(Node);
456 void StmtPrinter::VisitCXXTryStmt(CXXTryStmt *Node) {
458 PrintRawCompoundStmt(Node->getTryBlock());
459 for (unsigned i = 0, e = Node->getNumHandlers(); i < e; ++i) {
461 PrintRawCXXCatchStmt(Node->getHandler(i));
466 //===----------------------------------------------------------------------===//
467 // Expr printing methods.
468 //===----------------------------------------------------------------------===//
470 void StmtPrinter::VisitExpr(Expr *Node) {
471 OS << "<<unknown expr type>>";
474 void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
475 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
476 Qualifier->print(OS, Policy);
477 OS << Node->getDecl()->getNameAsString();
478 if (Node->hasExplicitTemplateArgumentList())
479 OS << TemplateSpecializationType::PrintTemplateArgumentList(
480 Node->getTemplateArgs(),
481 Node->getNumTemplateArgs(),
485 void StmtPrinter::VisitDependentScopeDeclRefExpr(
486 DependentScopeDeclRefExpr *Node) {
487 Node->getQualifier()->print(OS, Policy);
488 OS << Node->getDeclName().getAsString();
489 if (Node->hasExplicitTemplateArgs())
490 OS << TemplateSpecializationType::PrintTemplateArgumentList(
491 Node->getTemplateArgs(),
492 Node->getNumTemplateArgs(),
496 void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
497 if (Node->getQualifier())
498 Node->getQualifier()->print(OS, Policy);
499 OS << Node->getName().getAsString();
500 if (Node->hasExplicitTemplateArgs())
501 OS << TemplateSpecializationType::PrintTemplateArgumentList(
502 Node->getTemplateArgs(),
503 Node->getNumTemplateArgs(),
507 void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
508 if (Node->getBase()) {
509 PrintExpr(Node->getBase());
510 OS << (Node->isArrow() ? "->" : ".");
512 OS << Node->getDecl()->getNameAsString();
515 void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
516 if (Node->getBase()) {
517 PrintExpr(Node->getBase());
520 OS << Node->getProperty()->getNameAsCString();
523 void StmtPrinter::VisitObjCImplicitSetterGetterRefExpr(
524 ObjCImplicitSetterGetterRefExpr *Node) {
525 if (Node->getBase()) {
526 PrintExpr(Node->getBase());
529 if (Node->getGetterMethod())
530 OS << Node->getGetterMethod()->getNameAsString();
534 void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
535 switch (Node->getIdentType()) {
537 assert(0 && "unknown case");
538 case PredefinedExpr::Func:
541 case PredefinedExpr::Function:
542 OS << "__FUNCTION__";
544 case PredefinedExpr::PrettyFunction:
545 OS << "__PRETTY_FUNCTION__";
550 void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
551 unsigned value = Node->getValue();
562 // TODO: K&R: the meaning of '\\a' is different in traditional C
568 // Nonstandard escape sequence.
588 if (value < 256 && isprint(value)) {
589 OS << "'" << (char)value << "'";
590 } else if (value < 256) {
591 OS << "'\\x" << llvm::format("%x", value) << "'";
593 // FIXME what to really do here?
599 void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
600 bool isSigned = Node->getType()->isSignedIntegerType();
601 OS << Node->getValue().toString(10, isSigned);
603 // Emit suffixes. Integer literals are always a builtin integer type.
604 switch (Node->getType()->getAs<BuiltinType>()->getKind()) {
605 default: assert(0 && "Unexpected type for integer literal!");
606 case BuiltinType::Int: break; // no suffix.
607 case BuiltinType::UInt: OS << 'U'; break;
608 case BuiltinType::Long: OS << 'L'; break;
609 case BuiltinType::ULong: OS << "UL"; break;
610 case BuiltinType::LongLong: OS << "LL"; break;
611 case BuiltinType::ULongLong: OS << "ULL"; break;
614 void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
615 // FIXME: print value more precisely.
616 OS << Node->getValueAsApproximateDouble();
619 void StmtPrinter::VisitImaginaryLiteral(ImaginaryLiteral *Node) {
620 PrintExpr(Node->getSubExpr());
624 void StmtPrinter::VisitStringLiteral(StringLiteral *Str) {
625 if (Str->isWide()) OS << 'L';
628 // FIXME: this doesn't print wstrings right.
629 for (unsigned i = 0, e = Str->getByteLength(); i != e; ++i) {
630 unsigned char Char = Str->getStrData()[i];
636 else // Output anything hard as an octal escape.
638 << (char)('0'+ ((Char >> 6) & 7))
639 << (char)('0'+ ((Char >> 3) & 7))
640 << (char)('0'+ ((Char >> 0) & 7));
642 // Handle some common non-printable cases to make dumps prettier.
643 case '\\': OS << "\\\\"; break;
644 case '"': OS << "\\\""; break;
645 case '\n': OS << "\\n"; break;
646 case '\t': OS << "\\t"; break;
647 case '\a': OS << "\\a"; break;
648 case '\b': OS << "\\b"; break;
653 void StmtPrinter::VisitParenExpr(ParenExpr *Node) {
655 PrintExpr(Node->getSubExpr());
658 void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
659 if (!Node->isPostfix()) {
660 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
662 // Print a space if this is an "identifier operator" like __real, or if
663 // it might be concatenated incorrectly like '+'.
664 switch (Node->getOpcode()) {
666 case UnaryOperator::Real:
667 case UnaryOperator::Imag:
668 case UnaryOperator::Extension:
671 case UnaryOperator::Plus:
672 case UnaryOperator::Minus:
673 if (isa<UnaryOperator>(Node->getSubExpr()))
678 PrintExpr(Node->getSubExpr());
680 if (Node->isPostfix())
681 OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
684 bool StmtPrinter::PrintOffsetOfDesignator(Expr *E) {
685 if (isa<UnaryOperator>(E)) {
686 // Base case, print the type and comma.
687 OS << E->getType().getAsString() << ", ";
689 } else if (ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(E)) {
690 PrintOffsetOfDesignator(ASE->getLHS());
692 PrintExpr(ASE->getRHS());
696 MemberExpr *ME = cast<MemberExpr>(E);
697 bool IsFirst = PrintOffsetOfDesignator(ME->getBase());
698 OS << (IsFirst ? "" : ".") << ME->getMemberDecl()->getNameAsString();
703 void StmtPrinter::VisitUnaryOffsetOf(UnaryOperator *Node) {
704 OS << "__builtin_offsetof(";
705 PrintOffsetOfDesignator(Node->getSubExpr());
709 void StmtPrinter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
710 OS << (Node->isSizeOf() ? "sizeof" : "__alignof");
711 if (Node->isArgumentType())
712 OS << "(" << Node->getArgumentType().getAsString() << ")";
715 PrintExpr(Node->getArgumentExpr());
718 void StmtPrinter::VisitArraySubscriptExpr(ArraySubscriptExpr *Node) {
719 PrintExpr(Node->getLHS());
721 PrintExpr(Node->getRHS());
725 void StmtPrinter::VisitCallExpr(CallExpr *Call) {
726 PrintExpr(Call->getCallee());
728 for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) {
729 if (isa<CXXDefaultArgExpr>(Call->getArg(i))) {
730 // Don't print any defaulted arguments
735 PrintExpr(Call->getArg(i));
739 void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
740 // FIXME: Suppress printing implicit bases (like "this")
741 PrintExpr(Node->getBase());
742 if (FieldDecl *FD = dyn_cast<FieldDecl>(Node->getMemberDecl()))
743 if (FD->isAnonymousStructOrUnion())
745 OS << (Node->isArrow() ? "->" : ".");
746 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
747 Qualifier->print(OS, Policy);
749 OS << Node->getMemberDecl()->getNameAsString();
751 if (Node->hasExplicitTemplateArgumentList())
752 OS << TemplateSpecializationType::PrintTemplateArgumentList(
753 Node->getTemplateArgs(),
754 Node->getNumTemplateArgs(),
757 void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
758 PrintExpr(Node->getBase());
759 OS << (Node->isArrow() ? "->isa" : ".isa");
762 void StmtPrinter::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
763 PrintExpr(Node->getBase());
765 OS << Node->getAccessor().getName();
767 void StmtPrinter::VisitCastExpr(CastExpr *) {
768 assert(0 && "CastExpr is an abstract class");
770 void StmtPrinter::VisitExplicitCastExpr(ExplicitCastExpr *) {
771 assert(0 && "ExplicitCastExpr is an abstract class");
773 void StmtPrinter::VisitCStyleCastExpr(CStyleCastExpr *Node) {
774 OS << "(" << Node->getType().getAsString() << ")";
775 PrintExpr(Node->getSubExpr());
777 void StmtPrinter::VisitCompoundLiteralExpr(CompoundLiteralExpr *Node) {
778 OS << "(" << Node->getType().getAsString() << ")";
779 PrintExpr(Node->getInitializer());
781 void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
782 // No need to print anything, simply forward to the sub expression.
783 PrintExpr(Node->getSubExpr());
785 void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
786 PrintExpr(Node->getLHS());
787 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
788 PrintExpr(Node->getRHS());
790 void StmtPrinter::VisitCompoundAssignOperator(CompoundAssignOperator *Node) {
791 PrintExpr(Node->getLHS());
792 OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
793 PrintExpr(Node->getRHS());
795 void StmtPrinter::VisitConditionalOperator(ConditionalOperator *Node) {
796 PrintExpr(Node->getCond());
798 if (Node->getLHS()) {
800 PrintExpr(Node->getLHS());
803 else { // Handle GCC extension where LHS can be NULL.
807 PrintExpr(Node->getRHS());
812 void StmtPrinter::VisitAddrLabelExpr(AddrLabelExpr *Node) {
813 OS << "&&" << Node->getLabel()->getName();
816 void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
818 PrintRawCompoundStmt(E->getSubStmt());
822 void StmtPrinter::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
823 OS << "__builtin_types_compatible_p(";
824 OS << Node->getArgType1().getAsString() << ",";
825 OS << Node->getArgType2().getAsString() << ")";
828 void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
829 OS << "__builtin_choose_expr(";
830 PrintExpr(Node->getCond());
832 PrintExpr(Node->getLHS());
834 PrintExpr(Node->getRHS());
838 void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
842 void StmtPrinter::VisitShuffleVectorExpr(ShuffleVectorExpr *Node) {
843 OS << "__builtin_shufflevector(";
844 for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
846 PrintExpr(Node->getExpr(i));
851 void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
852 if (Node->getSyntacticForm()) {
853 Visit(Node->getSyntacticForm());
858 for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
860 if (Node->getInit(i))
861 PrintExpr(Node->getInit(i));
868 void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
870 for (unsigned i = 0, e = Node->getNumExprs(); i != e; ++i) {
872 PrintExpr(Node->getExpr(i));
877 void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
878 for (DesignatedInitExpr::designators_iterator D = Node->designators_begin(),
879 DEnd = Node->designators_end();
881 if (D->isFieldDesignator()) {
882 if (D->getDotLoc().isInvalid())
883 OS << D->getFieldName()->getName() << ":";
885 OS << "." << D->getFieldName()->getName();
888 if (D->isArrayDesignator()) {
889 PrintExpr(Node->getArrayIndex(*D));
891 PrintExpr(Node->getArrayRangeStart(*D));
893 PrintExpr(Node->getArrayRangeEnd(*D));
900 PrintExpr(Node->getInit());
903 void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
904 if (Policy.LangOpts.CPlusPlus)
905 OS << "/*implicit*/" << Node->getType().getAsString(Policy) << "()";
907 OS << "/*implicit*/(" << Node->getType().getAsString(Policy) << ")";
908 if (Node->getType()->isRecordType())
915 void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
916 OS << "__builtin_va_arg(";
917 PrintExpr(Node->getSubExpr());
919 OS << Node->getType().getAsString();
924 void StmtPrinter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
925 const char *OpStrings[NUM_OVERLOADED_OPERATORS] = {
927 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
929 #include "clang/Basic/OperatorKinds.def"
932 OverloadedOperatorKind Kind = Node->getOperator();
933 if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
934 if (Node->getNumArgs() == 1) {
935 OS << OpStrings[Kind] << ' ';
936 PrintExpr(Node->getArg(0));
938 PrintExpr(Node->getArg(0));
939 OS << ' ' << OpStrings[Kind];
941 } else if (Kind == OO_Call) {
942 PrintExpr(Node->getArg(0));
944 for (unsigned ArgIdx = 1; ArgIdx < Node->getNumArgs(); ++ArgIdx) {
947 if (!isa<CXXDefaultArgExpr>(Node->getArg(ArgIdx)))
948 PrintExpr(Node->getArg(ArgIdx));
951 } else if (Kind == OO_Subscript) {
952 PrintExpr(Node->getArg(0));
954 PrintExpr(Node->getArg(1));
956 } else if (Node->getNumArgs() == 1) {
957 OS << OpStrings[Kind] << ' ';
958 PrintExpr(Node->getArg(0));
959 } else if (Node->getNumArgs() == 2) {
960 PrintExpr(Node->getArg(0));
961 OS << ' ' << OpStrings[Kind] << ' ';
962 PrintExpr(Node->getArg(1));
964 assert(false && "unknown overloaded operator");
968 void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
969 VisitCallExpr(cast<CallExpr>(Node));
972 void StmtPrinter::VisitCXXNamedCastExpr(CXXNamedCastExpr *Node) {
973 OS << Node->getCastName() << '<';
974 OS << Node->getTypeAsWritten().getAsString() << ">(";
975 PrintExpr(Node->getSubExpr());
979 void StmtPrinter::VisitCXXStaticCastExpr(CXXStaticCastExpr *Node) {
980 VisitCXXNamedCastExpr(Node);
983 void StmtPrinter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *Node) {
984 VisitCXXNamedCastExpr(Node);
987 void StmtPrinter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *Node) {
988 VisitCXXNamedCastExpr(Node);
991 void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) {
992 VisitCXXNamedCastExpr(Node);
995 void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
997 if (Node->isTypeOperand()) {
998 OS << Node->getTypeOperand().getAsString();
1000 PrintExpr(Node->getExprOperand());
1005 void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
1006 OS << (Node->getValue() ? "true" : "false");
1009 void StmtPrinter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *Node) {
1013 void StmtPrinter::VisitCXXThisExpr(CXXThisExpr *Node) {
1017 void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
1018 if (Node->getSubExpr() == 0)
1022 PrintExpr(Node->getSubExpr());
1026 void StmtPrinter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *Node) {
1027 // Nothing to print: we picked up the default argument
1030 void StmtPrinter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *Node) {
1031 OS << Node->getType().getAsString();
1033 PrintExpr(Node->getSubExpr());
1037 void StmtPrinter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) {
1038 PrintExpr(Node->getSubExpr());
1041 void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
1042 OS << Node->getType().getAsString();
1044 for (CXXTemporaryObjectExpr::arg_iterator Arg = Node->arg_begin(),
1045 ArgEnd = Node->arg_end();
1046 Arg != ArgEnd; ++Arg) {
1047 if (Arg != Node->arg_begin())
1054 void StmtPrinter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *Node) {
1055 OS << Node->getType().getAsString() << "()";
1058 void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) {
1059 if (E->isGlobalNew())
1062 unsigned NumPlace = E->getNumPlacementArgs();
1065 PrintExpr(E->getPlacementArg(0));
1066 for (unsigned i = 1; i < NumPlace; ++i) {
1068 PrintExpr(E->getPlacementArg(i));
1072 if (E->isParenTypeId())
1075 if (Expr *Size = E->getArraySize()) {
1076 llvm::raw_string_ostream s(TypeS);
1077 Size->printPretty(s, Context, Helper, Policy);
1079 TypeS = "[" + TypeS + "]";
1081 E->getAllocatedType().getAsStringInternal(TypeS, Policy);
1083 if (E->isParenTypeId())
1086 if (E->hasInitializer()) {
1088 unsigned NumCons = E->getNumConstructorArgs();
1090 PrintExpr(E->getConstructorArg(0));
1091 for (unsigned i = 1; i < NumCons; ++i) {
1093 PrintExpr(E->getConstructorArg(i));
1100 void StmtPrinter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
1101 if (E->isGlobalDelete())
1104 if (E->isArrayForm())
1106 PrintExpr(E->getArgument());
1109 void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1110 PrintExpr(E->getBase());
1115 if (E->getQualifier())
1116 E->getQualifier()->print(OS, Policy);
1119 E->getDestroyedType().getAsStringInternal(TypeS, Policy);
1123 void StmtPrinter::VisitCXXConstructExpr(CXXConstructExpr *E) {
1124 // FIXME. For now we just print a trivial constructor call expression,
1125 // constructing its first argument object.
1126 if (E->getNumArgs() == 1) {
1127 CXXConstructorDecl *CD = E->getConstructor();
1128 if (CD->isTrivial())
1129 PrintExpr(E->getArg(0));
1131 // Nothing to print.
1134 void StmtPrinter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
1135 // Just forward to the sub expression.
1136 PrintExpr(E->getSubExpr());
1140 StmtPrinter::VisitCXXUnresolvedConstructExpr(
1141 CXXUnresolvedConstructExpr *Node) {
1142 OS << Node->getTypeAsWritten().getAsString();
1144 for (CXXUnresolvedConstructExpr::arg_iterator Arg = Node->arg_begin(),
1145 ArgEnd = Node->arg_end();
1146 Arg != ArgEnd; ++Arg) {
1147 if (Arg != Node->arg_begin())
1154 void StmtPrinter::VisitCXXDependentScopeMemberExpr(
1155 CXXDependentScopeMemberExpr *Node) {
1156 if (!Node->isImplicitAccess()) {
1157 PrintExpr(Node->getBase());
1158 OS << (Node->isArrow() ? "->" : ".");
1160 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1161 Qualifier->print(OS, Policy);
1162 else if (Node->hasExplicitTemplateArgs())
1163 // FIXME: Track use of "template" keyword explicitly?
1166 OS << Node->getMember().getAsString();
1168 if (Node->hasExplicitTemplateArgs()) {
1169 OS << TemplateSpecializationType::PrintTemplateArgumentList(
1170 Node->getTemplateArgs(),
1171 Node->getNumTemplateArgs(),
1176 void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
1177 if (!Node->isImplicitAccess()) {
1178 PrintExpr(Node->getBase());
1179 OS << (Node->isArrow() ? "->" : ".");
1181 if (NestedNameSpecifier *Qualifier = Node->getQualifier())
1182 Qualifier->print(OS, Policy);
1184 // FIXME: this might originally have been written with 'template'
1186 OS << Node->getMemberName().getAsString();
1188 if (Node->hasExplicitTemplateArgs()) {
1189 OS << TemplateSpecializationType::PrintTemplateArgumentList(
1190 Node->getTemplateArgs(),
1191 Node->getNumTemplateArgs(),
1196 static const char *getTypeTraitName(UnaryTypeTrait UTT) {
1198 default: assert(false && "Unknown type trait");
1199 case UTT_HasNothrowAssign: return "__has_nothrow_assign";
1200 case UTT_HasNothrowCopy: return "__has_nothrow_copy";
1201 case UTT_HasNothrowConstructor: return "__has_nothrow_constructor";
1202 case UTT_HasTrivialAssign: return "__has_trivial_assign";
1203 case UTT_HasTrivialCopy: return "__has_trivial_copy";
1204 case UTT_HasTrivialConstructor: return "__has_trivial_constructor";
1205 case UTT_HasTrivialDestructor: return "__has_trivial_destructor";
1206 case UTT_HasVirtualDestructor: return "__has_virtual_destructor";
1207 case UTT_IsAbstract: return "__is_abstract";
1208 case UTT_IsClass: return "__is_class";
1209 case UTT_IsEmpty: return "__is_empty";
1210 case UTT_IsEnum: return "__is_enum";
1211 case UTT_IsPOD: return "__is_pod";
1212 case UTT_IsPolymorphic: return "__is_polymorphic";
1213 case UTT_IsUnion: return "__is_union";
1217 void StmtPrinter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
1218 OS << getTypeTraitName(E->getTrait()) << "("
1219 << E->getQueriedType().getAsString() << ")";
1224 void StmtPrinter::VisitObjCStringLiteral(ObjCStringLiteral *Node) {
1226 VisitStringLiteral(Node->getString());
1229 void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
1230 OS << "@encode(" << Node->getEncodedType().getAsString() << ')';
1233 void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
1234 OS << "@selector(" << Node->getSelector().getAsString() << ')';
1237 void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
1238 OS << "@protocol(" << Node->getProtocol()->getNameAsString() << ')';
1241 void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
1243 Expr *receiver = Mess->getReceiver();
1244 if (receiver) PrintExpr(receiver);
1245 else OS << Mess->getClassName()->getName();
1247 Selector selector = Mess->getSelector();
1248 if (selector.isUnarySelector()) {
1249 OS << selector.getIdentifierInfoForSlot(0)->getName();
1251 for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
1252 if (i < selector.getNumArgs()) {
1253 if (i > 0) OS << ' ';
1254 if (selector.getIdentifierInfoForSlot(i))
1255 OS << selector.getIdentifierInfoForSlot(i)->getName() << ':';
1259 else OS << ", "; // Handle variadic methods.
1261 PrintExpr(Mess->getArg(i));
1267 void StmtPrinter::VisitObjCSuperExpr(ObjCSuperExpr *) {
1271 void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
1272 BlockDecl *BD = Node->getBlockDecl();
1275 const FunctionType *AFT = Node->getFunctionType();
1277 if (isa<FunctionNoProtoType>(AFT)) {
1279 } else if (!BD->param_empty() || cast<FunctionProtoType>(AFT)->isVariadic()) {
1281 std::string ParamStr;
1282 for (BlockDecl::param_iterator AI = BD->param_begin(),
1283 E = BD->param_end(); AI != E; ++AI) {
1284 if (AI != BD->param_begin()) OS << ", ";
1285 ParamStr = (*AI)->getNameAsString();
1286 (*AI)->getType().getAsStringInternal(ParamStr, Policy);
1290 const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
1291 if (FT->isVariadic()) {
1292 if (!BD->param_empty()) OS << ", ";
1299 void StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) {
1300 OS << Node->getDecl()->getNameAsString();
1302 //===----------------------------------------------------------------------===//
1303 // Stmt method implementations
1304 //===----------------------------------------------------------------------===//
1306 void Stmt::dumpPretty(ASTContext& Context) const {
1307 printPretty(llvm::errs(), Context, 0,
1308 PrintingPolicy(Context.getLangOptions()));
1311 void Stmt::printPretty(llvm::raw_ostream &OS, ASTContext& Context,
1312 PrinterHelper* Helper,
1313 const PrintingPolicy &Policy,
1314 unsigned Indentation) const {
1320 if (Policy.Dump && &Context) {
1321 dump(Context.getSourceManager());
1325 StmtPrinter P(OS, Context, Helper, Policy, Indentation);
1326 P.Visit(const_cast<Stmt*>(this));
1329 //===----------------------------------------------------------------------===//
1331 //===----------------------------------------------------------------------===//
1333 // Implement virtual destructor.
1334 PrinterHelper::~PrinterHelper() {}