00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 #include "AstDumper.h"
00010 #include "ExprDumper.h"
00011 #include "DeclDumper.h"
00012 #include "StmtDumper.h"
00013 #include "TypeDumper.h"
00014 #include "comma/ast/Decl.h"
00015 #include "comma/ast/Expr.h"
00016 #include "comma/ast/RangeAttrib.h"
00017 #include "comma/ast/Stmt.h"
00018 #include "comma/ast/Type.h"
00019 
00020 #include "llvm/Support/Format.h"
00021 
00022 using namespace comma;
00023 
00024 using llvm::dyn_cast;
00025 using llvm::cast;
00026 using llvm::isa;
00027 
00028 
00029 
00030 
00031 llvm::raw_ostream &AstDumperBase::printHeader(Ast *node)
00032 {
00033     const char *kindString = node->getKindString();
00034     S << llvm::format("<%s ", kindString);
00035     S.write_hex(uintptr_t(node));
00036     return S;
00037 }
00038 
00039 llvm::raw_ostream &AstDumperBase::printIndentation()
00040 {
00041     for (unsigned i = 0; i < indentLevel; ++i)
00042         S << ' ';
00043     return S;
00044 }
00045 
00046 llvm::raw_ostream &AstDumperBase::dumpParamMode(PM::ParameterMode mode)
00047 {
00048     switch (mode) {
00049     case PM::MODE_DEFAULT:
00050         S << "D";
00051         break;
00052     case PM::MODE_IN:
00053         S << "I";
00054         break;
00055     case PM::MODE_OUT:
00056         S << "O";
00057         break;
00058     case PM::MODE_IN_OUT:
00059         S << "IO";
00060         break;
00061     }
00062     return S;
00063 }
00064 
00065 
00066 
00067 
00068 AstDumper::AstDumper(llvm::raw_ostream &stream)
00069     : AstDumperBase(stream)
00070 {
00071     EDumper = new ExprDumper(stream, this);
00072     DDumper = new DeclDumper(stream, this);
00073     SDumper = new StmtDumper(stream, this);
00074     TDumper = new TypeDumper(stream, this);
00075 }
00076 
00077 AstDumper::~AstDumper()
00078 {
00079     delete EDumper;
00080     delete DDumper;
00081     delete SDumper;
00082     delete TDumper;
00083 }
00084 
00085 llvm::raw_ostream &AstDumper::dumpDecl(Decl *node)
00086 {
00087     return DDumper->dump(node, indentLevel);
00088 }
00089 
00090 llvm::raw_ostream &AstDumper::dumpExpr(Expr *node)
00091 {
00092     return EDumper->dump(node, indentLevel);
00093 }
00094 
00095 llvm::raw_ostream &AstDumper::dumpStmt(Stmt *node)
00096 {
00097     return SDumper->dump(node, indentLevel);
00098 }
00099 
00100 llvm::raw_ostream &AstDumper::dumpType(Type *node)
00101 {
00102     return TDumper->dump(node, indentLevel);
00103 }
00104 
00105 llvm::raw_ostream &AstDumper::dumpRangeAttrib(RangeAttrib *node)
00106 {
00107     printHeader(node) << ' ';
00108     return dump(node->getPrefix(), indentLevel) << '>';
00109 }
00110 
00111 llvm::raw_ostream &AstDumper::dump(Ast *node, unsigned level)
00112 {
00113     unsigned savedLevel = indentLevel;
00114     indentLevel = level;
00115     if (Decl *decl = dyn_cast<Decl>(node))
00116         dumpDecl(decl);
00117     else if (Stmt *stmt = dyn_cast<Stmt>(node))
00118         dumpStmt(stmt);
00119     else if (Expr *expr = dyn_cast<Expr>(node))
00120         dumpExpr(expr);
00121     else if (Type *type = dyn_cast<Type>(node))
00122         dumpType(type);
00123     else {
00124         switch (node->getKind()) {
00125 
00126         default:
00127             assert(false && "Cannot dump this kind of node yet!");
00128             break;
00129 
00130         case Ast::AST_ArrayRangeAttrib:
00131         case Ast::AST_ScalarRangeAttrib:
00132             dumpRangeAttrib(cast<RangeAttrib>(node));
00133             break;
00134         };
00135     }
00136     indentLevel = savedLevel;
00137     return S;
00138 }
00139