[llvm-commits] CVS: llvm-java/tools/classdump/classdump.cpp
Alkis Evlogimenos
alkis at cs.uiuc.edu
Fri Feb 11 12:25:06 PST 2005
Changes in directory llvm-java/tools/classdump:
classdump.cpp updated: 1.15 -> 1.16
---
Log message:
Make classdump output be similar to javap -c (for debugging the
bytecode parser). There are a couple of bytecodes that don't work yet,
but the majority is there and a lot of classes in java/lang and
java/util are already parsed completely (and correctly!).
---
Diffs of the changes: (+567 -1)
classdump.cpp | 568 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 567 insertions(+), 1 deletion(-)
Index: llvm-java/tools/classdump/classdump.cpp
diff -u llvm-java/tools/classdump/classdump.cpp:1.15 llvm-java/tools/classdump/classdump.cpp:1.16
--- llvm-java/tools/classdump/classdump.cpp:1.15 Mon Sep 13 20:04:42 2004
+++ llvm-java/tools/classdump/classdump.cpp Fri Feb 11 14:24:29 2005
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include <llvm/Java/ClassFile.h>
+#include <llvm/Java/BytecodeParser.h>
#include <llvm/Support/CommandLine.h>
#include <llvm/System/Signals.h>
@@ -24,6 +25,571 @@
static cl::opt<std::string>
InputClass(cl::Positional, cl::desc("<input class>"));
+namespace {
+
+ using namespace llvm::Java;
+
+ class ClassDump : public BytecodeParser<ClassDump> {
+ const ClassFile* CF;
+ std::ostream& Out;
+
+ public:
+ ClassDump(const ClassFile* cf, std::ostream& out)
+ : CF(cf), Out(out) {
+
+ if (CF->isPublic())
+ Out << "public ";
+ if (CF->isFinal())
+ Out << "final ";
+
+ Out << "class " << CF->getThisClass()->getName()->str() << ' ';
+
+ if (ConstantClass* super = CF->getSuperClass())
+ Out << "extends " << super->getName()->str() << ' ';
+
+ if (!CF->getInterfaces().empty()) {
+ const Classes& interfaces = CF->getInterfaces();
+ Out << "implements " << interfaces[0]->getName()->str();
+ for (unsigned i = 1, e = interfaces.size(); i != e; ++i)
+ Out << ", " << interfaces[i]->getName()->str();
+ Out << ' ';
+ }
+ Out << "{\n";
+
+ const Fields& fields = CF->getFields();
+ // Dump static fields.
+ for (unsigned i = 0, e = fields.size(); i != e; ++i)
+ if (fields[i]->isStatic())
+ dumpField(fields[i]);
+ // Dump instance fields.
+ for (unsigned i = 0, e = fields.size(); i != e; ++i)
+ if (!fields[i]->isStatic())
+ dumpField(fields[i]);
+
+ const Methods& methods = CF->getMethods();
+ for (unsigned i = 0, e = methods.size(); i != e; ++i)
+ dumpMethod(methods[i]);
+
+ Out << "\n}\n";
+ }
+
+ void dumpField(const Field* F) {
+ Out << '\n';
+ if (F->isPublic())
+ Out << "public ";
+ else if (F->isProtected())
+ Out << "protected ";
+ else if (F->isPrivate())
+ Out << "private ";
+
+ if (F->isStatic())
+ Out << "static ";
+
+ if (F->isFinal())
+ Out << "final ";
+
+ Out << getPrettyString(F->getDescriptor()->str()) << ' '
+ << F->getName()->str() << ";\n";
+ }
+
+ void dumpMethod(const Method* M) {
+ Out << '\n';
+ if (M->isPublic())
+ Out << "public ";
+ else if (M->isProtected())
+ Out << "protected ";
+ else if (M->isPrivate())
+ Out << "private ";
+
+ if (M->isSynchronized())
+ Out << "synchronized ";
+
+ if (M->isStatic())
+ Out << "static ";
+
+ if (M->isFinal())
+ Out << "final ";
+
+ std::string Signature = getPrettyString(M->getDescriptor()->str());
+ Signature.insert(Signature.find('('), M->getName()->str());
+
+ Out << Signature << ";\n";
+ if (CodeAttribute* CodeAttr = M->getCodeAttribute()) {
+ Out << "\tCode:";
+ parse(CodeAttr->getCode(), 0, CodeAttr->getCodeSize());
+ Out << '\n';
+ }
+ }
+
+ std::string getPrettyString(const std::string& Desc) {
+ unsigned I = 0;
+ return getPrettyStringHelper(Desc, I);
+ }
+
+ std::string getPrettyStringHelper(const std::string& Desc, unsigned& I) {
+ if (Desc.size() == I)
+ return "";
+
+ switch (Desc[I++]) {
+ case 'B': return "byte";
+ case 'C': return "char";
+ case 'D': return "double";
+ case 'F': return "float";
+ case 'I': return "int";
+ case 'J': return "long";
+ case 'S': return "short";
+ case 'Z': return "boolean";
+ case 'V': return "void";
+ case 'L': {
+ unsigned E = Desc.find(';', I);
+ std::string ClassName = Desc.substr(I, E - I);
+ I = E + 1;
+ return ClassName;
+ }
+ case '[': {
+ std::string ArrayPart;
+ ArrayPart += "[]";
+ while (Desc[I] == '[') {
+ ArrayPart += "[]";
+ ++I;
+ }
+
+ return getPrettyStringHelper(Desc, I) + ArrayPart;
+ }
+ case '(': {
+ std::string Params;
+ while (Desc[I] != ')') {
+ if (Desc[I-1] != '(')
+ Params += ", ";
+ Params += getPrettyStringHelper(Desc, I);
+ }
+ return getPrettyStringHelper(Desc, ++I) + " (" + Params + ')';
+ }
+ }
+
+ return "";
+ }
+
+ /// @brief called before every bytecode
+ void pre_inst(unsigned bcI) { Out << "\n\t " << bcI << ":\t"; }
+ /// @brief called on ACONST_NULL
+ void do_aconst_null() { Out << "aconst_null"; }
+ /// @brief called on ICONST_<n>, SIPUSH and BIPUSH
+ void do_iconst(int value) {
+ if (value == -1)
+ Out << "iconst_m1";
+ else if (value >=0 && value <= 5)
+ Out << "iconst_" << value;
+ else if (value <= 255)
+ Out << "bipush " << value;
+ else
+ Out << "sipush " << value;
+ }
+ /// @brief called on LCONST_<n>
+ void do_lconst(long long value) {
+ if (value == 0 || value == 1)
+ Out << "lconst_" << value;
+ else
+ Out << "lconst " << value;
+ }
+ /// @brief called on FCONST_<n>
+ void do_fconst(float value) {
+ if (value >= 0 && value <= 2)
+ Out << "fconst_" << value;
+ else
+ Out << "fconst " << value;
+ }
+ /// @brief called on DCONST_<n>
+ void do_dconst(double value) {
+ if (value == 0 || value == 1)
+ Out << "dconst_" << value;
+ else
+ Out << "dconst " << value;
+ }
+ /// @brief called on LDC and LDC_W
+ void do_ldc(unsigned index) { Out << "ldc \t#" << index; }
+ /// @brief called on LDC2_W
+ void do_ldc2(unsigned index) { Out << "ldc2 \t#" << index; }
+ /// @brief called on ILOAD and ILOAD_<n>
+ void do_iload(unsigned index) {
+ if (index <= 3)
+ Out << "iload_" << index;
+ else
+ Out << "iload " << index;
+ }
+ /// @brief called on LLOAD and LLOAD_<n>
+ void do_lload(unsigned index) {
+ if (index <= 3)
+ Out << "lload_" << index;
+ else
+ Out << "lload " << index;
+ }
+ /// @brief called on FLOAD and FLOAD_<n>
+ void do_fload(unsigned index) {
+ if (index <= 3)
+ Out << "fload_" << index;
+ else
+ Out << "fload " << index;
+ }
+ /// @brief called on DLOAD and DLOAD_<n>
+ void do_dload(unsigned index) {
+ if (index <= 3)
+ Out << "dload_" << index;
+ else
+ Out << "dload " << index;
+ }
+ /// @brief called on ALOAD and ALOAD_<n>
+ void do_aload(unsigned index) {
+ if (index <= 3)
+ Out << "aload_" << index;
+ else
+ Out << "aload " << index;
+ }
+ /// @brief called on IALOAD
+ void do_iaload() { Out << "iaload"; }
+ /// @brief called on LALOAD
+ void do_laload() { Out << "laload"; }
+ /// @brief called on FALOAD
+ void do_faload() { Out << "faload"; }
+ /// @brief called on DALOAD
+ void do_daload() { Out << "daload"; }
+ /// @brief called on AALOAD
+ void do_aaload() { Out << "aaload"; }
+ /// @brief called on BALOAD
+ void do_baload() { Out << "baload"; }
+ /// @brief called on CALOAD
+ void do_caload() { Out << "caload"; }
+ /// @brief called on SALOAD
+ void do_saload() { Out << "saload"; }
+ /// @brief called on ISTORE and ISTORE_<n>
+ void do_istore(unsigned index) {
+ if (index <= 3)
+ Out << "istore_" << index;
+ else
+ Out << "istore " << index;
+ }
+ /// @brief called on LSTORE and LSTORE_<n>
+ void do_lstore(unsigned index) {
+ if (index <= 3)
+ Out << "lstore_" << index;
+ else
+ Out << "lstore " << index;
+ }
+ /// @brief called on FSTORE and FSTORE_<n>
+ void do_fstore(unsigned index) {
+ if (index <= 3)
+ Out << "fstore_" << index;
+ else
+ Out << "fstore " << index;
+ }
+ /// @brief called on DSTORE and DSTORE_<n>
+ void do_dstore(unsigned index) {
+ if (index <= 3)
+ Out << "dstore_" << index;
+ else
+ Out << "dstore " << index;
+ }
+ /// @brief called on ASTORE and ASTORE_<n>
+ void do_astore(unsigned index) {
+ if (index <= 3)
+ Out << "astore_" << index;
+ else
+ Out << "astore " << index;
+ }
+ /// @brief called on IASTORE
+ void do_iastore() { Out << "iastore"; }
+ /// @brief called on LASTORE
+ void do_lastore() { Out << "lastore"; }
+ /// @brief called on FASTORE
+ void do_fastore() { Out << "fastore"; }
+ /// @brief called on DASTORE
+ void do_dastore() { Out << "dastore"; }
+ /// @brief called on AASTORE
+ void do_aastore() { Out << "aastore"; }
+ /// @brief called on BASTORE
+ void do_bastore() { Out << "bastore"; }
+ /// @brief called on CASTORE
+ void do_castore() { Out << "castore"; }
+ /// @brief called on SASTORE
+ void do_sastore() { Out << "sastore"; }
+ /// @brief called on POP
+ void do_pop() { Out << "pop"; }
+ /// @brief called on POP2
+ void do_pop2() { Out << "pop2"; }
+ /// @brief called on DUP
+ void do_dup() { Out << "dup"; }
+ /// @brief called on DUP_X1
+ void do_dup_x1() { Out << "dup_x1"; }
+ /// @brief called on DUP_X2
+ void do_dup_x2() { Out << "dup_x2"; }
+ /// @brief called on DUP2
+ void do_dup2() { Out << "dup2"; }
+ /// @brief called on DUP2_X1
+ void do_dup2_x1() { Out << "dup2_x1"; }
+ /// @brief called on DUP2_X2
+ void do_dup2_x2() { Out << "dup2_x2"; }
+ /// @brief called on SWAP
+ void do_swap() { Out << "swap"; }
+ /// @brief called on IADD
+ void do_iadd() { Out << "iadd"; }
+ /// @brief called on LADD
+ void do_ladd() { Out << "ladd"; }
+ /// @brief called on FADD
+ void do_fadd() { Out << "fadd"; }
+ /// @brief called on DADD
+ void do_dadd() { Out << "dadd"; }
+ /// @brief called on ISUB
+ void do_isub() { Out << "isub"; }
+ /// @brief called on LSUB
+ void do_lsub() { Out << "lsub"; }
+ /// @brief called on FSUB
+ void do_fsub() { Out << "fsub"; }
+ /// @brief called on DSUB
+ void do_dsub() { Out << "dsub"; }
+ /// @brief called on IMUL
+ void do_imul() { Out << "imul"; }
+ /// @brief called on LMUL
+ void do_lmul() { Out << "lmul"; }
+ /// @brief called on FMUL
+ void do_fmul() { Out << "fmul"; }
+ /// @brief called on DMUL
+ void do_dmul() { Out << "dmul"; }
+ /// @brief called on IDIV
+ void do_idiv() { Out << "idiv"; }
+ /// @brief called on LDIV
+ void do_ldiv() { Out << "ldiv"; }
+ /// @brief called on FDIV
+ void do_fdiv() { Out << "fdiv"; }
+ /// @brief called on DDIV
+ void do_ddiv() { Out << "ddiv"; }
+ /// @brief called on IREM
+ void do_irem() { Out << "irem"; }
+ /// @brief called on LREM
+ void do_lrem() { Out << "lrem"; }
+ /// @brief called on FREM
+ void do_frem() { Out << "frem"; }
+ /// @brief called on DREM
+ void do_drem() { Out << "drem"; }
+ /// @brief called on INEG
+ void do_ineg() { Out << "ineg"; }
+ /// @brief called on LNEG
+ void do_lneg() { Out << "lneg"; }
+ /// @brief called on FNEG
+ void do_fneg() { Out << "fneg"; }
+ /// @brief called on DNEG
+ void do_dneg() { Out << "dneg"; }
+ /// @brief called on ISHL
+ void do_ishl() { Out << "ishl"; }
+ /// @brief called on LSHL
+ void do_lshl() { Out << "lshl"; }
+ /// @brief called on ISHR
+ void do_ishr() { Out << "ishr"; }
+ /// @brief called on LSHR
+ void do_lshr() { Out << "lshr"; }
+ /// @brief called on IUSHR
+ void do_iushr() { Out << "iushr"; }
+ /// @brief called on LUSHR
+ void do_lushr() { Out << "lushr"; }
+ /// @brief called on IAND
+ void do_iand() { Out << "iand"; }
+ /// @brief called on LAND
+ void do_land() { Out << "land"; }
+ /// @brief called on IOR
+ void do_ior() { Out << "ior"; }
+ /// @brief called on LOR
+ void do_lor() { Out << "lor"; }
+ /// @brief called on IXOR
+ void do_ixor() { Out << "ixor"; }
+ /// @brief called on LXOR
+ void do_lxor() { Out << "lxor"; }
+ /// @brief called on IINC
+ void do_iinc(unsigned index, int amount) {
+ Out << "iinc " << index << ", " << amount;
+ }
+ /// @brief called on I2L
+ void do_i2l() { Out << "i2l"; }
+ /// @brief called on I2F
+ void do_i2f() { Out << "i2f"; }
+ /// @brief called on I2D
+ void do_i2d() { Out << "i2d"; }
+ /// @brief called on L2I
+ void do_l2i() { Out << "l2i"; }
+ /// @brief called on L2F
+ void do_l2f() { Out << "l2f"; }
+ /// @brief called on L2D
+ void do_l2d() { Out << "l2d"; }
+ /// @brief called on F2I
+ void do_f2i() { Out << "f2i"; }
+ /// @brief called on F2L
+ void do_f2l() { Out << "f2l"; }
+ /// @brief called on F2D
+ void do_f2d() { Out << "f2d"; }
+ /// @brief called on D2I
+ void do_d2i() { Out << "d2i"; }
+ /// @brief called on D2L
+ void do_d2l() { Out << "d2l"; }
+ /// @brief called on D2F
+ void do_d2f() { Out << "d2f"; }
+ /// @brief called on I2B
+ void do_i2b() { Out << "i2b"; }
+ /// @brief called on I2C
+ void do_i2c() { Out << "i2c"; }
+ /// @brief called on I2S
+ void do_i2s() { Out << "i2s"; }
+ /// @brief called on LCMP
+ void do_lcmp() { Out << "lcmp"; }
+ /// @brief called on FCMPL
+ void do_fcmpl() { Out << "fcmpl"; }
+ /// @brief called on DCMPL
+ void do_dcmpl() { Out << "dcmpl"; }
+ /// @brief called on FCMPG
+ void do_fcmpg() { Out << "fcmpg"; }
+ /// @brief called on DCMPG
+ void do_dcmpg() { Out << "dcmpg"; }
+ /// @brief called on IFEQ
+ void do_ifeq(unsigned t, unsigned f) { Out << "ifeq " << t; }
+ /// @brief called on IFNE
+ void do_ifne(unsigned t, unsigned f) { Out << "ifne " << t; }
+ /// @brief called on IFLT
+ void do_iflt(unsigned t, unsigned f) { Out << "iflt " << t; }
+ /// @brief called on IFGE
+ void do_ifge(unsigned t, unsigned f) { Out << "ifge " << t; }
+ /// @brief called on IFGT
+ void do_ifgt(unsigned t, unsigned f) { Out << "ifgt " << t; }
+ /// @brief called on IFLE
+ void do_ifle(unsigned t, unsigned f) { Out << "ifle " << t; }
+ /// @brief called on IF_ICMPEQ
+ void do_if_icmpeq(unsigned t, unsigned f) { Out << "if_icmpeq " << t; }
+ /// @brief called on IF_ICMPNE
+ void do_if_icmpne(unsigned t, unsigned f) { Out << "if_icmpne " << t; }
+ /// @brief called on IF_ICMPLT
+ void do_if_icmplt(unsigned t, unsigned f) { Out << "if_icmplt " << t; }
+ /// @brief called on IF_ICMPGE
+ void do_if_icmpge(unsigned t, unsigned f) { Out << "if_icmpge " << t; }
+ /// @brief called on IF_ICMPGT
+ void do_if_icmpgt(unsigned t, unsigned f) { Out << "if_icmpgt " << t; }
+ /// @brief called on IF_ICMPLE
+ void do_if_icmple(unsigned t, unsigned f) { Out << "if_icmple " << t; }
+ /// @brief called on IF_ACMPEQ
+ void do_if_acmpeq(unsigned t, unsigned f) { Out << "if_acmpeq " << t; }
+ /// @brief called on IF_ACMPNE
+ void do_if_acmpne(unsigned t, unsigned f) { Out << "if_acmpne " << t; }
+ /// @brief called on GOTO and GOTO_W
+ void do_goto(unsigned target) { Out << "goto " << target; }
+ /// @brief called on JSR and JSR_W
+ void do_jsr(unsigned target, unsigned retAddress) { abort(); }
+ /// @brief called on RET
+ void do_ret(unsigned index) { abort(); }
+ /// @brief called on TABLESWITCH and LOOKUPSWITCH
+ void do_switch(unsigned defTarget, const SwitchCases& sw) { abort(); }
+ /// @brief called on IRETURN
+ void do_ireturn() { Out << "ireturn"; }
+ /// @brief called on LRETURN
+ void do_lreturn() { Out << "lreturn"; }
+ /// @brief called on FRETURN
+ void do_freturn() { Out << "freturn"; }
+ /// @brief called on DRETURN
+ void do_dreturn() { Out << "dreturn"; }
+ /// @brief called on ARETURN
+ void do_areturn() { Out << "areturn"; }
+ /// @brief called on RETURN
+ void do_return() { Out << "return"; }
+ /// @brief called on GETSTATIC
+ void do_getstatic(unsigned index) {
+ Out << "getstatic #" << index << "; //Field ";
+ printMemberRef(index);
+ }
+ /// @brief called on PUTSTATIC
+ void do_putstatic(unsigned index) {
+ Out << "putstatic #" << index << "; //Field ";
+ printMemberRef(index);
+ }
+ /// @brief called on GETFIELD
+ void do_getfield(unsigned index) {
+ Out << "getfield #" << index << "; //Field ";
+ printMemberRef(index);
+ }
+ /// @brief called on PUTFIELD
+ void do_putfield(unsigned index) {
+ Out << "putfield #" << index << "; //Field ";
+ printMemberRef(index);
+ }
+ /// @brief called on INVOKEVIRTUAL
+ void do_invokevirtual(unsigned index) {
+ Out << "invokevirtual #" << index << "; //Method ";
+ printMemberRef(index);
+ }
+ /// @brief called on INVOKESPECIAL
+ void do_invokespecial(unsigned index) {
+ Out << "invokespecial #" << index << "; //Method ";
+ printMemberRef(index);
+ }
+ /// @brief called on INVOKESTATIC
+ void do_invokestatic(unsigned index) {
+ Out << "invokestatic #" << index << "; //Method ";
+ printMemberRef(index);
+ }
+ /// @brief called on INVOKEINTERFACE
+ void do_invokeinterface(unsigned index) {
+ Out << "invokeinterface #" << index << "; //InterfaceMethod ";
+ printMemberRef(index);
+ }
+ /// @brief called on NEW
+ void do_new(unsigned index) {
+ Out << "new #" << index << "; //class ";
+ printClassRef(index);
+ }
+ /// @brief called on NEWARRAY
+ void do_newarray(JType type) { Out << "newarray #" << type; abort(); }
+ /// @brief called on ANEWARRAY
+ void do_anewarray(unsigned index) {
+ Out << "anewarray #" << index << "; //class ";
+ printClassRef(index);
+ }
+ /// @brief called on ARRAYLENGTH
+ void do_arraylength() { Out << "arraylength"; }
+ /// @brief called on ATHROW
+ void do_athrow() { Out << "athrow"; }
+ /// @brief called on CHECKCAST
+ void do_checkcast(unsigned index) {
+ Out << "checkcast #" << index
+ << "; //class ";
+ printClassRef(index);
+ }
+ /// @brief called on INSTANCEOF
+ void do_instanceof(unsigned index) {
+ Out << "instanceof #" << index
+ << "; //class ";
+ printClassRef(index);
+ }
+ /// @brief called on MONITORENTER
+ void do_monitorenter() { Out << "monitorenter"; }
+ /// @brief called on MONITOREXIT
+ void do_monitorexit() { Out << "monitorexit"; }
+ /// @brief called on MULTIANEWARRAY
+ void do_multianewarray(unsigned index, unsigned dims) { }
+ /// @brief called on IFNULL
+ void do_ifnull(unsigned t, unsigned f) { Out << "ifnull " << t; }
+ /// @brief called on IFNONNULL
+ void do_ifnonnull(unsigned t, unsigned f) { Out << "ifnonnull " << t; }
+
+ void printMemberRef(unsigned index) {
+ ConstantMemberRef* Ref = CF->getConstantMemberRef(index);
+ ConstantClass* Class = Ref->getClass();
+ if (Class != CF->getThisClass())
+ Out << Class->getName()->str() << '.';
+ Out << Ref->getNameAndType()->getName()->str()
+ << ':'
+ << Ref->getNameAndType()->getDescriptor()->str();
+ }
+
+ void printClassRef(unsigned index) {
+ const std::string& FQCN = CF->getConstantClass(index)->getName()->str();
+ Out << FQCN.substr(FQCN.rfind('/')+1);
+ }
+ };
+}
+
int main(int argc, char* argv[])
{
sys::PrintStackTraceOnErrorSignal();
@@ -33,7 +599,7 @@
try {
const Java::ClassFile* cf(Java::ClassFile::get(InputClass));
- cf->dump(std::cout);
+ ClassDump(cf, std::cout);
}
catch (std::exception& e) {
std::cerr << e.what() << '\n';
More information about the llvm-commits
mailing list