| //===-- classdump.cpp - classdump utility -----------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file was developed by the LLVM research group and is distributed under |
| // the University of Illinois Open Source License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This is a sample class reader driver. It is used to drive class |
| // reader tests. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include <llvm/Java/ClassFile.h> |
| #include <llvm/Java/BytecodeParser.h> |
| #include <llvm/Support/CommandLine.h> |
| #include <llvm/System/Signals.h> |
| |
| #include <cstddef> |
| #include <iostream> |
| |
| using namespace llvm; |
| |
| namespace { |
| |
| enum DumpType { code, constantPool }; |
| |
| cl::opt<std::string> |
| InputClass(cl::Positional, cl::desc("<input class>")); |
| |
| cl::opt<DumpType> |
| DumpMode( |
| "dumptype", |
| cl::desc("Dump type: (default = code)"), |
| cl::Prefix, |
| cl::values( |
| clEnumVal(code, "code"), |
| clEnumVal(constantPool, "constant pool"), |
| clEnumValEnd), |
| cl::init(code)); |
| |
| 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->getNumInterfaces()) { |
| Out << "implements " << CF->getInterface(0)->getName()->str(); |
| for (unsigned i = 1, e = CF->getNumInterfaces(); i != e; ++i) |
| Out << ", " << CF->getInterface(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 "; |
| |
| if (F->isTransient()) |
| Out << "transient "; |
| |
| 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->isStatic()) |
| Out << "static "; |
| |
| if (M->isAbstract()) |
| Out << "abstract "; |
| |
| if (M->isFinal()) |
| Out << "final "; |
| |
| if (M->isSynchronized()) |
| Out << "synchronized "; |
| |
| 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; |
| std::string prettyString = getPrettyStringHelper(Desc, I); |
| for (unsigned i = 0, e = prettyString.size(); i != e; ++i) |
| if (prettyString[i] == '/') |
| prettyString[i] = '.'; |
| return prettyString; |
| } |
| |
| 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 >= -128 && value <= 127) |
| 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) { |
| if (index <= 255) |
| Out << "ldc"; |
| else |
| Out << "ldc_w"; |
| Out << "\t#" << index << "; //" << *CF->getConstant(index); |
| } |
| /// @brief called on LDC2_W |
| void do_ldc2(unsigned index) { |
| Out << "ldc2_w \t#" << index << "; //" << *CF->getConstant(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 |
| void do_tableswitch(unsigned defTarget, const SwitchCases& sw) { |
| Out << "tableswitch{ //" << sw.front().first << " to " << sw.back().first; |
| for (unsigned i = 0, e = sw.size(); i != e; ++i) |
| Out << "\n\t\t\t" << sw[i].first << ": " << sw[i].second << ';'; |
| Out << ";\n\t\t\tdefault: " << defTarget << " }"; |
| } |
| /// @brief called on LOOKUPSWITCH |
| void do_lookupswitch(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 "; |
| switch (type) { |
| case BOOLEAN: Out << "boolean"; break; |
| case CHAR: Out << "char"; break; |
| case FLOAT: Out << "float"; break; |
| case DOUBLE: Out << "double"; break; |
| case BYTE: Out << "byte"; break; |
| case SHORT: Out << "short"; break; |
| case INT: Out << "int"; break; |
| case LONG: Out << "long"; break; |
| default: assert(0 && "Unknown type for newarray!"); |
| } |
| } |
| |
| /// @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(); |
| cl::ParseCommandLineOptions(argc, argv, |
| "class dump utility"); |
| |
| try { |
| const Java::ClassFile* cf(Java::ClassFile::get(InputClass)); |
| |
| switch (DumpMode) { |
| default: |
| std::cerr << "no dump type selected"; |
| abort(); |
| case code: { |
| ClassDump(cf, std::cout); |
| break; |
| } |
| case constantPool: { |
| for (unsigned i = 0, e = cf->getNumConstants(); i != e; ++i) { |
| Constant* c = cf->getConstant(i); |
| std::cout.width(6); |
| std::cout << i << ": "; |
| std::cout.width(0); |
| if (c) |
| std::cout << *cf->getConstant(i); |
| else |
| std::cout << "empty"; |
| std::cout << '\n'; |
| } |
| break; |
| } |
| } |
| } |
| catch (std::exception& e) { |
| std::cerr << e.what() << '\n'; |
| return EXIT_FAILURE; |
| } |
| |
| return EXIT_SUCCESS; |
| } |