//===--- StmtPrinter.cpp - Printing implementation for Stmt ASTs ----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Stmt::dumpPretty/Stmt::printPretty methods, which
// pretty print the AST back out to C code.
//
//===----------------------------------------------------------------------===//
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/PrettyPrinter.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Streams.h"
#include "llvm/Support/Format.h"
using namespace clang;
//===----------------------------------------------------------------------===//
// StmtPrinter Visitor
//===----------------------------------------------------------------------===//
namespace {
class VISIBILITY_HIDDEN StmtPrinter : public StmtVisitor<StmtPrinter> {
llvm::raw_ostream &OS;
unsigned IndentLevel;
clang::PrinterHelper* Helper;
public:
StmtPrinter(llvm::raw_ostream &os, PrinterHelper* helper) :
OS(os), IndentLevel(0), Helper(helper) {}
void PrintStmt(Stmt *S, int SubIndent = 1) {
IndentLevel += SubIndent;
if (S && isa<Expr>(S)) {
// If this is an expr used in a stmt context, indent and newline it.
Indent();
Visit(S);
OS << ";\n";
} else if (S) {
Visit(S);
} else {
Indent() << "<<<NULL STATEMENT>>>\n";
}
IndentLevel -= SubIndent;
}
void PrintRawCompoundStmt(CompoundStmt *S);
void PrintRawDecl(Decl *D);
void PrintRawDeclStmt(DeclStmt *S);
void PrintRawIfStmt(IfStmt *If);
void PrintExpr(Expr *E) {
if (E)
Visit(E);
else
OS << "<null expr>";
}
llvm::raw_ostream &Indent(int Delta = 0) const {
for (int i = 0, e = IndentLevel+Delta; i < e; ++i)
OS << " ";
return OS;
}
bool PrintOffsetOfDesignator(Expr *E);
void VisitUnaryOffsetOf(UnaryOperator *Node);
void Visit(Stmt* S) {
if (Helper && Helper->handledStmt(S,OS))
return;
else StmtVisitor<StmtPrinter>::Visit(S);
}
void VisitStmt(Stmt *Node);
#define STMT(CLASS, PARENT) \
void Visit##CLASS(CLASS *Node);
#include "clang/AST/StmtNodes.def"
};
}
//===----------------------------------------------------------------------===//
// Stmt printing methods.
//===----------------------------------------------------------------------===//
void StmtPrinter::VisitStmt(Stmt *Node) {
Indent() << "<<unknown stmt type>>\n";
}
/// PrintRawCompoundStmt - Print a compound stmt without indenting the {, and
/// with no newline after the }.
void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
OS << "{\n";
for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end();
I != E; ++I)
PrintStmt(*I);
Indent() << "}";
}
void StmtPrinter::PrintRawDecl(Decl *D) {
// FIXME: Need to complete/beautify this... this code simply shows the
// nodes are where they need to be.
if (TypedefDecl *localType = dyn_cast<TypedefDecl>(D)) {
OS << "typedef " << localType->getUnderlyingType().getAsString();
OS << " " << localType->getNameAsString();
} else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
// Emit storage class for vardecls.
if (VarDecl *V = dyn_cast<VarDecl>(VD)) {
switch (V