[llvm-commits] [parallel] CVS: llvm/test/Programs/MultiSource/Applications/hbd/LICENSE.TXT Makefile Sort.class access.cpp access.h class.cpp class.h config.h consts.h cp.cpp cp.h d1-pushc.cpp d2-pushl.cpp d3-popl.cpp d4-array.cpp d5-stack.cpp d6-arith.cpp d7-cntrl.cpp d8-ret.cpp d9-swtch.cpp da-field.cpp db-meth.cpp dc-misc.cpp decomp.cpp decomp.h err.cpp err.h exp.cpp exp.h field.h file.h general.h hbd.1 hbd.cpp hbd.sgml id.cpp id.h method.h op.cpp op.h options.h sig.cpp sig.h version.cpp version.h

Misha Brukman brukman at cs.uiuc.edu
Mon Mar 1 18:59:08 PST 2004


Changes in directory llvm/test/Programs/MultiSource/Applications/hbd:

LICENSE.TXT added (r1.1.2.1)
Makefile added (r1.1.2.1)
Sort.class added (r1.1.2.1)
access.cpp added (r1.1.2.1)
access.h added (r1.1.2.1)
class.cpp added (r1.1.2.1)
class.h added (r1.1.2.1)
config.h added (r1.1.2.1)
consts.h added (r1.1.2.1)
cp.cpp added (r1.1.2.1)
cp.h added (r1.1.2.1)
d1-pushc.cpp added (r1.1.2.1)
d2-pushl.cpp added (r1.1.2.1)
d3-popl.cpp added (r1.1.2.1)
d4-array.cpp added (r1.1.2.1)
d5-stack.cpp added (r1.1.2.1)
d6-arith.cpp added (r1.1.2.1)
d7-cntrl.cpp added (r1.1.2.1)
d8-ret.cpp added (r1.1.2.1)
d9-swtch.cpp added (r1.1.2.1)
da-field.cpp added (r1.1.2.1)
db-meth.cpp added (r1.1.2.1)
dc-misc.cpp added (r1.1.2.1)
decomp.cpp added (r1.1.2.1)
decomp.h added (r1.1.2.1)
err.cpp added (r1.1.2.1)
err.h added (r1.1.2.1)
exp.cpp added (r1.1.2.1)
exp.h added (r1.1.2.1)
field.h added (r1.1.2.1)
file.h added (r1.1.2.1)
general.h added (r1.1.2.1)
hbd.1 added (r1.1.2.1)
hbd.cpp added (r1.1.2.1)
hbd.sgml added (r1.1.2.1)
id.cpp added (r1.1.2.1)
id.h added (r1.1.2.1)
method.h added (r1.1.2.1)
op.cpp added (r1.1.2.1)
op.h added (r1.1.2.1)
options.h added (r1.1.2.1)
sig.cpp added (r1.1.2.1)
sig.h added (r1.1.2.1)
version.cpp added (r1.1.2.1)
version.h added (r1.1.2.1)

---
Log message:

Merge from trunk

---
Diffs of the changes:  (+3758 -0)

Index: llvm/test/Programs/MultiSource/Applications/hbd/LICENSE.TXT
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/LICENSE.TXT:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/LICENSE.TXT	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,9 ----
+ Homebrew Decompiler
+ ------------------------------------------------------------------------------
+ Homebrew Decompiler is licensed under the GNU General Public License.  Please
+ see the file doc/COPYING for more information.
+ 
+ The Makefiles and autoconf code from the original distribution have been
+ removed as they are not needed within the LLVM build system.  A hard-coded
+ config.h file is provided.
+ 


Index: llvm/test/Programs/MultiSource/Applications/hbd/Makefile
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/Makefile:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/Makefile	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,8 ----
+ LEVEL = ../../../../..
+ PROG = hbd
+ CPPFLAGS += -DHAVE_CONFIG_H
+ LDFLAGS += -lstdc++
+ LIBS += -lstdc++
+ RUN_OPTIONS = Sort.class
+ REQUIRES_EH_SUPPORT := 1
+ include ../../Makefile.multisrc


Index: llvm/test/Programs/MultiSource/Applications/hbd/Sort.class


Index: llvm/test/Programs/MultiSource/Applications/hbd/access.cpp
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/access.cpp:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/access.cpp	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,48 ----
+ /* access.cpp */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #include <string.h>
+ #include "general.h"
+ #include "access.h"
+ 
+ char *flag2str[] = {
+   "public ", "private ", "protected ", "static ",
+   "final ", "synchronized ", "threadsafe ", "transient ",
+   "native ", "interface ", "abstract "
+ };
+ 
+ int flag2strlen[] = {
+   7, 8, 10, 7, 6, 13, 11, 10, 7, 10, 9
+ };
+ 
+ char *AccessFlags::toString(char *buffer)
+ {
+   u16 f, i;
+ 
+   *buffer = '\0';
+ 
+   for (f = flags, i = 0; f; f>>=1, i++) {
+     if (f & 1) {
+       strcat(buffer, flag2str[i]);
+     }
+   }
+   return buffer;
+ }
+ 
+ u16 AccessFlags::strlen()
+ {
+   u16 buffsize = 0, f, i;
+ 
+   for (f = flags, i = 0; f; f>>=1, i++) {
+     if (f & 1) {
+       buffsize += flag2strlen[i];
+     }
+   }
+ 
+   return buffsize;
+ }


Index: llvm/test/Programs/MultiSource/Applications/hbd/access.h
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/access.h:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/access.h	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,66 ----
+ /* access.h */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #ifndef ACCESS_H
+ #define ACCESS_H
+ 
+ #include "general.h"
+ 
+ /* The various types of Access flags Java uses */
+ enum Access {
+   ACC_PUBLIC = 0x0001, /* visible to everyone */
+   ACC_PRIVATE = 0x0002, /* visible only to defining class */
+   ACC_PROTECTED = 0x0004, /* visible to subclasses */
+   ACC_STATIC = 0x0008, /* instance variable is static */
+   ACC_FINAL = 0x0010, /* no further subclassing, overriding */
+   ACC_SYNCHRONIZED = 0x0020, /* wrap method call */
+                               /* in monitor lock */
+   ACC_THREADSAFE = 0x0040, /* can cache in registers */
+   ACC_TRANSIENT = 0x0080, /* not persistant */
+   ACC_NATIVE = 0x0100, /* implemented in C */
+   ACC_INTERFACE = 0x0200, /* class is an interface */
+   ACC_ABSTRACT = 0x0400 /* no definition provided */
+ };
+ 
+ /*
+    A class representing a set of access flags with
+    various useful methods.
+ */
+ 
+ struct AccessFlags {
+   u16 flags;
+ 
+   AccessFlags() {
+     flags = 0;
+   }
+ 
+   AccessFlags(u16 inflags) {
+     flags = inflags;
+   }
+ 
+   void operator =(u16 inflags) {
+     flags = inflags;
+   }
+ 
+   void operator +=(Access a) {
+     flags |= (u16)a;
+   }
+ 
+   void operator -=(Access a) {
+     flags &= ~(u16)a;
+   }
+ 
+   int operator &(u16 intflags) {
+     return flags & intflags;
+   }
+ 
+   char *toString(char *buffer);
+   u16 strlen();
+ };
+ 
+ #endif


Index: llvm/test/Programs/MultiSource/Applications/hbd/class.cpp
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/class.cpp:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/class.cpp	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,418 ----
+ /* class.cpp */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #include <string.h>
+ #include <ctype.h>
+ #include "general.h"
+ #include "options.h"
+ #include "cp.h"
+ #include "access.h"
+ #include "field.h"
+ #include "exp.h"
+ #include "method.h"
+ #include "version.h"
+ #include "class.h"
+ #include "file.h"
+ #include "err.h"
+ #include "consts.h"
+ 
+ #define JAVA_CLASSFILE_MAGIC              0xCafeBabeL
+ 
+ char *progname;
+ 
+ Classfile::Classfile(int argc, char **argv) {
+   functoinsert = 0;
+   outfile = stdout; infile = stdin;
+   progname = *argv++;
+   if (strcmp(progname + strlen(progname) - 3, "hbt") == 0) {
+     for (; (--argc) && (**argv == '-'); argv++) {
+       options = (CL_Options)0;
+       switch (toupper((*argv)[1])) {
+         case 'D': *(int *)&options |= (int)OPT_DEBUG; break;
+         case 'I': functoinsert = &((*argv)[2]); break;
+         default:
+           fprintf(stderr, "Unknown flag: %s\n", argv[1]);
+           fatalerror(COMMAND_LINE_ERR_HBT, progname);
+       }
+     }
+     char *tmpstr;
+     switch (argc) {
+       case 1:
+         tmpstr = new char[strlen(argv[0])+5];
+         strcpy(tmpstr, argv[0]);
+         strcat(tmpstr, ".bak");
+         rename(argv[0], tmpstr);
+         if ((infile = fopen(tmpstr, "rb"))==NULL) {
+           fprintf(stderr, "Could not open file %s\n", argv[0]);
+           goto defaultcase_hbt;
+         }
+         if ((outfile = fopen(argv[0], "wb"))==NULL) {
+           fprintf(stderr, "Could not open file %s\n", argv[1]);
+           goto defaultcase_hbt;
+         }
+         delete tmpstr;
+         break;
+       default: defaultcase_hbt:
+         fatalerror(COMMAND_LINE_ERR_HBT, progname);
+     }
+     if (functoinsert == 0)
+       fatalerror(COMMAND_LINE_ERR_HBT, progname);
+     outfile_pos = 0;
+   } else {
+     for (; (--argc) && (**argv == '-'); argv++) {
+       options = (CL_Options)0;
+       switch (toupper((*argv)[1])) {
+         case 'O': *(int *)&options |= (int)OPT_DECOMPILE_OFF; break;
+         case 'D': *(int *)&options |= (int)OPT_DEBUG; break;
+         default:
+           fprintf(stderr, "Unknown flag: %s\n", argv[1]);
+           fatalerror(COMMAND_LINE_ERR_HBD, progname);
+       }
+     }
+     switch (argc) {
+       case 2:
+         if ((outfile = fopen(argv[1], "wb"))==NULL) {
+           fprintf(stderr, "Could not open file %s\n", argv[1]);
+           goto defaultcase_hbd;
+         }
+       case 1:
+         if ((infile = fopen(argv[0], "rb"))==NULL) {
+           fprintf(stderr, "Could not open file %s\n", argv[0]);
+           goto defaultcase_hbd;
+         }
+         break;
+       default: defaultcase_hbd:
+        fatalerror(COMMAND_LINE_ERR_HBD, progname);
+     }
+   }
+   infile_pos = 0;
+ }
+ 
+ void Classfile::read() {
+   u16 numimports;
+ 
+   if (get32(infile, &infile_pos) != JAVA_CLASSFILE_MAGIC) fatalerror(NOT_A_CLASS_ERR);
+ 
+   version.read(this);
+   fprintf(stderr, "Classfile version %d.%d\n", version.major_version, version.minor_version);
+ 
+   imports_count = 0;
+   cp.read(this, &imports_count);
+   access_flags = get16(infile, &infile_pos);
+ 
+   this_class = get16(infile, &infile_pos);
+   super_class = get16(infile, &infile_pos);
+   if (((interfaces = new u16[interfaces_count = get16(infile, &infile_pos)]) == 0) && interfaces_count) memerr();
+   u16 i,j;
+   for (j = 0, i = interfaces_count; i--;) {
+     interfaces[j++] = get16(infile, &infile_pos);
+   }
+   if (((fields = new field_info_ptr[fields_count = get16(infile, &infile_pos)]) == 0) && fields_count) memerr();
+   for (j = 0, i = fields_count; i--;) {
+     field_info *fip = fields[j++] = new field_info;
+     if (!fip) memerr();
+     field_info &fi = *fip;
+     fi.isconstant = 0;
+     fi.access_flags = get16(infile, &infile_pos);
+     fi.name = cp[get16(infile, &infile_pos)]->chp;
+     fi.sig = cp[get16(infile, &infile_pos)]->chp;
+     for (int l = get16(infile, &infile_pos); l--;) {
+       u16 attribute_name_index = get16(infile, &infile_pos);
+       u32 attribute_size = get32(infile, &infile_pos);
+       char *attribute_name = cp[attribute_name_index]->chp;
+       if (!strcmp(attribute_name,"ConstantValue")) {
+         if (attribute_size != 2) {
+           fprintf(stderr, "Bad size on ConstantValue Attribute - should be 2!\n");
+           exit(1);
+         } else {
+           fi.isconstant = 1;
+           fi.constval_index = get16(infile, &infile_pos);
+         }
+       } else {
+         fprintf(stderr, "Skipping Unknown Field Attribute: %s (size %ld)\n", attribute_name, attribute_size);
+         for (u32 m = attribute_size; m--;) get8(infile, &infile_pos);
+       }
+     }
+   }
+   if (((methods = new method_info_ptr[methods_count = get16(infile, &infile_pos)]) == 0) && methods_count) memerr();
+   imports_count += methods_count;
+   numimports = 0;
+   if ((imports = new char_ptr[imports_count]) == 0) memerr();
+   char *tmpstr1, *tmpstr2, *tmpstr;
+   int package_name_length;
+   tmpstr = cp(this_class)->chp;
+   if ((tmpstr1 = strchr(tmpstr,'/')) != 0) {
+     int l;
+     while (tmpstr1) {
+       l = tmpstr1 - tmpstr;
+       tmpstr1 = strchr(tmpstr1 + 1, '/');
+     }
+     if ((package_name = new char[l+1]) == 0) memerr();
+     strncpy(package_name, tmpstr, l);
+     package_name[l] = '\0';
+     if ((this_class_name = new char[strlen(tmpstr + l + 1) + 1]) == 0) memerr();
+     strcpy(this_class_name, cp(this_class)->chp = tmpstr + l + 1);
+     tmpstr = package_name;
+     package_name_length = strlen(tmpstr);
+     while ((tmpstr = strchr(tmpstr,'/')) != 0) *tmpstr++ = '.';
+   } else {
+     package_name = 0;
+     package_name_length = 0;
+     if ((this_class_name = new char[strlen(tmpstr) + 1]) == 0) memerr();
+     strcpy(this_class_name, tmpstr);
+   }
+   for (i16 l = cp.count(); --l >= 0;) {
+     cp_info tmpcpi = *(cp[l]);
+     if (tmpcpi.tag == CONSTANT_Class) {
+       char **chap = &(cp(l)->chp);
+       tmpstr = *chap;
+       if (!strncmp(tmpstr, "java/lang/", 10)) *chap = tmpstr + 10;
+       else while ((tmpstr = strchr(tmpstr,'/')) != 0) *tmpstr++ = '.';
+       tmpstr = *chap;
+       if (package_name && !strncmp(tmpstr, package_name, package_name_length)) *chap = tmpstr += package_name_length + 1;
+       if ((numimports!=imports_count)&&(tmpstr2 = strrchr(tmpstr,'.')) != 0) {
+         imports[numimports++] = tmpstr;
+         for (int tint = numimports - 2; tint>=0; tint--) {
+           if (!strcmp(imports[tint], tmpstr)) {
+             --numimports;
+             break;
+           }
+         }
+         *chap = tmpstr2 + 1;
+       }
+     } else if(tmpcpi.tag == CONSTANT_NameAndType) {
+       //      int tmpindex;
+       tmpstr = cp[/*tmpindex = */((NameAndType*)tmpcpi.p)->signature_index]->chp;
+         char *copytmpstr = tmpstr2 = strdup(tmpstr); if (!copytmpstr) memerr();
+       char *srcstr = tmpstr2, *deststr = tmpstr, *tmpstr3, *tmpstr4;
+       while ((*deststr++ = *srcstr++) != '\0') {
+         if (*(srcstr-1) == 'L') {
+           tmpstr3 = strchr(srcstr, ';'); if (!tmpstr3) fatalerror(UNKNOWN_ERR);
+           if (!strncmp(srcstr, "java/lang/", 10)) srcstr += 10;
+           else {
+             tmpstr2 = srcstr;
+             while (((tmpstr2 = strchr(tmpstr2,'/')) != 0)&&(tmpstr2 < tmpstr3)) *tmpstr2++ = '.';
+           }
+           if (package_name && !strncmp(srcstr, package_name, package_name_length)) srcstr += package_name_length + 1;
+           if (numimports!=imports_count && (tmpstr4 = strchr(srcstr, '.')) != 0 && tmpstr4 < tmpstr3) {
+             while (tmpstr4 != 0 && tmpstr4 < tmpstr3) { tmpstr2 = tmpstr4+1; tmpstr4 = strchr(tmpstr2,'.'); }
+             int tint = tmpstr3 - srcstr;
+             char *tstr = imports[numimports++] = new char[tint+1];
+             if (!tstr) memerr();
+             tstr = strncpy(tstr, srcstr, tint);
+             tstr[tint] = '\0';
+             for (tint = numimports - 2; tint>=0; tint--) {
+               if (!strcmp(imports[tint], tstr)) {
+                 --numimports;
+                 delete tstr;
+                 break;
+               }
+             }
+             srcstr = tmpstr2;
+           }
+           while ((*deststr++ = *srcstr++) != ';') ;
+         }
+       }
+     }
+   }
+   for (j = 0, i = methods_count; i--;) {
+     method_info *mip = methods[j++] = new method_info;
+     if (!mip) memerr();
+     method_info &mi = *mip;
+     mi.access_flags = get16(infile, &infile_pos);
+     char *tmpstr;
+     mi.name = cp[get16(infile, &infile_pos)]->chp;
+     mi.sig = cp[get16(infile, &infile_pos)]->chp;
+ 
+     //    int tmpindex;
+     tmpstr = mi.sig;
+     char *copytmpstr = tmpstr2 = strdup(tmpstr); if (!copytmpstr) memerr();
+     char *srcstr = tmpstr2, *deststr = tmpstr, *tmpstr3, *tmpstr4;
+     while ((*deststr++ = *srcstr++) != '\0') {
+       if (*(srcstr-1) == 'L') {
+         tmpstr3 = strchr(srcstr, ';'); if (!tmpstr3) fatalerror(UNKNOWN_ERR);
+         if (!strncmp(srcstr, "java/lang/", 10)) srcstr += 10;
+         else {
+           tmpstr2 = srcstr;
+           while (((tmpstr2 = strchr(tmpstr2,'/')) != 0)&&(tmpstr2 < tmpstr3)) *tmpstr2++ = '.';
+         }
+         if (package_name && !strncmp(srcstr, package_name, package_name_length)) srcstr += package_name_length + 1;
+         if (numimports!=imports_count && (tmpstr4 = strchr(srcstr, '.')) != 0 && tmpstr4 < tmpstr3) {
+           while (tmpstr4 != 0 && tmpstr4 < tmpstr3) { tmpstr2 = tmpstr4+1; tmpstr4 = strchr(tmpstr2,'.'); }
+           int tint = tmpstr3 - srcstr;
+           char *tstr = imports[numimports++] = new char[tint+1];
+           if (!tstr) memerr();
+           tstr = strncpy(tstr, srcstr, tint);
+           tstr[tint] = '\0';
+           for (tint = numimports - 2; tint>=0; tint--) {
+             if (!strcmp(imports[tint], tstr)) {
+               --numimports;
+               delete tstr;
+               break;
+             }
+           }
+           srcstr = tmpstr2;
+         }
+       }
+     }
+     mi.num_throws = 0;
+     mi.local_variable_table_length = 0;
+     mi.line_number_table_length = 0;
+     for (int l = get16(infile, &infile_pos); l--;) {
+       u16 attribute_name_index = get16(infile, &infile_pos);
+       u32 attribute_size = get32(infile, &infile_pos);
+       char *attribute_name = cp[attribute_name_index]->chp;
+       if (!strcmp(attribute_name,"Code")) {
+         mi.max_stack = (u8)get16(infile, &infile_pos);
+         mi.max_locals = (u8)get16(infile, &infile_pos);
+         if ((mi.code = new u8[mi.code_length = get32(infile, &infile_pos)]) == 0) memerr();
+         getstr(mi.code, mi.code_length, infile);
+         if (((mi.exception_table = new ExceptionTableEntry[mi.exception_table_length = get16(infile, &infile_pos)]) == 0) && mi.exception_table_length) memerr();
+         for (u16 n = 0, m = mi.exception_table_length; m--;) {
+           mi.exception_table[n].tag = TRY;
+           mi.exception_table[n].start_pc = get16(infile, &infile_pos);
+           mi.exception_table[n].end_pc = get16(infile, &infile_pos);
+           mi.exception_table[n].handler_pc = get16(infile, &infile_pos);
+           mi.exception_table[n++].catch_type = get16(infile, &infile_pos);
+         }
+         //        getstr(mi.exception_table, mi.exception_table_length << 3, infile);
+         for (int l2 = get16(infile, &infile_pos); l2--;) {
+           u16 attribute_name_index2 = get16(infile, &infile_pos);
+           u32 attribute_size2 = get32(infile, &infile_pos);
+           char *attribute_name2 = cp[attribute_name_index2]->chp;
+           if (!strcmp(attribute_name2,"LineNumberTable")) {
+             if ((mi.line_number_table = new LineNumberTableEntry[mi.line_number_table_length = get16(infile, &infile_pos)]) == 0) memerr();
+             getstr(mi.line_number_table, mi.line_number_table_length << 2, infile);
+           } else if (!strcmp(attribute_name2,"LocalVariableTable")) {
+             if ((mi.local_variable_table = new LocalVariableTableEntry[mi.local_variable_table_length = get16(infile, &infile_pos)]) == 0) memerr();
+             getstr(mi.local_variable_table, mi.local_variable_table_length * 10, infile);
+             if ((mi.local_names = new char*[2*mi.local_variable_table_length]) == 0) memerr();
+             int o;
+             for (o = mi.local_variable_table_length; o--;) {
+               char *tmpstr = cp[mi.local_variable_table[o].name_index]->chp;
+               if ((mi.local_names[mi.local_variable_table[o].slot] = new char[strlen(tmpstr) + 1]) == 0) memerr();
+               strcpy(mi.local_names[mi.local_variable_table[o].slot], tmpstr);
+             }
+             if ((mi.local_sigs = new char*[2*mi.local_variable_table_length]) == 0) memerr();
+             for (o = mi.local_variable_table_length; o--;) {
+               char *tmpstr = cp[mi.local_variable_table[o].signature_index]->chp;
+               if ((mi.local_sigs[mi.local_variable_table[o].slot] = new char[strlen(tmpstr) + 1]) == 0) memerr();
+               strcpy(mi.local_sigs[mi.local_variable_table[o].slot], tmpstr);
+             }
+           } else {
+             fprintf(stderr, "Skipping Unknown Code Attribute: %s (size %ld)\n", attribute_name2, attribute_size2);
+             for (int m = attribute_size2; m--;) get8(infile, &infile_pos);
+           }
+         }
+       } else if (!strcmp(attribute_name,"Exceptions")) {
+         int *tmpintptr;
+         if ((tmpintptr = mi.throws = new int[mi.num_throws = get16(infile, &infile_pos)]) == 0) memerr();
+         for (int m = mi.num_throws;m--;) *tmpintptr++ = get16(infile, &infile_pos); //*tmpstr++ = constant_pool[constant_pool[get16(infile)].i].cp;
+       } else {
+         fprintf(stderr, "Skipping Unknown Method Attribute: %s (size %ld)\n", attribute_name, attribute_size);
+         //      char *ti = new int[attribute_size], *tip = ti;
+         for (unsigned int m = 0; m++!=attribute_size;) printf("%02x%c", /**tip++ =*/ get8(infile, &infile_pos), (m%8)?' ':(m%16?'\n':'\t'));
+         printf("\n");
+         //      int tc = ti[0]<<8+ti[1]
+       }
+     }
+   }
+   imports_count = numimports;
+   for (j = 0, i = get16(infile, &infile_pos); i--;) {
+     u16 attribute_name_index = get16(infile, &infile_pos);
+     u32 attribute_size = get32(infile, &infile_pos);
+     char *attribute_name = cp[attribute_name_index]->chp;
+     if (!strcmp(attribute_name,"SourceFile")) {
+       if (attribute_size != 2) {
+         fprintf(stderr, "Bad size on SourceFile Attribute - should be 2!\n");
+         exit(1);
+       } else {
+         char *tmpstr = cp[get16(infile, &infile_pos)]->chp;
+         if ((source_name = new char[strlen(tmpstr) + 1]) == 0) memerr();
+         strcpy(source_name, tmpstr);
+       }
+     } else {
+       fprintf(stderr, "Skipping Unknown Attribute: %s (size %ld)\n", attribute_name, attribute_size);
+       for (u32 k = attribute_size; k--;) get8(infile, &infile_pos);
+     }
+   }
+ }
+ 
+ void Classfile::print() {
+   int i,j;
+   fprintf(stderr, "Compiled from %s\n", source_name);
+   fprintf(outfile, "/*\n** Compiled from %s - COPYRIGHT UNKNOWN.\n**\n"
+       "** Decompiled using the HomeBrew Decompiler\n"
+       "** Copyright (c) 1994-2003 Widget (aka Pete Ryland).\n"
+       "** Available under GPL from http://pdr.cx/hbd/\n*/\n\n", source_name);
+   if (package_name) fprintf(outfile, "package %s;\n\n", package_name);
+   char **strptr = imports;
+   for (i = imports_count; i--;) {
+     fprintf(outfile, "import %s;\n", *strptr++);
+   }
+   fprintf(outfile, "\n");
+   char *tmpstr = new char[access_flags.strlen() + 1];
+   fprintf(outfile, "%sclass %s ", access_flags.toString(tmpstr), this_class_name);
+   delete tmpstr;
+   if (super_class) {
+     if (!strcmp(tmpstr = cp(super_class)->chp, "Object")) {
+       super_class_name = "Object";
+     } else {
+       if ((super_class_name = new char[strlen(tmpstr) + 1]) == 0) memerr();
+       strcpy(super_class_name, tmpstr);
+       fprintf(outfile, "extends %s ", super_class_name);
+     }
+   }
+   if (interfaces_count) {
+     fprintf(outfile, "implements ");
+     for (j = 0, i = interfaces_count - 1; i--;) {
+       fprintf(outfile, "%s, ", cp(interfaces[j])->chp);
+     }
+     fprintf(outfile, "%s ", cp(interfaces[j])->chp);
+   }
+   fprintf(outfile, "{");
+   for (j = 0, i = fields_count; i--;) {
+     field_info &fi = *(fields[j++]);
+     tmpstr = new char[fi.access_flags.strlen() + 1];
+     fprintf(outfile, "\n  %s", fi.access_flags.toString(tmpstr));
+     delete tmpstr;
+     tmpstr = fi.sig;
+     printsigname(this, outfile, tmpstr, fi.name, 0);
+     if (fi.isconstant) {
+       fprintf(outfile, " = ");
+       char *chptr = fi.sig;
+       switch(*chptr++) {
+         case SIGNATURE_INT:
+           fprintf(outfile, "0x%lX", cp[fi.constval_index]->i);
+           break;
+         case SIGNATURE_LONG:
+           if(cp[fi.constval_index]->i) {
+             fprintf(outfile, "0x%lX%08lXL", cp[fi.constval_index]->i,
+                 cp[(u16)((i16)fi.constval_index + 1)]->i);
+           } else {
+             fprintf(outfile, "0x%lXL", cp[(u16)((i16)fi.constval_index + 1)]->i);
+           }
+           break;
+         case SIGNATURE_FLOAT:
+           fprintf(outfile, "%#.100Gf", cp[fi.constval_index]->f);
+           break;
+         case SIGNATURE_DOUBLE:
+           fprintf(outfile, "%#.100Gd",(float)*(double*)(cp[fi.constval_index]->i));
+           break;
+         default:
+           fprintf(stderr, "Bad type for constant\n");
+       }
+     }
+     fprintf(outfile, ";");
+   }
+   for (j = 0, i = methods_count; i--;) {
+     if (decompileblock(this, methods[j++])) fprintf(outfile, "/* Decompilation Error.  Continuing... */");
+   }
+   fprintf(outfile, "\n}");
+   return;
+ }


Index: llvm/test/Programs/MultiSource/Applications/hbd/class.h
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/class.h:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/class.h	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,105 ----
+ /* class.h */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #ifndef CLASS_H
+ #define CLASS_H
+ 
+ #include <stdio.h>
+ #include "options.h"
+ #include "version.h"
+ #include "cp.h"
+ #include "access.h"
+ #include "general.h"
+ #include "field.h"
+ #include "method.h"
+ 
+ /* The master classfile structure. */
+ struct Classfile {
+   /* The input and output files */
+   FILE *infile, *outfile;
+ 
+   /* These keeps a tab on where in the files we are */
+   int infile_pos, outfile_pos;
+ 
+   /* The command-line options we are using */
+   CL_Options options;
+   
+   /* The basic class file format starts from here */
+ 
+   /* The class version - should always be 45.3 */
+   ClassVersion version;
+ 
+   /* The Constant Pool */
+   ConstPool cp;
+ 
+   /* The access modifiers for this class */
+   AccessFlags access_flags;
+ 
+   /* An index into the constant pool of the name
+      of this class. */
+   u16 this_class;
+ 
+   /* This contains the name of the package for this class,
+      resolved from the above constant-pool reference */
+   char *package_name;
+ 
+   /* This contains the name of the actual class,
+      resolved from the above constant-pool reference */
+   char *this_class_name;
+ 
+   /* This is an index into the constant pool for the name
+      of the parent class */
+   u16 super_class;
+ 
+   /* The resolved string */
+   char *super_class_name;
+ 
+   /* This table contains indexes into the constant pool
+      for the interfaces that this class implements */
+   u16 interfaces_count;
+   u16 *interfaces;
+ 
+   /* This table contains the fields in this class */
+   u16 fields_count;
+   field_info_ptr *fields;
+ 
+   /* This table contains the methods in this class */
+   u16 methods_count;
+   method_info_ptr *methods;
+ 
+   /* The name of the source file from which this
+      class was compiled.  This is determined from
+      the SourceFile attribute. */
+   char *source_name;
+ 
+   /* This table holds the import statements that this
+      class would have needed to enable it to refer to
+      all the classes it uses without referring to
+      their package name.  It is determined from clues
+      the parser finds along the way. */
+   u16 imports_count;
+   char **imports;
+ 
+   /* The function that the translator will be inserting
+      the code for */
+   char *functoinsert;
+ 
+   /* The constructor, which will parse the command-line
+      arguments */
+   Classfile(int argc, char **argv);
+ 
+   /* The read() and print() methods are only used by the
+      decompiler */
+   /* The read() method parses the input file */
+   void read();
+   /* print() decompiles and prints the decompilation
+      of the class */
+   void print();
+ };
+ 
+ #endif


Index: llvm/test/Programs/MultiSource/Applications/hbd/config.h
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/config.h:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/config.h	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,53 ----
+ /* src/config.h.  Generated by configure.  */
+ /* src/config-h.in.  Generated from configure.in by autoheader.  */
+ 
+ /* Define to 1 if you have the <inttypes.h> header file. */
+ #define HAVE_INTTYPES_H 1
+ 
+ /* Define to 1 if you have the <memory.h> header file. */
+ #define HAVE_MEMORY_H 1
+ 
+ /* Define to 1 if you have the <stdint.h> header file. */
+ #define HAVE_STDINT_H 1
+ 
+ /* Define to 1 if you have the <stdlib.h> header file. */
+ #define HAVE_STDLIB_H 1
+ 
+ /* Define to 1 if you have the <strings.h> header file. */
+ #define HAVE_STRINGS_H 1
+ 
+ /* Define to 1 if you have the <string.h> header file. */
+ #define HAVE_STRING_H 1
+ 
+ /* Define to 1 if you have the <sys/stat.h> header file. */
+ #define HAVE_SYS_STAT_H 1
+ 
+ /* Define to 1 if you have the <sys/types.h> header file. */
+ #define HAVE_SYS_TYPES_H 1
+ 
+ /* Define to 1 if you have the <unistd.h> header file. */
+ #define HAVE_UNISTD_H 1
+ 
+ /* Name of package */
+ #define PACKAGE "hbd"
+ 
+ /* Define to the address where bug reports for this package should be sent. */
+ #define PACKAGE_BUGREPORT ""
+ 
+ /* Define to the full name of this package. */
+ #define PACKAGE_NAME ""
+ 
+ /* Define to the full name and version of this package. */
+ #define PACKAGE_STRING ""
+ 
+ /* Define to the one symbol short name of this package. */
+ #define PACKAGE_TARNAME ""
+ 
+ /* Define to the version of this package. */
+ #define PACKAGE_VERSION ""
+ 
+ /* Define to 1 if you have the ANSI C header files. */
+ #define STDC_HEADERS 1
+ 
+ /* Version number of package */
+ #define VERSION "0.2.3"


Index: llvm/test/Programs/MultiSource/Applications/hbd/consts.h
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/consts.h:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/consts.h	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,28 ----
+ /* consts.h */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #ifndef CONSTS_H
+ #define CONSTS_H
+ 
+ /* These are the tags that the constant pool uses. */
+ enum {
+     CONSTANT_Utf8 = 1,
+     CONSTANT_Unicode,   /* unused */
+     CONSTANT_Integer,
+     CONSTANT_Float,
+     CONSTANT_Long,      
+     CONSTANT_Double,
+     CONSTANT_Class,
+     CONSTANT_String,
+     CONSTANT_Fieldref,
+     CONSTANT_Methodref,
+     CONSTANT_InterfaceMethodref,
+     CONSTANT_NameAndType
+ };
+ 
+ #endif


Index: llvm/test/Programs/MultiSource/Applications/hbd/cp.cpp
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/cp.cpp:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/cp.cpp	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,83 ----
+ /* cp.cpp */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #include "general.h"
+ #include "cp.h"
+ #include "file.h"
+ #include "err.h"
+ #include "class.h"
+ #include "consts.h"
+ 
+ void ConstPool::read(Classfile *c, u16 *imports_count) {
+   if ((constant_pool = new cp_info[(constant_pool_count = get16(c->infile, &c->infile_pos))]) == 0) memerr();
+   for (int j = 1, i = constant_pool_count - 1; i--;) {
+     cp_info *cpi = &constant_pool[j++];
+     cpi->tag = (unsigned char)get8(c->infile, &c->infile_pos);
+     unsigned short size;
+     D(fprintf(c->outfile, "\npos: 0x%05X\tindex: %4d\t",c->infile_pos,j-1))
+       switch(cpi->tag) {
+         case CONSTANT_Utf8:
+           if ((cpi->chp = new char[(size = get16(c->infile, &c->infile_pos)) + 1]) == 0) memerr();
+           getstr(cpi->chp, size, c->infile);
+           cpi->chp[size] = '\0';
+           D(fprintf(c->outfile, "UTF8: %s\t", cpi->chp))
+           break;
+         case CONSTANT_Unicode: D(fprintf(c->outfile, "Unicode\t")) /* unused */
+           break;
+         case CONSTANT_Integer:
+           cpi->i = get32(c->infile, &c->infile_pos);
+           D(fprintf(c->outfile, "32-bit int: 0x%8lX\t", cpi->i))
+           break;
+         case CONSTANT_Float:
+           cpi->i = get32(c->infile, &c->infile_pos);
+           D(fprintf(c->outfile, "32-bit float: %.25G\t", cpi->f))
+           break;
+         case CONSTANT_Long:
+           cpi->i = get32(c->infile, &c->infile_pos);
+           cpi = &constant_pool[j++];
+           cpi->tag = 0;
+           cpi->i = get32(c->infile, &c->infile_pos);
+           D(((cpi - 1)->i) ? fprintf(c->outfile, "64-bit int: 0x%lX%08lX", (cpi - 1)->i, cpi->i) : fprintf(c->outfile, "64-bit int: 0x%lX", cpi->i))
+           if (i--) continue;
+           break;
+         case CONSTANT_Double:
+           *(((unsigned long *)&cpi->i) + 1) = get32(c->infile, &c->infile_pos);
+           cpi->i = get32(c->infile, &c->infile_pos);
+           D(fprintf(c->outfile, "64-bit float: %.25G\t",(float)*(double*)(&cpi->i))) constant_pool[j++].tag = 0;
+           if (i--) continue;
+           break;
+         case CONSTANT_Class:
+           imports_count++;
+           cpi->i = get16(c->infile, &c->infile_pos);
+           D(fprintf(c->outfile, "Class: name = index %d\t", (int)cpi->i))
+           break;
+         case CONSTANT_String:
+           cpi->i = get16(c->infile, &c->infile_pos);
+           D(fprintf(c->outfile, "String: index %d\t", (int)cpi->i))
+           break;
+         case CONSTANT_Fieldref:
+         case CONSTANT_Methodref:
+         case CONSTANT_InterfaceMethodref:
+            if ((cpi->p = new Ref) == 0) memerr();
+            ((Ref*)cpi->p)->class_index = get16(c->infile, &c->infile_pos);
+            ((Ref*)cpi->p)->name_and_type = get16(c->infile, &c->infile_pos);
+            D(fprintf(c->outfile, "Ref: class_index %d, n&t_index %d\t", ((Ref*)cpi->p)->class_index, ((Ref*)cpi->p)->name_and_type))
+            break;
+         case CONSTANT_NameAndType:
+           imports_count++;
+           if ((cpi->p = new NameAndType) == 0) memerr();
+           ((NameAndType*)cpi->p)->name_index = get16(c->infile, &c->infile_pos);
+           ((NameAndType*)cpi->p)->signature_index = get16(c->infile, &c->infile_pos);
+           D(fprintf(c->outfile, "Name&Type: name_index %d, sig_index %d\t", ((NameAndType*)cpi->p)->name_index, ((NameAndType*)cpi->p)->signature_index))
+           break;
+         default:
+           fprintf(stderr, "Error reading constant pool entry %d of %d at file pos 0x%08x!\n", j, constant_pool_count, c->infile_pos);
+           fatalerror(CP_ERR);
+       }
+   }
+ }


Index: llvm/test/Programs/MultiSource/Applications/hbd/cp.h
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/cp.h:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/cp.h	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,68 ----
+ /* cp.h */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #ifndef CP_H
+ #define CP_H
+ 
+ #include "general.h"
+ 
+ /* These are structures that the constant pool's table
+    can contain. */
+ 
+ typedef struct {
+   u16 class_index;
+   u16 name_and_type;
+ } Ref;
+ 
+ typedef struct {
+   u16 name_index;
+   u16 signature_index;
+ } NameAndType;
+ 
+ /* The generic structure of constants that will appear
+    in the table of constants in the constant pool */
+ struct cp_info {
+   unsigned char tag;
+   union {
+     long i;
+     void *p;
+     double d;
+     float f;
+     char *chp;
+   };
+ };
+ 
+ /* Forward declaration of the Classfile struct */
+ struct Classfile;
+ 
+ /* The ConstPool struct, which contains the Constant
+    Pool. */
+ struct ConstPool {
+   /* The number of entries in this Constant Pool */
+   u16 constant_pool_count;
+ 
+   /* The table of constants */
+   cp_info *constant_pool;
+ 
+   /* This will parse the input file for a constant pool */
+   void read(Classfile *c, u16 *imports_count);
+ 
+   /* These methods provide easy access to commonly
+      used parts of constant pool entries */
+   cp_info *operator [](u16 i) {
+     return &(constant_pool[i]);
+   }
+   cp_info *operator ()(u16 i) {
+     return &(constant_pool[constant_pool[i].i]);
+   }
+   u16 count() {
+     return constant_pool_count;
+   }
+ };
+ 
+ #endif


Index: llvm/test/Programs/MultiSource/Applications/hbd/d1-pushc.cpp
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/d1-pushc.cpp:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/d1-pushc.cpp	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,80 ----
+ /* d1-pushc.cpp */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #include <stdio.h>
+ #include "exp.h"
+ #include "class.h"
+ #include "decomp.h"
+ #include "cp.h"
+ #include "consts.h"
+ 
+ int pushimm(Classfile *c) /* push immediate value e.g. bipush 34 */
+ {
+   int pcval = currpc - 1;
+   int val = JDNEXT8S();
+   if (ch == 0x11) { val<<=8; val+=JDNEXT8U(); }
+   char *temp_str = new char[32];
+   sprintf(temp_str, "%i", val);
+   *stkptr++ = new Exp(pcval, temp_str, INT, IM); /* id->linfo = val */
+   return 0;
+ }
+ 
+ int pushconst(Classfile *c) /* push value from cp e.g. ldc1 #3 */
+ {
+   int pcval = currpc - 1;
+   int val = JDNEXT8U();
+   if (ch != 0x12) { val<<=8; val+=JDNEXT8U(); }
+   Type idtype;
+   char tmpstr[1024];
+   cp_info *cpi = c->cp[val];
+   switch (cpi->tag) {
+     case CONSTANT_Integer:
+       sprintf(tmpstr, "0x%lX", cpi->i);
+       idtype = INT;
+ //      id->linfo = cpi->i;
+       break;
+     case CONSTANT_Long:
+       if (cpi->i)
+ 	sprintf(tmpstr, "0x%lX%08lXL", cpi->i, (cpi + 1)->i);
+       else
+ 	sprintf(tmpstr, "0x%lXL", (cpi + 1)->i);
+       idtype = LONG;
+ //      id->linfo = (cpi + 1)->i;
+ //      id->llinfo[2] = cpi->i;
+       break;
+     case CONSTANT_Float:
+       sprintf(tmpstr, "%.25Gf", cpi->f);
+       idtype = FLOAT;
+ //      id->dinfo = cpi->f;
+       break;
+     case CONSTANT_Double:
+       sprintf(tmpstr, "%.25Gd", *(double *)&cpi->i);
+       idtype = DOUBLE;
+ //      id->dinfo = *(double*)&cpi->i;
+       break;
+     case CONSTANT_String:
+       sprintf(tmpstr, "\"%s\"", c->cp[cpi->i]->chp);
+       idtype = OBJECT; /* java.lang.String */
+ //      id->dinfo = (int)c->cp[cpi->i]->chp;
+       break;
+     default:
+       fprintf(stderr, "Unkown tag %d on constant\n", cpi->tag);
+       return -1;
+   }
+   char *idname = new char[strlen(tmpstr) + 1];
+   strcpy(idname, tmpstr);
+   *stkptr++ = new Exp(pcval, idname, idtype, CP, val);
+   return 0;
+ }
+ 
+ int pushimp(Classfile *c) /* push implied immediate value e.g. iconst_m1 */
+ {
+   *stkptr++ = new Exp(currpc - 1, ch - 1);
+   return 0;
+ }
+ 


Index: llvm/test/Programs/MultiSource/Applications/hbd/d2-pushl.cpp
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/d2-pushl.cpp:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/d2-pushl.cpp	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,60 ----
+ /* d2-pushl.cpp */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #include "general.h"
+ #include "exp.h"
+ #include "decomp.h"
+ #include "method.h"
+ 
+ int pushlocal(Classfile *c) /* push value from local (or params) */
+ {
+   int pcval = currpc - 1;
+   int val;
+   Type idtype = VOID;
+   if (ch < 0x1A) {
+     val = JDNEXT8S();
+     switch (ch) {
+       case 0x15: idtype = INT; break;
+       case 0x16: idtype = LONG; break;
+       case 0x17: idtype = FLOAT; break;
+       case 0x18: idtype = DOUBLE; break;
+       case 0x19: idtype = OBJECT; break;
+     }
+   } else if (ch < 0x1E) {
+     val = ch - 0x1A;
+     idtype = INT;
+   } else if (ch < 0x22) {
+     val = ch - 0x1E;
+     idtype = LONG;
+   } else if (ch < 0x26) {
+     val = ch - 0x22;
+     idtype = FLOAT;
+   } else if (ch < 0x2A) {
+     val = ch - 0x26;
+     idtype = DOUBLE;
+   } else /* if (ch < 0x2E) */ {
+     val = ch - 0x2A;
+     idtype = OBJECT;
+   }
+   char *tmpstr = miptr->local_names[val], *idname;
+   if (tmpstr) {
+     idname = new char[strlen(tmpstr) + 1];
+     strcpy(idname, tmpstr);
+   } else {
+     fprintf(stderr, "Error in code: local used before defined.\n");
+     return 1;
+   }
+   Exp *e = new Exp(pcval, idname, idtype, LO, val);
+ //  if((lastaction == 16)&&(!strcmp((*(donestkptr-1))->exp1->e->id->name,id->name))) {
+ //    *stkptr++ = *(--donestkptr);
+     *stkptr++ = e;
+ //  } else {
+ //    *stkptr++ = e;
+ //  }
+   return 0;
+ }


Index: llvm/test/Programs/MultiSource/Applications/hbd/d3-popl.cpp
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/d3-popl.cpp:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/d3-popl.cpp	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,116 ----
+ /* d3-popl.cpp */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #include <stdlib.h>
+ #include "exp.h"
+ #include "class.h"
+ #include "decomp.h"
+ #include "cp.h"
+ 
+ int storelocal(Classfile *c) /* pop value to local (including params) */
+ {
+   unsigned pcval = currpc - 1;
+   int val;
+   Type idtype = VOID;
+   if (ch < 0x3B) {
+     switch (ch) {
+       case 0x36: idtype = INT; break;
+       case 0x37: idtype = LONG; break;
+       case 0x38: idtype = FLOAT; break;
+       case 0x39: idtype = DOUBLE; break;
+       case 0x3A: idtype = OBJECT; break;
+     }
+     val = JDNEXT8S();
+   } else if (ch < 0x3F) {
+     val = ch - 0x3B;
+     idtype = INT;
+   } else if (ch < 0x43) {
+     val = ch - 0x3F;
+     idtype = LONG;
+   } else if (ch < 0x47) {
+     val = ch - 0x43;
+     idtype = FLOAT;
+   } else if (ch < 0x4B) {
+     val = ch - 0x47;
+     idtype = DOUBLE;
+   } else {
+     val = ch - 0x4B;
+     idtype = OBJECT;
+   }
+ //  if (val) {
+     char *tmpstr = miptr->local_names[val], *idname;
+     if (tmpstr) {
+       idname = new char[strlen(tmpstr) + 1];
+       strcpy(idname, tmpstr);
+       idtype = miptr->local_types[val];
+     } else {
+       idname = miptr->local_names[val] = new char[7];
+       sprintf(idname, "var%d", val);
+       if ((miptr->local_types[val] == VOID)||(miptr->local_types[val] == UNKNOWN)) {
+ 	if (idtype != INT)
+ 	  miptr->local_types[val] = idtype;
+ 	else
+ 	  miptr->local_types[val] = UNKNOWN;
+       }
+     }
+   Exp *e1 = new Exp(pcval, idname, idtype, LO, val);
+   Exp *e2 = *(--stkptr);
+   Exp *e = new Exp(pcval, min(pcval, e2->minpc), BINARY, idtype, ASSIGN, e1, e2);
+   if (!tmpstr) miptr->local_firstuses[val] = e->minpc;
+   if ((e2->e->type == INT) && (e1->e->type == BOOLEAN))
+     if ((e2->e == std_exps + 2)||(e2->e == std_exps + 3)) /* 0 or 1 */
+       e2->e += 13; /* false or true */
+     else
+       /* CMPEQ */;
+   *donestkptr++ = e;
+   return 0;
+ }
+ 
+ int iinclocal(Classfile *c) /* increment local by value */
+ {
+   int pcval = currpc - 1;
+   int val;
+   val = JDNEXT8S();
+   char *id1name;
+   char *tmpstr = miptr->local_names[val];
+   if (tmpstr) {
+ //    id1name = new char[strlen(tmpstr) + 1];
+ //    strcpy(id1name, tmpstr);
+     id1name = tmpstr;
+   } else {
+     printf("Local int used before defined.\n");
+     return 1;
+   }
+   if (miptr->local_types[val] == UNKNOWN) miptr->local_types[val] = INT;
+ //  if (miptr->local_types[val] == UNKNOWN) miptr->local_types[val] = INT;
+ //  if (miptr->local_types[val] == VOID) miptr->local_types[val] = INT;
+   if ((miptr->local_types[val] != INT)&&(miptr->local_types[val] != SHORT)) {
+     printf("Incrementation of local var%d of type %d i.e. %s.\n", val, miptr->local_types[val], type2str[miptr->local_types[val]]);
+     return 1;
+   }
+   int incnum = JDNEXT8S();
+ //  id2->linfo = incnum;
+   Exp *e;
+   if ((incnum!=1)&&(incnum!=-1)) {
+     Exp *e1 = new Exp(pcval, id1name, INT, LO, val);
+     char *id2name = new char[5]; sprintf(id2name, "%ld", labs(incnum));
+     Exp *e2 = new Exp(pcval, id2name, INT, IM);
+     e = new Exp(pcval, BINARY, INT, (incnum<0)?SUBASSIGN:ADDASSIGN, e1, e2);
+   } else {
+     Exp *e1 = new Exp(pcval, id1name, INT, LO, val);
+     e = new Exp(pcval, PREUNARY, INT, (incnum<0)?DEC:INC, e1);
+   }
+ 
+   if ((lastaction == 4)&&(!strcmp((*(stkptr-1))->e->id->name,id1name))) {
+     e->e->et = POSTUNARY; e->minpc = min(e->minpc, (*(stkptr-1))->minpc);
+     *(stkptr-1) = e;
+   } else {
+     *donestkptr++ = e;
+   }
+   return 0;
+ }


Index: llvm/test/Programs/MultiSource/Applications/hbd/d4-array.cpp
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/d4-array.cpp:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/d4-array.cpp	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,68 ----
+ /* d4-array.cpp */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #include "exp.h"
+ #include "class.h"
+ #include "decomp.h"
+ #include "cp.h"
+ 
+ int anewarray(Classfile *c)
+ {
+   unsigned pcval = currpc - 1;
+   int val = JDNEXT16U();
+   char *class_name = c->cp(val)->chp;
+   Exp *e1 = new Exp(pcval, class_name, VOID, NO);
+   Exp *e2 = new Exp(pcval, ARRAYACCESS, VOID, ID, e1, *(stkptr-1));
+   *(stkptr-1) = new Exp(pcval, min(pcval, e2->exp2->minpc), PREUNARY, ARRAY, NEW, e2);
+   return 0;
+ }
+ 
+ int multianewarray(Classfile *c)
+ {
+   printf("Multi");
+   unsigned pcval = currpc - 1;
+   /*int val = */JDNEXT16U();
+ //  char *class_name; // = c->constant_pool[c->constant_pool[val].i].cp;
+ //  for (val = JDNEXT8U(); val--;) {
+ //    --stkptr;
+ //  } stkptr++;
+   Exp *e1 = *(stkptr-1);
+   *(stkptr-1) = new Exp(pcval, min(pcval, e1->minpc), PREUNARY, ARRAY, NEW, e1);
+   return 0;
+ }
+ 
+ int doarraylength(Classfile *c) /* 190 == 0xBE */
+ {
+   unsigned pcval = currpc - 1;
+   Exp *e1 = *(stkptr-1);
+   Exp *e2 = new Exp(pcval, "length", VOID, NO);
+   *(stkptr-1) = new Exp(pcval, min(pcval, e1->minpc), BINARY, INT, DOT, e1, e2);
+   return 0;
+ }
+ 
+ int doarrayget(Classfile *c)
+ {
+   unsigned pcval = currpc - 1;
+   Exp *e2 = *(--stkptr);
+   Exp *e1 = *(stkptr-1);
+   *(stkptr-1) = new Exp(pcval, min(min(pcval, e1->minpc), e2->minpc), ARRAYACCESS,
+                         (Type)(ch - (0x2E - INT)), ID, e1, e2);
+   return 0;
+ }
+ 
+ int doarrayput(Classfile *c)
+ {
+   unsigned pcval = currpc - 1;
+   Exp *e4 = *(--stkptr);
+   Exp *e3 = *(--stkptr);
+   Exp *e2 = *(--stkptr);
+   unsigned minpcval = min(min(pcval, e2->minpc), e3->minpc);
+   Exp *e1 = new Exp(pcval, minpcval, ARRAYACCESS, OBJECT, ID, e2, e3);
+   *donestkptr++ = new Exp(pcval, minpcval, BINARY, OBJECT, ASSIGN, e1, e4);
+   return 0;
+ }


Index: llvm/test/Programs/MultiSource/Applications/hbd/d5-stack.cpp
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/d5-stack.cpp:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/d5-stack.cpp	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,39 ----
+ /* d5-stack.cpp */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #include "exp.h"
+ #include "class.h"
+ #include "decomp.h"
+ #include "cp.h"
+ 
+ int dopop(Classfile *c)
+ {
+   if (stkptr != stack) *donestkptr++ = *(--stkptr);
+   return 0;
+ }
+ 
+ 
+ int dodup(Classfile *c)
+ {
+   if ((*(stkptr-1))->e->op != NEW) {
+     *stkptr = *(stkptr-1);
+     (*stkptr)->numrefs++;
+     stkptr++;
+   }
+   return 0;
+ }
+ 
+ int dodup_x1(Classfile *c)
+ {
+   *stkptr = *(stkptr-1);
+   *(stkptr-1) = *(stkptr-2);
+   *(stkptr-2) = *stkptr;
+   (*stkptr)->numrefs++;
+   stkptr++;
+   return 0;
+ }


Index: llvm/test/Programs/MultiSource/Applications/hbd/d6-arith.cpp
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/d6-arith.cpp:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/d6-arith.cpp	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,99 ----
+ /* d6-arith.cpp */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #include "exp.h"
+ #include "class.h"
+ #include "decomp.h"
+ #include "cp.h"
+ 
+ extern int cond_pcend;
+ extern Exp *cond_e;
+ extern Exp *cond_e2;
+ extern Exp **cond_donestkptr;
+ extern Exp **cond_stkptr;
+ 
+ int pushbinop(Classfile *c) /* push binary operation, popping operands e.g. lxor */
+ {
+   unsigned pcval = currpc - 1;
+   Exp *e2 = *(--stkptr);
+   Exp *e1 = *(stkptr-1);
+   *(stkptr-1) = new Exp(pcval, min(min(e1->minpc, e2->minpc), pcval), BINARY,
+                         e1->e->type,
+                         (Op)((ch < 0x74)?
+                           ((ch - 0x60) >> 2) : (0x07 + ((ch - 0x78) >> 1))),
+                         e1, e2);
+   return 0;
+ }
+ 
+ int pushunop(Classfile *c) /* push unary operation, popping operand e.g. lneg */
+ {
+   unsigned pcval = currpc - 1, branch_pc;
+   char *tmpstr, *buff;
+   Exp *e1 = *(stkptr-1);
+   Op eop = CAST;
+   Type etype = VOID;
+   int val;
+   switch (ch) {
+     case 0x74: case 0x75: case 0x76: case 0x77: eop = NEG; etype = e1->e->type; break;
+     case 0x88: case 0x8B: case 0x8E: etype = INT; break;
+     case 0x85: case 0x8C: case 0x8F: etype = LONG; break;
+     case 0x86: case 0x89: case 0x90: etype = FLOAT; break;
+     case 0x87: case 0x8A: case 0x8D: etype = DOUBLE; break;
+     case 0x91: etype = BYTE; break;
+     case 0x92: etype = CHAR; break;
+     case 0x93: etype = SHORT; break;
+     case 0xBF:
+       --stkptr;
+       *donestkptr++ = new Exp(pcval, min(e1->minpc, pcval), PREUNARY, VOID, THROW, e1);
+       return 0;
+     case 0xBB:
+       val = JDNEXT16U();
+       tmpstr = c->cp(val)->chp;
+       buff = new char[strlen(tmpstr) + 1]; strcpy(buff, tmpstr);
+       e1 = new Exp(pcval, buff, VOID, CP, val);
+       *(stkptr++) = new Exp(pcval, min(e1->minpc, pcval), PREUNARY, OBJECT, NEW, e1);
+ //      if ((ch = JDNEXT8()) == 0x59)
+ //	return actiontable[actions[ch = JDNEXT8()]]();
+ //      else
+ //	return actiontable[actions[ch]]();
+     case 0xBA: eop = NEW; break;
+     case 0xA7: /* GOTO really shouldn't be here! */
+       if (stkptr!=stack) {
+ //	if (stkptr!=(stack+1)) { fprintf(stderr, "Error in conditional operator!\n"); return 1; }
+ 	if (cond_pcend != -1) { fprintf(stderr, "Can't handle recursive conditional operators!\n"); return 1; }
+ 	cond_pcend = pcval + JDNEXT16S();
+ 	cond_stkptr = stkptr;
+ 	cond_e2 = *(--stkptr);
+ 	--donestkptr;
+ 	if ((*donestkptr)->e->et == BRANCH) {
+ 	  if ((*donestkptr)->branch_pc != currpc) {
+ 	    fprintf(stderr, "Error in conditional operator!\n"); return 1;
+ 	  }
+ 	  cond_e = *donestkptr;
+ 	} else {
+ 	  fprintf(stderr, "Use of comma operator in conditionals not yet supported.\n");
+ 	  return 1;
+ 	}
+ 	cond_donestkptr = donestkptr;
+ 	return 0;
+       }
+       branch_pc = pcval + JDNEXT16S();
+       tmpstr = new char[100];
+       sprintf(tmpstr,"label%i", branch_pc);
+       buff = new char[strlen(tmpstr) + 1]; strcpy(buff, tmpstr);
+       delete tmpstr;
+       e1 = new Exp(pcval, buff, VOID/*label*/, IM);
+       *donestkptr++ = new Exp(pcval, PREUNARY, VOID, GOTO, e1, branch_pc);
+       return 0;
+     default:
+       fprintf(stderr, "Error in pushing unary operation\n");
+       exit(-1);
+   }
+   *(stkptr-1) = new Exp(pcval, min(e1->minpc, pcval), PREUNARY, etype, eop, e1);
+   return 0;
+ }


Index: llvm/test/Programs/MultiSource/Applications/hbd/d7-cntrl.cpp
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/d7-cntrl.cpp:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/d7-cntrl.cpp	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,84 ----
+ /* d7-cntrl.cpp */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #include "exp.h"
+ #include "class.h"
+ #include "decomp.h"
+ #include "cp.h"
+ 
+ int cond_pcend;
+ Exp *cond_e;
+ Exp *cond_e2;
+ Exp **cond_donestkptr;
+ Exp **cond_stkptr;
+ 
+ int doif1(Classfile *c)
+ {
+   unsigned pcval = currpc - 1;
+   Exp *e = *(--stkptr), *e1, *e2;
+   switch (e->e->type) {
+     case CMPTYPE:
+       if (e->e->op != CMP) { fprintf(stderr, "doif1 error\n"); return 1; }
+       e->e->op = (Op)(EQUAL + ch - 0x99); e->e->type = BOOLEAN;
+       break;
+     case BOOLEAN:
+       if (ch == 0x99) // ifeq (ie if false)
+         if (notexp(&e)) { fprintf(stderr, "doif1 error\n"); return 1; }
+       break;
+     case INT:
+       e1 = *stkptr; e2 = new Exp(pcval, I0EXP);
+       e = new Exp(pcval, e1->minpc, BINARY, BOOLEAN, (Op)(EQUAL + ch - 0x99), e1, e2);
+       break;
+     case OBJECT:
+       e1 = *stkptr; e2 = new Exp(pcval, NULLEXP);
+       e = new Exp(pcval, e1->minpc, BINARY, BOOLEAN, (Op)(EQUAL + ch - 0xC6), e1, e2);
+       break;
+     default:
+       break;
+   }
+   *donestkptr++ = new Exp(pcval, e->minpc, IFEXP, e, pcval + JDNEXT16S());
+   return 0;
+ }
+ 
+ int doif2(Classfile *c)
+ {
+   unsigned pcval = currpc - 1;
+   Exp *e2 = *(--stkptr);
+   Exp *e1 = *(--stkptr);
+   Exp *e = new Exp(pcval, min(e1->minpc, e2->minpc), BINARY, BOOLEAN,
+                    (Op)(EQUAL + ((ch - 0x9F) % 6)), e1, e2);
+   *donestkptr++ = new Exp(pcval, e->minpc, /*std_exp*/IFEXP, e,
+                           /*branch_pc*/pcval + JDNEXT16S());
+   return 0;
+ }
+ 
+ int docmp(Classfile *c)
+ {
+   unsigned pcval = currpc - 1;
+   Exp *e2 = *(--stkptr);
+   Exp *e1 = *(stkptr-1);
+   *(stkptr-1) = new Exp(pcval, min(e1->minpc, e2->minpc), BINARY, CMPTYPE, CMP, e1, e2);
+   return 0;
+ }
+ 
+ int finishconditional(Classfile *c) {
+   if ((stkptr != cond_stkptr) || (donestkptr != cond_donestkptr))
+     { fprintf(stderr, "Error cond\n"); return 1; }
+   cond_e->e++;
+   if ((cond_e->exp1->e->op > LESSOREQUAL) || (cond_e->exp1->e->op < EQUAL)) {
+     if (cond_e->exp1->e->type != BOOLEAN) { fprintf(stderr, "Can't not a non-boolean\n"); return 1; }
+     Exp *e1 = cond_e->exp1;
+     cond_e->exp1 = new Exp(currpc, e1->minpc, PREUNARY, BOOLEAN, NOT_BOOL, e1);
+   } else {
+     *((int*)(&cond_e->exp1->e->op)) ^= 1;
+   }
+   cond_e->exp2 = cond_e2; cond_e->exp3 = *(stkptr-1);
+   *(stkptr-1) = cond_e;
+   cond_pcend = -1;
+   return 0;
+ }


Index: llvm/test/Programs/MultiSource/Applications/hbd/d8-ret.cpp
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/d8-ret.cpp:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/d8-ret.cpp	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,35 ----
+ /* d8-ret.cpp */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #include "exp.h"
+ #include "class.h"
+ #include "decomp.h"
+ #include "cp.h"
+ 
+ int doreturn(Classfile *c) /* push return op, popping operand e.g. ireturn LO3 */
+ {
+   unsigned pcval = currpc - 1;
+   if (ch == 0xB1) {
+     if (bufflength > 0) {
+       Exp *e1 = new Exp(pcval, "/* void */", VOID, IM);
+       *donestkptr++ = new Exp(pcval, PREUNARY, VOID, RETURN, e1);
+     }
+   } else {
+     Exp *e1 = *(stkptr-1);
+     if ((e1->e->type == INT) && (miptr->ret_type == BOOLEAN)) {
+       if ((e1->e == std_exps + 2)||(e1->e == std_exps + 3))
+ 	e1->e += 13; /* convert 0 or 1 to false or true */
+       else
+ 	/* CMPEQ */;
+     }
+     --stkptr;
+     *donestkptr++ = new Exp(pcval, min(pcval, e1->minpc), PREUNARY, VOID, RETURN, e1);
+   }
+   return 0;
+ }
+ 


Index: llvm/test/Programs/MultiSource/Applications/hbd/d9-swtch.cpp
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/d9-swtch.cpp:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/d9-swtch.cpp	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,43 ----
+ /* d9-swtch.cpp */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #include "exp.h"
+ #include "class.h"
+ #include "decomp.h"
+ #include "cp.h"
+ 
+ int dotableswitch(Classfile *c)
+ {
+   unsigned pcval = currpc - 1;
+   while(currpc%4) JDNEXT8U();
+   Exp *e1 = *(--stkptr);
+   unsigned defaultpc = JDNEXT32S();
+   unsigned low = JDNEXT32S(), high = JDNEXT32S(), numcases = high - low + 1;
+   Case *tcase = new Case[numcases];
+   *donestkptr++ = new Exp(pcval, e1->minpc, SWITCH, VOID, ID, e1, defaultpc, numcases, tcase);
+   for (unsigned m = low; m <= high;) {
+      tcase->caseval = m++;
+      (tcase++)->branch_pc = JDNEXT32S();
+    }
+   return 0;
+ }
+ 
+ int doluswitch(Classfile *c)
+ {
+   unsigned pcval = currpc - 1;
+   while(currpc%4) JDNEXT8U();
+   Exp *e1 = *(--stkptr);
+   unsigned defaultpc = JDNEXT32U(), numcases = JDNEXT32U();
+   Case *tcase = new Case[numcases];
+   *donestkptr++ = new Exp(pcval, e1->minpc, SWITCH, VOID, ID, e1, defaultpc, numcases, tcase);
+   for (unsigned m = numcases; m--;) {
+     tcase->caseval = JDNEXT32U();
+     (tcase++)->branch_pc = JDNEXT32U();
+   }
+   return 0;
+ }


Index: llvm/test/Programs/MultiSource/Applications/hbd/da-field.cpp
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/da-field.cpp:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/da-field.cpp	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,112 ----
+ /* da-field.cpp */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #include "exp.h"
+ #include "class.h"
+ #include "decomp.h"
+ #include "cp.h"
+ #include "field.h"
+ 
+ int doget(Classfile *c)
+ {
+   unsigned pcval = currpc - 1;
+   int val = JDNEXT16S();
+   Ref *mr = (Ref*)c->cp[val]->p;
+   NameAndType *nt = (NameAndType*)c->cp[mr->name_and_type]->p;
+   char *tmpstr = c->cp[nt->name_index]->chp;
+   Exp *e = new Exp(pcval, tmpstr, sig2type(c->cp[nt->signature_index]->chp), CP, val);
+   if (ch == 0xB2) { /* getstatic */
+     Exp *e1;
+     tmpstr = c->cp(mr->class_index)->chp;
+ //    int tmpint = strlen(c->package_name);
+     if (strcmp(tmpstr, c->this_class_name)) {
+       Exp *e2 = new Exp(pcval, tmpstr, VOID, NO);
+       e1 = new Exp(pcval, BINARY, e->e->type, DOT, e2, e);
+       e->e->type = VOID;
+     } else {
+       e1 = e;
+     }
+     *stkptr++ = e1;
+     return 0;
+   } else {          /* getfield  */
+     if (((*(stkptr-1))->e->et == IDENT) && !strcmp((*(stkptr-1))->e->id->name,"this")) {
+       /* this.bar == bar */
+       e->minpc = min(pcval, (*(stkptr-1))->minpc);
+       *(stkptr-1) = e; return 0;
+     } else {
+       /* foo.bar */
+       *(stkptr-1) = new Exp(pcval, min(pcval, (*(stkptr-1))->minpc), BINARY,
+                             e->e->type, DOT, *(stkptr-1), e);
+       e->e->type = VOID;
+       return 0;
+     }
+   }
+ }
+ 
+ int doput(Classfile *c)
+ {
+   unsigned pcval = currpc - 1;
+   int val = JDNEXT16S();
+   Ref *mr = (Ref*)c->cp[val]->p;
+   NameAndType *nt = (NameAndType*)c->cp[mr->name_and_type]->p;
+   char *tmpstr = c->cp[nt->name_index]->chp;
+   Exp *e = new Exp(pcval, tmpstr, sig2type(c->cp[nt->signature_index]->chp), NO);
+   if (ch == 0xB3) { /* putstatic */
+     Exp *e1;
+     tmpstr = c->cp(mr->class_index)->chp;
+     if (strcmp(tmpstr, c->this_class_name)) {
+       Exp *e2 = new Exp(pcval, tmpstr, VOID, NO);
+       e1 = new Exp(pcval, BINARY, e->e->type, DOT, e2, e);
+       e->e->type = VOID;
+     } else {
+       e1 = e;
+     }
+     Exp *e3 = *(--stkptr);
+     if ((e3->e->type == INT) && (e1->e->type == BOOLEAN)) {
+       if ((e3->e == std_exps + 2)||(e3->e == std_exps + 3))
+ 	e3->e += 13;
+       else
+ 	/* CMPEQ */;
+     }
+     *donestkptr++ = new Exp(pcval, min(pcval, e3->minpc), BINARY,
+                             e1->e->type, ASSIGN, e1, e3);
+     return 0;
+   } else {          /* putfield  */
+     Exp *e3 = *(stkptr-2);
+     if ((e3->e->et == IDENT) && !strcmp(e3->e->id->name,"this")) {
+       /* this.bar == bar */
+       e3 = *(--stkptr);
+       if ((e3->e->type == INT) && (e->e->type == BOOLEAN)) {
+ 	if ((e3->e == std_exps + 2)||(e3->e == std_exps + 3))
+ 	  e3->e += 13;
+ 	else
+ 	  /* CMPEQ */;
+       }
+       stkptr--;
+       *donestkptr++ = new Exp(pcval, min(min(pcval, (*stkptr)->minpc),
+                                          (*stkptr)->minpc),
+                               BINARY, e->e->type, ASSIGN, e, e3);
+       return 0;
+     } else {
+       /* foo.bar */
+       Exp *e1 = new Exp(pcval, min((*(stkptr-1))->minpc, pcval), BINARY,
+                         e->e->type, DOT, e3, e);
+       e->e->type = VOID;
+       e3 = *(--stkptr);
+       if ((e3->e->type == INT) && (e1->e->type == BOOLEAN)) {
+ 	if ((e3->e == std_exps + 2)||(e3->e == std_exps + 3))
+ 	  e3->e += 13;
+ 	else
+ 	  /* CMPEQ */;
+       }
+       *donestkptr++ = new Exp(pcval, min(e3->minpc, e1->minpc), BINARY,
+                               e1->e->type, ASSIGN, e1, e3);
+       return 0;
+     }
+   }
+ }


Index: llvm/test/Programs/MultiSource/Applications/hbd/db-meth.cpp
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/db-meth.cpp:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/db-meth.cpp	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,117 ----
+ /* db-meth.cpp */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #include "exp.h"
+ #include "class.h"
+ #include "decomp.h"
+ #include "cp.h"
+ 
+ int invokefunc(Classfile *c)
+ {
+   unsigned pcval = currpc - 1;
+   unsigned minpcval = pcval;
+   int i;
+   Type exptypes[256];
+   int val = JDNEXT16S();
+   Ref *mr = (Ref*)c->cp[val]->p;
+   NameAndType *nt = (NameAndType*)c->cp[mr->name_and_type]->p;
+   char *classname = c->cp(mr->class_index)->chp;
+   char *tmpstr = c->cp[nt->signature_index]->chp;
+   char *name = c->cp[nt->name_index]->chp;
+   Exp **el = new Exp*[strlen(tmpstr)-2];
+   Exp *e1 = new Exp(pcval, name, VOID, NO);
+   unsigned numexps = 0;
+   while (*(++tmpstr) != ')') {
+     exptypes[numexps++] = sig2type(tmpstr);
+     if (*tmpstr == '[') tmpstr++;
+     if (*tmpstr == 'L') while (*(++tmpstr) != ';') /* do nothing */;
+   }
+   Type etype = sig2type(tmpstr + 1);
+   Exp **elp = el;
+   for (i = numexps; i--;) {
+     if (((*(--stkptr))->e->type == INT) && (exptypes[i] == BOOLEAN)) {
+       if (((*stkptr)->e == std_exps + 2)||((*stkptr)->e == std_exps + 3))
+ 	(*stkptr)->e += 13;
+       else
+ 	/* CMPEQ */;
+     }
+     *elp++ = *stkptr;
+     minpcval = min(minpcval, (*stkptr)->minpc);
+   }
+   if (ch == 0xB9) { /* invokeinterface */
+     if (numexps != (unsigned)(JDNEXT8U() - 1)) {
+       fprintf(stderr,"Error in interface method invocation - nargs doesn't match.\n");
+       return 1;
+     }
+     JDNEXT8U(); /* reserved byte */
+   }
+   if (ch != 0xB8) { /* invokevirtual OR invokenonvirtual OR invokeinterface */
+     if (((*(stkptr-1))->e->et == IDENT) && !strcmp((*(stkptr-1))->e->id->name,"this")) {
+       /* this.bar(...) == bar(...) */
+       if (strcmp(classname,c->this_class_name)) { /* super.bar(...) */
+ 	if (!strcmp(name,"<init>")) { /* super() */
+ 	  e1->e->id->name = "super";
+ 	  minpcval = min(minpcval, (*(stkptr-1))->minpc);
+           Exp *e = new Exp(pcval, minpcval, FUNCTIONCALL, etype, ID, e1, numexps, el);
+ 	  if (etype == VOID) {
+             --stkptr; *donestkptr++ = e;
+ 	  } else *(stkptr-1) = e;
+ 	  return 0;
+ 	}
+ 	minpcval = min(minpcval, (*(stkptr-1))->minpc);
+ 	Exp *e2 = new Exp(pcval, "super", VOID, NO);
+ 	Exp *e3 = new Exp(pcval, minpcval, BINARY, FUNC, DOT, e2, e1);
+         Exp *e = new Exp(pcval, minpcval, FUNCTIONCALL, etype, ID, e3, numexps, el);
+ 	if (etype == VOID) {
+           --stkptr; *donestkptr++ = e;
+ 	} else *(stkptr-1) = e;
+ 	return 0;
+       } else {
+ 	if (!strcmp(name,"<init>")) {
+           minpcval = min(minpcval, (*(stkptr-1))->minpc);
+           e1->e->id->name = "this";
+         }
+         Exp *e = new Exp(pcval, minpcval, FUNCTIONCALL, etype, ID, e1, numexps, el);
+         if (e->e->type == VOID) {
+           --stkptr; *donestkptr++ = e;
+         } else *(stkptr-1) = e;
+         return 0;
+       }
+     } else {
+       /* foo.bar(...) */
+       Exp *e;
+       if (!strcmp(name,"<init>")) {
+         /* killexp(e1)? */
+         minpcval = min(minpcval, (*(stkptr-1))->minpc);
+         e = new Exp(pcval, minpcval, FUNCTIONCALL, OBJECT, ID, *(stkptr-1), numexps, el);
+       } else {
+         minpcval = min(minpcval, (*(stkptr-1))->minpc);
+         Exp *e3 = new Exp(pcval, minpcval, BINARY, FUNC, DOT, *(stkptr-1), e1);
+         e = new Exp(pcval, minpcval, FUNCTIONCALL, etype, ID, e3, numexps, el);
+       }
+       if ((e->exp1->e->op != NEW) && (etype == VOID)) {
+         --stkptr; *donestkptr++ = e;
+       } else *(stkptr-1) = e;
+       return 0;
+     }
+   } else { /* invokestatic */
+     Exp *e;
+     tmpstr = c->cp(mr->class_index)->chp;
+     if (strcmp(tmpstr, c->this_class_name)) {
+       Exp *e2 = new Exp(pcval, tmpstr, VOID, NO);
+       Exp *e3 = new Exp(pcval, minpcval, BINARY, FUNC, DOT, e2, e1);
+       e = new Exp(pcval, minpcval, FUNCTIONCALL, etype, ID, e3, numexps, el);
+     } else
+       e = new Exp(pcval, minpcval, FUNCTIONCALL, etype, ID, e1, numexps, el);
+     if (etype == VOID)
+       *donestkptr++ = e;
+     else
+       *stkptr++ = e;
+     return 0;
+   }
+ }


Index: llvm/test/Programs/MultiSource/Applications/hbd/dc-misc.cpp
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/dc-misc.cpp:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/dc-misc.cpp	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,32 ----
+ /* dc-misc.cpp */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #include "exp.h"
+ #include "class.h"
+ #include "decomp.h"
+ #include "cp.h"
+ 
+ int docheckcast(Classfile *c)
+ {
+   unsigned pcval = currpc - 1;
+   unsigned val = JDNEXT16U();
+   Exp *e1 = *(stkptr-1);
+   Exp *e2 = new Exp(pcval, c->cp(val)->chp, OBJECT, CP, val);
+   *(stkptr-1) = new Exp(pcval, min(e1->minpc, pcval), PREUNARY, OBJECT, CAST, e1, e2);
+   return 0;
+ }
+ 
+ int doinstanceof(Classfile *c)
+ {
+   unsigned pcval = currpc - 1;
+   unsigned val = JDNEXT16U();
+   Exp *e1 = *(stkptr-1);
+   Exp *e2 = new Exp(pcval, c->cp(val)->chp, OBJECT, CP, val);
+   *(stkptr-1) = new Exp(pcval, e1->minpc, BINARY, BOOLEAN, INSTANCEOF, e1, e2);
+   return 0;
+ }


Index: llvm/test/Programs/MultiSource/Applications/hbd/decomp.cpp
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/decomp.cpp:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/decomp.cpp	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,340 ----
+ /* decomp.cpp */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #include <stdio.h>
+ #include <string.h>
+ #include <stdlib.h>
+ #include "general.h"
+ #include "options.h"
+ #include "version.h"
+ #include "cp.h"
+ #include "access.h"
+ #include "field.h"
+ #include "exp.h"
+ #include "method.h"
+ #include "consts.h"
+ #include "class.h"
+ #include "file.h"
+ #include "sig.h"
+ #include "decomp.h"
+ 
+ void printintlist(intlist *t) {
+   fprintf(stderr, "[");
+   intnode *n = t->head;
+   while (n) {
+     fprintf(stderr, "%d", n->node);
+     n = n->next;
+     if (!n)
+       break;
+     fprintf(stderr, ", ");
+   }
+   fprintf(stderr, "]\n");
+ }
+ 
+ int ch;
+ unsigned char *inbuff;
+ int bufflength;
+ unsigned currpc;
+ int lastaction;
+ method_info *miptr;
+ 
+ Exp *stack[8];
+ Exp **stkptr;
+ Exp *donestack[256];
+ Exp **donestkptr;
+ 
+ //Block *blocks[16];
+ //int numblocks;
+ //int currblock;
+ 
+ int indentlevel;
+ 
+ /*
+ char pass1size[] = {
+   1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,
+   2, 3, 2, 3, 3, 2, 2, 2,  2, 2, 1, 1, 1, 1, 1, 1,
+   1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 0, 0,
+   0, 0, 1, 0, 0, 0, 2, 2,  2, 2, 2, 1, 1, 1, 1, 1,
+   1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 0,
+   0, 0, 0, 1, 0, 0, 0, 1,  1, 1, 1, 1, 1, 1, 1, 1,
+   1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,
+   1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,
+ 
+   1, 1, 1, 1, 3, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,
+ */// 1,1,1,1,/*C*/1,1,1,1,1,/*.*/-1,-1,-1,-1,-1,-1,-1, // cmps
+ // -1,-1,-1,-1,-1,-1,-1,-2,-3,-4,-5,-6,/*R*/1,1,1,1, // returns
+ //  1,1/*.*/,3,3,3,3, 3, 3,  5, 3, 3, 3, 0, 3, 1, 1,
+ /*  3, 0, 0, 0, 0, 3,-1,-1,  0, 0, 0, 0, 0, 0, 0, 0,
+   0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,
+   0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,
+   0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,
+ };
+ 
+ int addifblock(void)
+ {
+   unsigned pcval = currpc - 1;
+   Block *b = blocks[currblock++] = new Block;
+   b->tag = IF;
+   b->start_pc = pcval + 3;
+   b->end_pc = pcval + (signed)(((unsigned)JDNEXT8() << 8) + (unsigned)JDNEXT8());
+   b->else_pc = 0;
+   b->exp = 0;
+   fprintf(stderr, "if(?) goto %d else %d\n", b->end_pc, b->start_pc);
+   return 0;
+ }
+ 
+ int addgotoblock(void)
+ {
+   unsigned pcval = currpc - 1;
+   Block *b = blocks[currblock++] = new Block;
+   b->tag = GOTOLABEL;
+   b->start_pc = pcval + 3;
+   b->end_pc = pcval + (signed)(((unsigned)JDNEXT8() << 8) + (unsigned)JDNEXT8());
+   b->else_pc = 0;
+   b->exp = 0;
+   fprintf(stderr, "goto %d instead of %d\n", b->end_pc, b->start_pc);
+   return 0;
+ }
+ 
+ int (*pass1actions[])(void) = {
+   0, addifblock, addgotoblock, 0, 0, 0, 0, 0,
+   0, 0, 0
+ };
+ */
+ char actions[] = {
+   0, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,
+   2, 2, 3, 3, 3, 4, 4, 4,  4, 4, 4, 4, 4, 4, 4, 4,
+   4, 4, 4, 4, 4, 4, 4, 4,  4, 4, 4, 4, 4, 4,15, 0,
+   0, 0,15, 0, 0, 0, 5, 5,  5, 5, 5, 5, 5, 5, 5, 5,
+   5, 5, 5, 5, 5, 5, 5, 5,  5, 5, 5, 5, 5, 5, 5, 0,
+   0, 0, 0,18, 0, 0, 0,21,  0,13,25, 0, 0, 0, 0, 0,
+   6, 6, 6, 6, 6, 6, 6, 6,  6, 6, 6, 6, 6, 6, 6, 6,
+   6, 6, 6, 6, 7, 7, 7, 7,  6, 6, 6, 6, 6, 6, 6, 6,
+ 
+   6, 6, 6, 6,16, 7, 7, 7,  7, 7, 7, 7, 7, 7, 7, 7,
+   7, 7, 7, 0,22,22,22,22, 22,12,12,12,12,12,12,23,
+  23,23,23,23,23,23,23, 7,  0, 0,27,24,10,10,10,10,
+  10,10, 8, 9, 8, 9,11,11, 11,11, 7, 7, 0,19,14, 7,
+  17,26, 0, 0, 0,20/*?(multianewarray)*/,12,12,  0, 0, 0, 0, 0, 0, 0, 0,
+   0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,
+   0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,
+   0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,
+ };
+ 
+ int (*actiontable[])(Classfile *c) = {
+   0, pushimp, pushimm, pushconst, pushlocal, storelocal, pushbinop, pushunop,
+   doget, doput, doreturn, invokefunc, doif1, dodup, doarraylength, doarrayget,
+   iinclocal, docheckcast, doarrayput, anewarray, multianewarray, dopop, docmp, doif2,
+   doluswitch, dodup_x1, doinstanceof, dotableswitch
+ };
+ 
+ int decompileblock(Classfile *c, method_info_ptr mi) {
+   char *str;
+ //  int i;
+   miptr = mi;
+   cond_pcend = -1;
+   char *strptr;
+   int dodecompile = ((int)(c->options)) ^ 2;
+ 
+   if (mi->name == "<init>") {
+   }
+ 
+   strptr = new char[mi->access_flags.strlen() + 1];
+   fprintf(c->outfile, "\n  %s", mi->access_flags.toString(strptr));
+   delete strptr;
+   char *tmp = mi->sig;
+   if (printsigname(c, c->outfile, tmp, mi->name, mi)) return 1;
+   for (int m = 0; m != mi->num_throws;) {
+     fprintf(c->outfile, " throws %s", c->cp(mi->throws[m++])->chp);
+   }
+   if ((mi->access_flags & (ACC_NATIVE | ACC_ABSTRACT))) dodecompile = 0;
+   if (dodecompile) {
+ 
+ /**********************************************************************/
+ /** PASS1 - input stage, analyse opcodes, create stack of statements **/
+ /**********************************************************************/
+     int action = 0;
+     inbuff = mi->code;
+     bufflength = mi->code_length;
+     currpc = 0;
+     stkptr = stack;
+     donestkptr = donestack;
+     
+     indentlevel = 0;
+ //    indents_end = indents_begin = (intlist *)0;
+ 
+     while (bufflength > 0) {
+       if (((int)currpc == cond_pcend)) if (finishconditional(c)) return 1;
+       ch = JDNEXT8U();
+       lastaction = action;
+       action = actions[ch];
+       if (action) {
+         if(actiontable[action](c)) return 1;
+       } else {
+         fprintf(c->outfile, "//    unknown opcode 0x%02X\n", ch);
+       }
+     }
+ 
+     fprintf(c->outfile, " {\n");
+ 
+ /**********************************************************************/
+ /**  PASS2 - lazy conditionals (&& and ||), note backward jump refs  **/
+ /**********************************************************************/
+     looplist *branchbacklist = new looplist();
+     Exp **p = donestack;
+     for (;p < (donestkptr-1);p++) {
+       Exp *pptr = *p, *pptr1 = *(p+1), *pptr2 = *(p+2);
+       if (pptr->e->op == GOTO)
+         goto here;
+       if (pptr->e->et == BRANCH) {
+         if (pptr1->e->et == BRANCH || pptr1->e->op == COND) {
+           unsigned minpc = min(pptr->minpc, pptr1->minpc);
+           Exp *e;
+           if (pptr->branch_pc == pptr1->branch_pc) {
+             e = new Exp(minpc, BINARY, BOOLEAN, OR_BOOL,
+                 pptr->exp1, pptr1->exp1);
+           } else {
+             if (pptr->branch_pc == pptr2->minpc) {
+               e = new Exp(minpc, BINARY, BOOLEAN, AND_BOOL,
+                   pptr->exp1, pptr1->exp1);
+               if (notexp(&(e->exp1))) return 1;
+             } else {
+               goto here;
+             }
+           }
+           killexp(pptr);
+           pptr1->exp1 = e;
+           pptr1->minpc = minpc;
+           *p = pptr1; *(++p) = 0;
+           pptr = pptr1; pptr1 = pptr2;
+         }
+ here:
+         if (pptr->minpc >= pptr->branch_pc) {
+           branchbacklist->add(new Loop(pptr->minpc, pptr->branch_pc,
+                 pptr1->minpc, pptr->exp1, LOOP_DOWHILE));
+         }
+       }
+     }
+     
+ /**********************************************************************/
+ /** PASS3 - analyse control flow, recursively print statement stack  **/
+ /**********************************************************************/
+     intlist *iflist = new intlist();
+     intlist *elselist = new intlist();
+     looplist *branchbacklist2 = new looplist();
+     
+     p = donestack;
+     while (p != donestkptr) {
+      Exp *pptr = *p++;
+      if (pptr) {
+        if (!branchbacklist->isempty()) {
+          Loop *l = branchbacklist->top();
+          if (l->jumpto_pc == pptr->minpc) {
+            l->type = LOOP_DOWHILE;
+            fprintf(c->outfile, "    do {\n", str);
+            indentlevel++;
+            for (int i=indentlevel; i--;) fprintf(c->outfile, "  ");
+            branchbacklist2->push(branchbacklist->pop());
+          }
+        }
+        if (!branchbacklist->isempty()) {
+          Loop *l = branchbacklist->top();
+          if (pptr->e->op == GOTO && pptr->branch_pc == l->jumpfrom_pc) {
+            l->type = LOOP_WHILE;
+            str = l->condition->toString(0);
+            fprintf(c->outfile, "    while (%s) {\n", str);
+            delete str;
+            indentlevel++;
+            for (int i=indentlevel; i--;) fprintf(c->outfile, "  ");
+            branchbacklist2->push(branchbacklist->pop());
+            continue;
+          }
+        }
+        if (!iflist->isempty() && iflist->top() == pptr->minpc) {
+          iflist->pop();
+          fprintf(c->outfile, "  }\n");
+          indentlevel--;
+          for (int i=indentlevel; i--;) fprintf(c->outfile, "  ");
+        }
+        if (pptr->e->op == GOTO || pptr->e->et == BRANCH) {
+          if (!branchbacklist2->isempty()) {
+            Loop *l = branchbacklist2->top();
+            if (l->jumpfrom_pc == pptr->minpc) {
+              if (l->type == LOOP_DOWHILE) {
+                if (pptr->e->op == GOTO) {
+                  fprintf(c->outfile, "  } while(true);\t/*%d*/\n", pptr->minpc);
+                } else {
+                  char *str = l->condition->toString(0);
+                  fprintf(c->outfile, "  } while(%s);\t/*%d*/\n", str,
+                      pptr->minpc);
+                  delete str;
+                }
+              } else {
+                fprintf(c->outfile, "  }\t/*%d*/\n", pptr->minpc);
+              }
+              branchbacklist2->pop();
+              indentlevel--;
+              for (int i=indentlevel; i--;) fprintf(c->outfile, "  ");
+              continue;
+            }
+            if (branchbacklist2->containsPast(pptr->branch_pc)) {
+              fprintf(c->outfile, "    break;\t/*%d*/\n", (*(p-1))->minpc);
+              for (int i=indentlevel; i--;) fprintf(c->outfile, "  ");
+              continue;
+            }
+          }
+          if (!iflist->isempty() && iflist->top() == ((*p)?(*p)->minpc:0)) {
+            elselist->push(pptr->branch_pc);
+            iflist->pop();
+            fprintf(c->outfile, "  } else {\t/*%d*/\n", (*(p-1))->minpc);
+            for (int i=indentlevel; i--;) fprintf(c->outfile, "  ");
+            continue;
+          }
+          if (pptr->e->et == BRANCH && pptr->branch_pc > pptr->minpc) {
+            iflist->push(pptr->branch_pc);
+            indentlevel++;
+          }
+        } else {
+          if (pptr->e->op == RETURN && !iflist->isempty()
+              && iflist->top() == ((*p)?(*p)->minpc:0)) {
+            iflist->pop();
+            str = pptr->toString(0);
+            if (str) {
+              fprintf(c->outfile, "    %s;\t/*%d*/\n", str, (*(p-1))->minpc);
+              for (int i=indentlevel; i--;) fprintf(c->outfile, "  ");
+            }
+            delete str;
+            fprintf(c->outfile, "  }\n");
+            indentlevel--;
+            for (int i=indentlevel; i--;) fprintf(c->outfile, "  ");
+            continue;
+          } else {
+            if (!elselist->isempty() && elselist->top() == pptr->minpc) {
+              elselist->pop();
+              fprintf(c->outfile, "  }\n");
+              indentlevel--;
+              for (int i=indentlevel; i--;) fprintf(c->outfile, "  ");
+            }
+          }
+        }
+        str = pptr->toString(0);
+        if (str) {
+          fprintf(c->outfile, strrchr(str,'{')?"    %s":"    %s;", str);
+          fprintf(c->outfile, "\t/*%d*/",(*(p-1))->minpc);
+          fprintf(c->outfile, "\n");
+          for (int i=indentlevel; i--;) fprintf(c->outfile, "  ");
+        }
+        delete str;
+       }
+     }
+     fprintf(c->outfile, "  }");
+   } else {
+     fprintf(c->outfile, ";");
+   }
+   return 0;
+ }


Index: llvm/test/Programs/MultiSource/Applications/hbd/decomp.h
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/decomp.h:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/decomp.h	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,85 ----
+ /* decomp.h */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #ifndef DECOMP_H
+ #define DECOMP_H
+ 
+ #include "general.h"
+ 
+ /* These all need to be global for various reasons */
+ extern int ch;
+ extern char actions[];
+ extern int (*actiontable[])(Classfile *c);
+ extern unsigned char *inbuff;
+ extern int bufflength;
+ extern unsigned currpc;
+ 
+ /* Various macros to read the bytecodes and keep track of
+    where we are in the code */
+ #define JDNEXT8S() (i8)(currpc++,bufflength--,*inbuff++)
+ #define JDNEXT8U() (u8)(currpc++,bufflength--,*inbuff++)
+ #define JDNEXT16S() (i16)(currpc+=2,bufflength-=2,inbuff+=2, \
+                    (((u16)*(inbuff-2))<<8)+((u16)*(inbuff-1)))
+ #define JDNEXT16U() (u16)(currpc+=2,bufflength-=2,inbuff+=2, \
+                    (((u16)*(inbuff-2))<<8)+((u16)*(inbuff-1)))
+ #define JDNEXT32S() (i32)(currpc+=4,bufflength-=4,inbuff+=4, \
+            (((u32)*(inbuff-4))<<24)+(((u32)*(inbuff-3))<<16) \
+            +(((u32)*(inbuff-2))<<8)+((u32)*(inbuff-1)))
+ #define JDNEXT32U() (u32)(currpc+=4,bufflength-=4,inbuff+=4, \
+            (((u32)*(inbuff-4))<<24)+(((u32)*(inbuff-3))<<16) \
+            +(((u32)*(inbuff-2))<<8)+((u32)*(inbuff-1)))
+ //#define JDLAST(num) (*(inbuff-(num)-1))
+ #define JDLAST8S() (i8)(*(inbuff-1))
+ #define JDLAST8U() (u8)(*(inbuff-1))
+ #define JDPEEK8S() (i8)(*inbuff)
+ #define JDPEEK8U() (u8)(*inbuff)
+ 
+ /* These are all the prototypes for the actions that are used
+    by the decompiler */
+ int pushimp(Classfile *c);
+ int pushimm(Classfile *c);
+ int pushconst(Classfile *c);
+ int pushlocal(Classfile *c);
+ int storelocal(Classfile *c);
+ int pushbinop(Classfile *c);
+ int pushunop(Classfile *c);
+ int finishconditional(Classfile *c);
+ int doget(Classfile *c);
+ int doput(Classfile *c);
+ int doreturn(Classfile *c);
+ int invokefunc(Classfile *c);
+ int doif1(Classfile *c);
+ int dodup(Classfile *c);
+ int doarraylength(Classfile *c);
+ int doarrayget(Classfile *c);
+ int iinclocal(Classfile *c);
+ int docheckcast(Classfile *c);
+ int doarrayput(Classfile *c);
+ int anewarray(Classfile *c);
+ int multianewarray(Classfile *c);
+ int dopop(Classfile *c);
+ int docmp(Classfile *c);
+ int doif2(Classfile *c);
+ int doluswitch(Classfile *c);
+ int dodup_x1(Classfile *c);
+ int doinstanceof(Classfile *c);
+ int dotableswitch(Classfile *c);
+ 
+ /* These are the globals which contain the
+    various stacks used by the decompiler. */
+ extern Exp *stack[];
+ extern Exp **stkptr;
+ extern Exp *donestack[];
+ extern Exp **donestkptr;
+ extern int lastaction;
+ extern int cond_pcend;
+ extern Exp *cond_e1;
+ extern Exp *cond_e1;
+ extern Exp **cond_donestkptr;
+ 
+ #endif


Index: llvm/test/Programs/MultiSource/Applications/hbd/err.cpp
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/err.cpp:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/err.cpp	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,32 ----
+ /* err.cpp */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #include <stdio.h>
+ #include <stdarg.h>
+ #include "general.h"
+ #include "options.h"
+ 
+ char *errmsgs[] = {
+   "Unknown error.",
+   "Out of memory error.",
+   DEBUG_ON? "Usage: %s [-O] [-D] InFile.class [OutFile.java]\n"
+            :"Usage: %s [-O] InFile.class [OutFile.java]\n",
+   DEBUG_ON? "Usage: %s [-D] -Ifuncname InFile.class\n"
+            :"Usage: %s -Ifuncname InFile.class\n",
+   "Not a class.",
+   "Unsupported Class Version.",
+   "3"
+ };
+ void fatalerror(int msgid,...)
+ {
+   va_list ap;
+   va_start(ap, msgid);
+   vfprintf(stderr, errmsgs[msgid], ap);
+   va_end(ap);
+   exit(msgid);
+ }


Index: llvm/test/Programs/MultiSource/Applications/hbd/err.h
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/err.h:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/err.h	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,29 ----
+ /* errhandl.h */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #ifndef ERRHANDL_H
+ #define ERRHANDL_H
+ 
+ /* The various errors that can occur in the programs.
+    These are passed to the fatalerror() function
+    below. */
+ enum errorids {
+   UNKNOWN_ERR, OUT_OF_MEM_ERR,
+   COMMAND_LINE_ERR_HBD, COMMAND_LINE_ERR_HBT,
+   NOT_A_CLASS_ERR, BAD_VERSION_ERR, CP_ERR
+ };
+ 
+ /* This function will exit the program giving
+    an appropriate error.  The msgid should be
+    from the enum above */
+ void fatalerror(int msgid,...);
+ 
+ /* Since this is commonly used, we have a macro for it */
+ #define memerr() fatalerror(OUT_OF_MEM_ERR)
+ 
+ #endif


Index: llvm/test/Programs/MultiSource/Applications/hbd/exp.cpp
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/exp.cpp:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/exp.cpp	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,217 ----
+ /* exp.cpp */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include "exp.h"
+ 
+ Exp_ std_exps[] = {
+   Exp_(&idnull), Exp_(&idneg1), Exp_(&id0i), Exp_(&id1i), Exp_(&id2i), Exp_(&id3i),
+   Exp_(&id4i), Exp_(&id5i), Exp_(&id0L), Exp_(&id1L), Exp_(&id0f), Exp_(&id1f),
+   Exp_(&id2f), Exp_(&id0d), Exp_(&id1d), Exp_(&idfalse), Exp_(&idtrue),
+   Exp_(1, BRANCH, VOID, ID, 0), Exp_(1, TERNARY, BOOLEAN, COND, 0)
+ };
+ 
+ void killexp(Exp *e) {
+   if (!(--e->numrefs)) {
+     if (!e->e->isstd) {
+       if (e->e->et == IDENT) {
+ //      delete e->e->id->name;
+ //        delete e->e->id;
+       }
+ //      delete e->e;
+     }
+ //    delete e;
+   }
+ }
+ 
+ int notexp(Exp **e_ptr) {
+   Exp *e = *e_ptr;
+   switch (e->e->op) {
+     case NOT_BOOL:
+       *e_ptr = e->exp1;
+       killexp(e);
+       break;
+     case OR_BOOL:
+       e->e->op = AND_BOOL;
+       notexp(&(e->exp1));
+       notexp(&(e->exp2));
+       break;
+     case AND_BOOL:
+       e->e->op = OR_BOOL;
+       notexp(&(e->exp1));
+       notexp(&(e->exp2));
+       break;
+     case OR: case AND:
+       notexp(&(e->exp1));
+       notexp(&(e->exp2));
+     case EQUAL: case NOTEQUAL: case LESS: case GREATEROREQUAL:
+     case GREATER: case LESSOREQUAL:
+       *((int*)(&e->e->op)) ^= 1;
+       break;
+     default:
+       if (e->e->type != BOOLEAN) {
+         fprintf(stderr, "Can't not a non-boolean\n");
+         return 1;
+       }
+       *e_ptr = new Exp(e->pc, e->minpc, PREUNARY, BOOLEAN, NOT_BOOL, e);
+   }
+   return 0;
+ }
+ 
+ /*
+ Exp::Exp(int pcval, char *idname, Type idtype) {
+   numrefs = 1;
+   minpc = pc = pcval;
+   e = new Exp_;
+   e->isstd = 0;
+   e->et = IDENT;
+   e->op = ID;
+   e->type = idtype;
+   e->id = new Id;
+   e->id->name = idname;
+ }
+ */
+ 
+ char *Exp::toString(unsigned nextpc) {
+   char *e1, *e2, *e3, *o, *o2, *s, *t1;
+   int sizestr, i;
+   switch (e->et) {
+   case IDENT:
+     s = new char[strlen(e->id->name) + 1];
+     strcpy(s, e->id->name);
+     return s;
+   case PREUNARY:
+     exp1->numrefs += numrefs-1;
+     e1 = exp1->toString(0);
+     if (e->op == CAST) {
+       if (e->type == OBJECT) {
+         exp2->numrefs += numrefs-1;
+         e2 = exp2->toString(0);
+         killexp(exp2);
+         o = new char[strlen(e2) + 3];
+         sprintf(o, "(%s)", e2);
+         delete e2;
+       } else {
+         o = new char[strlen(type2str[e->type]) + 3];
+         sprintf(o, "(%s)", type2str[e->type]);
+       }
+     } else {
+       o = strdup(op2str[e->op]);
+     }
+     s = new char[5 + strlen(o) + strlen(e1)];
+     if (op_prec[exp1->e->op] < (op_prec[e->op] + 0))
+       sprintf(s, "%s(%s)", o, e1);
+     else
+       sprintf(s, "%s%s", o, e1);
+     killexp(exp1); delete e1; delete o;
+     return s;
+   case POSTUNARY:
+     exp1->numrefs += numrefs-1;
+     e1 = exp1->toString(0); o = op2str[e->op];
+     s = new char[5 + strlen(o) + strlen(e1)];
+     sprintf(s, (op_prec[exp1->e->op] < (op_prec[e->op] + 0))?"(%s)%s":"%s%s", e1, o);
+     killexp(exp1); delete e1;
+     return s;
+   case BINARY:
+     exp1->numrefs += numrefs-1;
+     exp2->numrefs += numrefs-1;
+     e1 = exp1->toString(0); e2 = exp2->toString(0);
+     o = op2str[e->op];
+     t1 = new char[9 + strlen(o)];
+     sprintf(t1, "%s%s%s",
+       (op_prec[exp1->e->op] < (op_prec[e->op] + 0))?"(%s)":"%s",
+       o, (op_prec[exp2->e->op] < (op_prec[e->op] + 0))?"(%s)":"%s");
+     s = new char[strlen(t1) + strlen(e1) + strlen(e2) - 3];
+     sprintf(s, t1, e1, e2); delete t1;
+     killexp(exp1); killexp(exp2); delete e1; delete e2;
+     return s;
+   case TERNARY:
+     exp1->numrefs += numrefs-1; exp2->numrefs += numrefs-1; exp3->numrefs += numrefs-1;
+     e1 = exp1->toString(0); e2 = exp2->toString(0); e3 = exp3->toString(0);
+     o = op2str[e->op]; o2 = op2str[e->op + 1];
+     t1 = new char[19];
+     sprintf(t1, "%s%s%s%s%s",
+       (op_prec[exp1->e->op] < (op_prec[e->op] + 0))?"(%s)":"%s",
+       o, (op_prec[exp2->e->op] < (op_prec[e->op] + 0))?"(%s)":"%s",
+       o2, (op_prec[exp3->e->op] < (op_prec[e->op] + 0))?"(%s)":"%s");
+     s = new char[strlen(t1) + strlen(e1) + strlen(e2) + strlen(e3) - 5];
+     sprintf(s, t1, e1, e2, e3); delete t1;
+     killexp(exp1); killexp(exp2); killexp(exp3);
+     delete e1; delete e2; delete e3;
+     return s;
+   case FUNCTIONCALL:
+     t1 = new char[256];
+     exp1->numrefs += numrefs-1;
+     e1 = exp1->toString(0); sizestr = strlen(e1) + 3;
+     sprintf(t1, "%s(", e1);
+     killexp(exp1); delete e1;
+     i = numexps;
+     if (i) {
+       while (--i) {
+         explist[i]->numrefs += numrefs-1;
+         e1 = explist[i]->toString(0); strcat(t1, e1); sizestr += strlen(e1) + 2;
+         killexp(explist[i]); delete e1; strcat(t1, ", ");
+       }
+       explist[0]->numrefs += numrefs-1;
+       e1 = explist[0]->toString(0); strcat(t1, e1); sizestr += strlen(e1);
+       killexp(explist[0]); delete e1;
+     }
+     strcat(t1,")");
+     s = new char[sizestr];
+     strcpy(s, t1);
+     delete t1;
+     return s;
+   case ARRAYACCESS:
+     exp1->numrefs += numrefs-1; exp2->numrefs += numrefs-1;
+     e1 = exp1->toString(0); e2 = exp2->toString(0);
+     s = new char[strlen(e1) + strlen(e2) + 3];
+     sprintf(s, "%s[%s]", e1, e2);
+     killexp(exp1); killexp(exp2); delete e1; delete e2;
+     return s;
+   case BRANCH:
+ //    if ((unsigned)e->op > minpc) {
+ //    {
+ //      intlist *i = indents_end, *j;
+ //      if ((!i) || (i->node >= branch_pc)) {
+ //        indents_end = new intlist;
+ //        indents_end->node = branch_pc;
+ //        indents_end->next = i;
+ //      } else {
+ //        while ((i->next) && (i->next->node < branch_pc)) i = i->next;
+ //        j = i->next; i = i->next = new intlist; i->next = j;
+ //        i->node = branch_pc;
+ //      }
+ //      indentlevel++;
+       notexp(&exp1);
+       exp1->numrefs += numrefs-1;
+       e1 = exp1->toString(0);
+       s = new char[strlen(e1) + 8];
+       sprintf(s, "if (%s) {", e1);
+ //    } else {
+ //      exp1->numrefs += numrefs-1;
+ //      e1 = exp1->toString(0);
+ //      s = new char[strlen(e1) + 21];
+ //      sprintf(s, "if (%s) goto label%d", e1, branch_pc);
+ //    }
+     killexp(exp1); delete e1;
+     return s;
+   case SWITCH:
+     exp1->numrefs += numrefs-1;
+     e1 = exp1->toString(0);
+     s = new char[strlen(e1) + 29];
+     sprintf(s, "switch (%s) default: label%d", e1, default_pc);
+     killexp(exp1); delete e1;
+     return s;
+   default:
+     fprintf(stderr, "Error converting expressions to strings. %d\n", e->et);
+     exit(-1);
+     return 0;
+   }
+ }


Index: llvm/test/Programs/MultiSource/Applications/hbd/exp.h
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/exp.h:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/exp.h	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,333 ----
+ /* exp.h */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #ifndef EXP_H
+ #define EXP_H
+ 
+ #include "id.h"
+ #include "op.h"
+ 
+ /* The various types of expressions */
+ enum Exptype {
+   NOEXP, IDENT, PREUNARY, POSTUNARY,
+   BINARY, TERNARY, FUNCTIONCALL, ARRAYACCESS,
+   BRANCH, SWITCH
+ };
+ 
+ /*
+    This structure is a secondary structure to
+    the actual Exp struct.  It is used to allow
+    us to have a set of "standard" Expressions
+    for things like an integer constant "1" which
+    is often used.  This saves both time and memory.
+ */
+ struct Exp_ {
+   int isstd;  /* 1 if this is one of the standard Exp_'s */
+   Exptype et; /* The tpye of expression this is */
+   Type type;  /* The Java type of the result of this Exp_ */
+   Op op;      /* The operation performed in this Exp_ */
+   Id *id;     /* A reference to an Id if this Exp_
+                  is simply an identifier */
+ 
+   /* This constructor creates an expression for the
+      given identifier */
+   Exp_(Id *idptr) {
+     isstd = 1; et = IDENT; type = idptr->type;
+     op = ID; id = idptr;
+   }
+ 
+   /* These constructors will create more general Exp_'s */
+   Exp_(Exptype _et, Type _type, Op _op) {
+     isstd = 0; et = _et; type = _type; op = _op;
+   }
+   Exp_(Exptype _et, Type _type, Op _op, Id *_id) {
+     isstd = 0; et = _et; type = _type; op = _op; id = _id;
+   }
+   Exp_(int _isstd, Exptype _et, Type _type, Op _op, Id *_id) {
+     isstd = _isstd; et = _et; type = _type; op = _op; id = _id;
+   }
+ };
+ 
+ /* This is the table of commonly-used Exp_'s */
+ extern Exp_ std_exps[];
+ 
+ struct Case { long caseval; long branch_pc; };
+ 
+ /* The main Exp struct */
+ struct Exp {
+   /* The secondary Exp_ structure for this Exp */
+   Exp_ *e;
+ 
+   /* A reference count */
+   unsigned numrefs;
+ 
+   unsigned pc;
+   unsigned minpc;
+   Exp *exp1, *exp2;
+ 
+   union {
+     Exp *exp3;
+     unsigned default_pc;
+   };
+   union {
+     unsigned numexps;
+     unsigned branch_pc;
+     unsigned numcases;
+   };
+   union {
+     Exp **explist;
+     Case *cases;
+   };
+ 
+   /* Constructors for "standard" Exp_'s */
+   Exp(unsigned pcval, unsigned stdexpnum) {
+     numrefs = 1; pc = minpc = pcval; e = std_exps + stdexpnum;
+   }
+   Exp(unsigned pcval, unsigned minpcval,
+       unsigned stdexpnum, Exp *_exp1, unsigned branchpcval) {
+     numrefs = 1; pc = pcval; minpc = minpcval;
+     e = std_exps + stdexpnum;
+     exp1 = _exp1; branch_pc = branchpcval;
+   }
+ 
+   /* A constructor for Identifiers */
+   Exp(unsigned pcval, Exptype et, Type type, Op op, Id *id) {
+     numrefs = 1; pc = minpc = pcval;
+     e = new Exp_(et, type, op, id);
+   }
+ 
+   /* A fairly general constructor */
+   Exp(unsigned pcval, Exptype et,
+       Type type, Op op, Exp *_exp1 = 0, Exp *_exp2 = 0) {
+     numrefs = 1; pc = minpc = pcval;
+     e = new Exp_(et, type, op);
+     exp1 = _exp1; exp2 = _exp2;
+   }
+ 
+   /* A constructor for case "expressions" */
+   Exp(unsigned pcval, unsigned minpcval, Exptype et,
+       Type type, Op op, Exp *_exp1, unsigned defaultpcval,
+       unsigned _numcases, Case *_cases) {
+     numrefs = 1; pc = pcval; minpc = minpcval;
+     e = new Exp_(et, type, op);
+     exp1 = _exp1; default_pc = defaultpcval;
+     numcases = _numcases; cases = _cases;
+   }
+ 
+   /* A constructor for method calls */
+   Exp(unsigned pcval, unsigned minpcval, Exptype et,
+       Type type, Op op, Exp *_exp1,
+       unsigned _numexps, Exp** _explist) {
+     numrefs = 1; pc = pcval; minpc = minpcval;
+     e = new Exp_(et, type, op);
+     exp1 = _exp1; numexps = _numexps;
+     explist = _explist;
+   }
+ 
+   /* A constructor for conditionals */
+   Exp(unsigned pcval, Exptype et, Type type,
+       Op op, Exp *_exp1, unsigned branchpcval) {
+     numrefs = 1; pc = minpc = pcval;
+     e = new Exp_(et, type, op);
+     exp1 = _exp1; branch_pc = branchpcval;
+   }
+ 
+   /* Another general constructor */
+   Exp(unsigned pcval, int minpcval, Exptype et,
+       Type type, Op op, Exp *_exp1, Exp *_exp2 = 0) {
+     numrefs = 1; pc = pcval; minpc = minpcval;
+     e = new Exp_(et, type, op);
+     exp1 = _exp1; exp2 = _exp2;
+   }
+ 
+   /* Another constructor for identifiers */
+   Exp(unsigned pcval, char *idname,
+       Type idtype, Loc idloc, int idlocinfo = 0) {
+     Id *id = new Id; id->name = idname; id->type = idtype;
+     id->loc = idloc; id->locinfo = idlocinfo;
+     numrefs = 1; pc = minpc = pcval;
+     e = new Exp_(IDENT, idtype, ID, id);
+   }
+ 
+   /* Provides a string representation of this Expression */
+   char *toString(unsigned nextpc);
+ };
+ 
+ /* This enum provides an easier way to look up the table of
+    "standard" Exp_'s */
+ enum stdexp_vals {
+   NULLEXP, INEG1EXP, I0EXP, I1EXP, I2EXP, I3EXP, I4EXP, I5EXP,
+   L0EXP, L1EXP, F0EXP, F1EXP, F2EXP, D0EXP, D1EXP, FALSEEXP,
+   TRUEEXP, IFEXP
+ };
+ 
+ /* This recursively deletes an expression and it's children */
+ void killexp(Exp *e);
+ 
+ /* This will negate a boolean expression. It will cause an
+    error if called on a non-boolean expression */
+ int notexp(Exp **e);
+ 
+ /* These handle the indent level during the print phase */
+ 
+ struct intnode {
+   unsigned node;
+   intnode *next;
+   
+   intnode(unsigned i) {
+     node = i;
+     next = 0;
+   }
+   
+   intnode(unsigned i, intnode *n) {
+     node = i;
+     next = n;
+   }
+ };
+ 
+ struct intlist {
+   intnode *head;
+   intnode *tail;
+   
+   intlist() {
+     head = 0;
+     tail = 0;
+   }
+ 
+   void push(unsigned i) {
+     intnode *n = new intnode(i, head);
+     head = n;
+     if (tail == 0)
+       tail = head;
+   }
+ 
+   void add(unsigned i) {
+     intnode *n = new intnode(i);
+     if (tail == 0) {
+       head = tail = n;
+     } else {
+       tail->next = n;
+       tail = n;
+     }
+   }
+ 
+   unsigned top() {
+     return head?head->node:0;
+   }
+   
+   int isempty() {
+     return head==0;
+   }
+   
+   unsigned pop() {
+     intnode *n = head;
+     unsigned i = n->node;
+     head = n->next;
+     delete n;
+     if (head == 0)
+       tail = 0;
+     return i;
+   }
+   
+   int contains(unsigned i) {
+     intnode *n = head;
+     while (n) {
+       if (n->node == i)
+         return 1;
+       n = n->next;
+     }
+     return 0;
+   }
+ };
+ 
+ typedef enum { LOOP_WHILE, LOOP_DOWHILE, LOOP_FOR } LoopType;
+ 
+ struct Loop {
+   unsigned jumpfrom_pc, jumpto_pc, jumppast_pc;
+   Exp *condition;
+   LoopType type;
+   
+   Loop(unsigned from, unsigned to, unsigned past, Exp *cond, LoopType lt) {
+     jumpfrom_pc = from; jumpto_pc = to; jumppast_pc = past;
+     condition = cond; type = lt;
+   }
+ };
+ 
+ struct loopnode {
+   Loop *node;
+   loopnode *next;
+   
+   loopnode(Loop *e) {
+     node = e;
+     next = 0;
+   }
+   
+   loopnode(Loop *e, loopnode *n) {
+     node = e;
+     next = n;
+   }
+ };
+ 
+ struct looplist {
+   loopnode *head;
+   loopnode *tail;
+   
+   looplist() {
+     head = 0;
+     tail = 0;
+   }
+ 
+   void push(Loop *e) {
+     loopnode *n = new loopnode(e, head);
+     head = n;
+     if (tail == 0)
+       tail = head;
+   }
+ 
+   void add(Loop *e) {
+     loopnode *n = new loopnode(e);
+     if (tail == 0) {
+       head = tail = n;
+     } else {
+       tail->next = n;
+       tail = n;
+     }
+   }
+ 
+   Loop *top() {
+     return head?head->node:0;
+   }
+   
+   int isempty() {
+     return head==0;
+   }
+   
+   Loop *pop() {
+     loopnode *n = head;
+     Loop *e = n->node;
+     head = n->next;
+     delete n;
+     if (head == 0)
+       tail = 0;
+     return e;
+   }
+   
+   int containsPast(unsigned i) {
+     loopnode *n = head;
+     while (n) {
+       if (n->node->jumppast_pc == i)
+         return 1;
+       n = n->next;
+     }
+     return 0;
+   }
+ };
+ 
+ extern int indentlevel;
+ 
+ #endif


Index: llvm/test/Programs/MultiSource/Applications/hbd/field.h
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/field.h:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/field.h	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,34 ----
+ /* field.h */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #ifndef FIELD_H
+ #define FIELD_H
+ 
+ #include "access.h"
+ 
+ /* This struct contains the info for one field */
+ typedef struct {
+   /* The access flags for this field */
+   AccessFlags access_flags;
+ 
+   /* The name of this field.
+      Resolved from the constant pool */
+   char *name;
+ 
+   /* The signature of this field.
+      Also, resolved from the constant pool */
+   char *sig;
+ 
+   /* 1 if this is a constant */
+   int isconstant;
+ 
+   /* If it is a constant, its index to the constant pool */
+   u16 constval_index;
+ } field_info, *field_info_ptr;
+ 
+ #endif


Index: llvm/test/Programs/MultiSource/Applications/hbd/file.h
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/file.h:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/file.h	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,51 ----
+ /* file.h */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #ifndef FILE_H
+ #define FILE_H
+ 
+ /* Various macros to read and copy from the files,
+    and maintain tabs on where in the files we are at. */
+ 
+ inline u8 get8(FILE *f, int *f_pos) {
+   *f_pos++;
+   return getc(f);
+ }
+ 
+ inline u16 get16(FILE *f, int *f_pos) {
+   u16 t1 = get8(f, f_pos); u16 t2 = get8(f, f_pos);
+   return (u16)((t1 << 8) | t2);
+ }
+ 
+ inline u32 get32(FILE *f, int *f_pos) {
+   u32 t1 = get16(f, f_pos); u32 t2 = get16(f, f_pos);
+   return (u32)((t1 << 16) | t2);
+ }
+ 
+ #define getstr(str, size, f) ((f##_pos+=size), \
+                              fread(str,size,1,f))
+ 
+ #define put8(f, v) ((f##_pos++),(putc((v), f)))
+ #define put16(f, v) (put8(f, (v) >> 8), put8(f, (v)))
+ #define putstr(outf, size, str) ((outf##_pos+=size), \
+                                 fwrite(str,size,1,outf))
+ 
+ #define copy8(inf, outf) ((outf##_pos++),(inf##_pos++), \
+                                    putc(getc(inf), outf))
+ #define copy16(inf, outf) (u16)( \
+                            (((u16)copy8(inf,outf)) << 8) \
+                            | (u16)copy8(inf,outf))
+ #define copy32(inf, outf) (u32)( \
+                            (((u32)copy16(inf,outf)) << 16) \
+                            | (u32)copy16(inf,outf))
+ #define copystr(str, size, inf, outf) ((outf##_pos+=size), \
+                                       (inf##_pos+=size), \
+                                       fread(str,size,1,inf), \
+                                       fwrite(str,size,1,outf))
+ 
+ #endif


Index: llvm/test/Programs/MultiSource/Applications/hbd/general.h
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/general.h:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/general.h	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,45 ----
+ /* general.h */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #ifndef _GENERAL_H_
+ #define _GENERAL_H_
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ 
+ /* These allow us to set debugging mode on at
+    compile-time or make it an option at run-time. */
+ //#define debug
+ #define debug_optional
+ 
+ /* The D macro */
+ #if defined(debug)
+ #  define D(x) x
+ #elif defined(debug_optional)
+ extern int debugon;
+ #  define D(x) if(debugon){ x; } else {}
+ #else
+ #  define D(x)
+ #endif /* debug */
+ 
+ /* The min macro */
+ #define min(a,b) (((a) < (b)) ? (a) : (b))
+ 
+ /* Miscellaneous typedefs for specific-sized quantities.
+    These should be in a machine-dependant file. */
+ typedef unsigned  char  u8;
+ typedef   signed  char  i8;
+ typedef unsigned short u16;
+ typedef   signed short i16;
+ typedef unsigned  long u32;
+ typedef   signed  long i32;
+ 
+ typedef char *char_ptr;
+ 
+ #endif


Index: llvm/test/Programs/MultiSource/Applications/hbd/hbd.1
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/hbd.1:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/hbd.1	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,83 ----
+ .\" This -*- nroff -*- file has been generated from
+ .\" DocBook SGML with docbook-to-man on Debian GNU/Linux.
+ ...\"
+ ...\"	transcript compatibility for postscript use.
+ ...\"
+ ...\"	synopsis:  .P! <file.ps>
+ ...\"
+ .de P!
+ \\&.
+ .fl			\" force out current output buffer
+ \\!%PB
+ \\!/showpage{}def
+ ...\" the following is from Ken Flowers -- it prevents dictionary overflows
+ \\!/tempdict 200 dict def tempdict begin
+ .fl			\" prolog
+ .sy cat \\$1\" bring in postscript file
+ ...\" the following line matches the tempdict above
+ \\!end % tempdict %
+ \\!PE
+ \\!.
+ .sp \\$2u	\" move below the image
+ ..
+ .de pF
+ .ie     \\*(f1 .ds f1 \\n(.f
+ .el .ie \\*(f2 .ds f2 \\n(.f
+ .el .ie \\*(f3 .ds f3 \\n(.f
+ .el .ie \\*(f4 .ds f4 \\n(.f
+ .el .tm ? font overflow
+ .ft \\$1
+ ..
+ .de fP
+ .ie     !\\*(f4 \{\
+ .	ft \\*(f4
+ .	ds f4\"
+ '	br \}
+ .el .ie !\\*(f3 \{\
+ .	ft \\*(f3
+ .	ds f3\"
+ '	br \}
+ .el .ie !\\*(f2 \{\
+ .	ft \\*(f2
+ .	ds f2\"
+ '	br \}
+ .el .ie !\\*(f1 \{\
+ .	ft \\*(f1
+ .	ds f1\"
+ '	br \}
+ .el .tm ? font underflow
+ ..
+ .ds f1\"
+ .ds f2\"
+ .ds f3\"
+ .ds f4\"
+ '\" t 
+ .ta 8n 16n 24n 32n 40n 48n 56n 64n 72n  
+ .TH "HBD" "1" 
+ .SH "NAME" 
+ hbd \(em Decompiles Java .class files. 
+ .SH "SYNOPSIS" 
+ .PP 
+ \fBhbd\fP [\fB-O \fIdon't decompile\fP\fP]  [\fB-D \fIdebug mode\fP\fP]  [Inputfile.class]  
+ .SH "DESCRIPTION" 
+ .PP 
+ The HomeBrew Decompiler, \fBhbd\fP, can 
+ be used to decompile Java .class files. 
+ .PP 
+ The class file to be decompiled is passed on the command 
+ line and the resulting decompilation goes to stdout.  Any 
+ errors can be seen on stderr. 
+ .SH "OPTIONS" 
+ .IP "\fB-D\fP         " 10 
+ Debug mode. 
+ .IP "\fB-O\fP         " 10 
+ Do not decompile. 
+ .SH "AUTHOR" 
+ .PP 
+ This manual page was written by Pete Ryland pdr at pdr.cx. 
+ Permission is granted to copy, distribute and/or modify this 
+ document under the terms of the GNU Free Documentation 
+ License, Version 1.1 or any later version published by the Free 
+ Software Foundation; with no Invariant Sections, no Front-Cover 
+ Texts and no Back-Cover Texts. 
+ ...\" created by instant / docbook-to-man, Sat 15 Feb 2003, 20:06 


Index: llvm/test/Programs/MultiSource/Applications/hbd/hbd.cpp
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/hbd.cpp:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/hbd.cpp	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,21 ----
+ /* hbd.cpp */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #include <stdio.h>
+ #include "class.h"
+ 
+ int debugon = 0;
+ 
+ int main(int argc, char **argv)
+ {
+   fprintf(stderr, "HomeBrew Decompiler.  Copyright (c) 1994-2003 Pete Ryland.\n");
+   Classfile c(argc, argv);
+   c.read();
+   c.print();
+   return 0;
+ }


Index: llvm/test/Programs/MultiSource/Applications/hbd/hbd.sgml
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/hbd.sgml:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/hbd.sgml	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,130 ----
+ <!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
+ 
+ <!-- Process this file with docbook-to-man to generate an nroff manual
+      page: `docbook-to-man manpage.sgml > manpage.1'.  You may view
+      the manual page with: `docbook-to-man manpage.sgml | nroff -man |
+      less'.  A typical entry in a Makefile or Makefile.am is:
+ 
+ manpage.1: manpage.sgml
+ 	docbook-to-man $< > $@
+ 
+     
+ 	The docbook-to-man binary is found in the docbook-to-man package.
+ 	Please remember that if you create the nroff version in one of the
+ 	debian/rules file targets (such as build), you will need to include
+ 	docbook-to-man in your Build-Depends control field.
+ 
+   -->
+ 
+   <!-- Fill in your name for FIRSTNAME and SURNAME. -->
+   <!ENTITY dhfirstname "<firstname>Pete</firstname>">
+   <!ENTITY dhsurname   "<surname>Ryland</surname>">
+   <!-- Please adjust the date whenever revising the manpage. -->
+   <!ENTITY dhdate      "<date>February 15, 2003</date>">
+   <!-- SECTION should be 1-8, maybe w/ subsection other parameters are
+        allowed: see man(7), man(1). -->
+   <!ENTITY dhsection   "<manvolnum>1</manvolnum>">
+   <!ENTITY dhemail     "<email>pdr at pdr.cx</email>">
+   <!ENTITY dhusername  "Pete Ryland">
+   <!ENTITY dhucpackage "<refentrytitle>HBD</refentrytitle>">
+   <!ENTITY dhpackage   "hbd">
+ 
+   <!ENTITY debian      "<productname>Debian</productname>">
+   <!ENTITY gnu         "<acronym>GNU</acronym>">
+   <!ENTITY gpl         "&gnu; <acronym>GPL</acronym>">
+ ]>
+ 
+ <refentry>
+   <refentryinfo>
+     <address>
+       &dhemail;
+     </address>
+     <author>
+       &dhfirstname;
+       &dhsurname;
+     </author>
+     <copyright>
+       <year>1994-2003</year>
+       <holder>&dhusername;</holder>
+     </copyright>
+     &dhdate;
+   </refentryinfo>
+   <refmeta>
+     &dhucpackage;
+ 
+     &dhsection;
+   </refmeta>
+   <refnamediv>
+     <refname>&dhpackage;</refname>
+ 
+     <refpurpose>Decompiles Java .class files.</refpurpose>
+   </refnamediv>
+   <refsynopsisdiv>
+     <cmdsynopsis>
+       <command>&dhpackage;</command>
+       <arg><option>-O <replaceable>don't decompile</replaceable></option></arg>
+       <arg><option>-D <replaceable>debug mode</replaceable></option></arg>
+       <arg>Inputfile.class</arg>
+     </cmdsynopsis>
+   </refsynopsisdiv>
+   <refsect1>
+     <title>DESCRIPTION</title>
+ 
+     <para>The HomeBrew Decompiler, <command>&dhpackage;</command>, can
+       be used to decompile Java .class files.</para>
+ 
+     <para>The class file to be decompiled is passed on the command
+       line and the resulting decompilation goes to stdout.  Any
+       errors can be seen on stderr.</para>
+ 
+   </refsect1>
+   <refsect1>
+     <title>OPTIONS</title>
+     <variablelist>
+       <varlistentry>
+         <term><option>-D</option>
+         </term>
+         <listitem>
+           <para>Debug mode.</para>
+         </listitem>
+       </varlistentry>
+       <varlistentry>
+         <term><option>-O</option>
+         </term>
+         <listitem>
+           <para>Do not decompile.</para>
+         </listitem>
+       </varlistentry>
+     </variablelist>
+   </refsect1>
+   <refsect1>
+     <title>AUTHOR</title>
+ 
+     <para>This manual page was written by &dhusername; &dhemail;.
+       Permission is granted to copy, distribute and/or modify this
+       document under the terms of the &gnu; Free Documentation
+       License, Version 1.1 or any later version published by the Free
+       Software Foundation; with no Invariant Sections, no Front-Cover
+       Texts and no Back-Cover Texts.</para>
+ 
+   </refsect1>
+ </refentry>
+ 
+ <!-- Keep this comment at the end of the file
+ Local variables:
+ mode: sgml
+ sgml-omittag:t
+ sgml-shorttag:t
+ sgml-minimize-attributes:nil
+ sgml-always-quote-attributes:t
+ sgml-indent-step:2
+ sgml-indent-data:t
+ sgml-parent-document:nil
+ sgml-default-dtd-file:nil
+ sgml-exposed-tags:nil
+ sgml-local-catalogs:nil
+ sgml-local-ecat-files:nil
+ End:
+ -->
+ 
+ 


Index: llvm/test/Programs/MultiSource/Applications/hbd/id.cpp
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/id.cpp:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/id.cpp	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,27 ----
+ /* id.cpp */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #include "id.h"
+ 
+ Id idnull  = {"null",  OBJECT,  IM, 0},
+    idneg1  = {"-1",    INT,     IM, 0},
+    id0i    = {"0",     INT,     IM, 0},
+    id1i    = {"1",     INT,     IM, 0},
+    id2i    = {"2",     INT,     IM, 0},
+    id3i    = {"3",     INT,     IM, 0},
+    id4i    = {"4",     INT,     IM, 0},
+    id5i    = {"5",     INT,     IM, 0},
+    id0L    = {"0L",    LONG,    IM, 0},
+    id1L    = {"1L",    LONG,    IM, 0},
+    id0f    = {"0.0f",  FLOAT,   IM, 0},
+    id1f    = {"1.0f",  FLOAT,   IM, 0},
+    id2f    = {"2.0f",  FLOAT,   IM, 0},
+    id0d    = {"0.0d",  DOUBLE,  IM, 0},
+    id1d    = {"1.0d",  DOUBLE,  IM, 0},
+    idfalse = {"false", BOOLEAN, IM, 0},
+    idtrue  = {"true",  BOOLEAN, IM, 0};


Index: llvm/test/Programs/MultiSource/Applications/hbd/id.h
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/id.h:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/id.h	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,50 ----
+ /* id.h */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #ifndef ID_H
+ #define ID_H
+ 
+ #include "sig.h"
+ 
+ /* The location of an identifier */
+ enum Loc {
+   NO /* Not Applicable */, IM /* Immediate */,
+   CP /* Const Pool */, LO /* Local */
+ }; /* Id location */
+ 
+ /* The Id structure, which contains information
+    about one identifier. */
+ struct Id {
+   /* Its name */
+   char *name;
+ 
+   /* Its Java type */
+   Type type;
+ 
+   /* Where this ident is located */
+   Loc loc;
+ 
+   /* An index into the "loc" of where this ident is */
+   int locinfo;
+ 
+   union {
+     long linfo;
+     double dinfo;
+     long llinfo[2];
+   };
+ };
+ 
+ /* "Standard" identifiers used by the standard Exp_'s */
+ extern Id idnull, idneg1,
+           id0i, id1i, id2i, id3i, id4i, id5i,
+           id0L, id1L, 
+ 	  id0f, id1f, id2f,
+           id0d, id1d,
+           idfalse, idtrue;
+ 
+ #endif


Index: llvm/test/Programs/MultiSource/Applications/hbd/method.h
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/method.h:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/method.h	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,148 ----
+ /* method.h */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #ifndef METHOD_H
+ #define METHOD_H
+ 
+ #include "access.h"
+ #include "exp.h"
+ 
+ /* These are used by our table of blocks */
+ typedef enum { TRY, IF, DOWHILE, WHILE, GOTOLABEL } Blocktype;
+ 
+ typedef struct {
+   /* The type of block this is */
+   Blocktype tag;
+ 
+   /* Its starting and ending code offsets */
+   unsigned short start_pc;
+   unsigned short end_pc;
+ 
+   /* Other offset, depending on the block type */
+   union {
+     unsigned else_pc;
+     unsigned short handler_pc;
+   };
+ 
+   /* An index into the constant pool
+      of the class we're catching */
+   unsigned short catch_type;
+ 
+   /* The list of expressions within this block */
+   Exp *exp;
+ } Block, ExceptionTableEntry;
+ 
+ /* The line number table has these as entries.
+    They are currently parsed from the input file,
+    but not used */
+ typedef struct {
+   unsigned short start_pc;
+   unsigned short line_number;
+ } LineNumberTableEntry;
+ 
+ /* This table stores the local table information.
+    This is parsed from the input file in the
+    optional LocalVariableTable attribute */
+ typedef struct {
+   /* The first code offset where this var is used */
+   unsigned short start_pc;
+ 
+   /* The length of the scope of this local */
+   unsigned short length;
+ 
+   /* The constant pool index to its name */
+   unsigned short name_index;
+ 
+   /* The constant pool index to its type signature */
+   unsigned short signature_index;
+ 
+   /* Which local we are talking about */
+   unsigned short slot;
+ } LocalVariableTableEntry;
+ 
+ /* The main method structure */
+ typedef struct {
+   /* The access flags for this method */
+   AccessFlags access_flags;
+ 
+   /* The name of the method */
+   char *name;
+ 
+   /* Its type signature */
+   char *sig;
+ 
+   /* The maximum stack size the JVM code can use */
+   unsigned char max_stack;
+ 
+   /* The maximium number of locals in scope at any one time */
+   unsigned char max_locals;
+ 
+   /* The length of the code in bytes */
+   unsigned code_length;
+ 
+   /* The code */
+   unsigned char *code;
+ 
+   /* The exception table */
+   unsigned short exception_table_length;
+   ExceptionTableEntry *exception_table;
+ 
+   /* The line number table */
+   unsigned short line_number_table_length;
+   LineNumberTableEntry *line_number_table;
+ 
+   /* The local variable table */
+   unsigned short local_variable_table_length;
+   LocalVariableTableEntry *local_variable_table;
+ 
+   /* A table of the names of the locals.
+      These are potentially created
+      as each local is encountered. */
+   char **local_names;
+ 
+   /* The type signatures of the locals.
+      These need to be guessed if there is no
+      LocalVariableTable attribute in the method. */
+   char **local_sigs;
+ 
+   /* The first code offset where each local is used.
+      Again, these need to be guessed if there is no
+      LocalVariableTable attribute in the method. */
+   unsigned *local_firstuses;
+ 
+   /* The types of the locals,
+      corresponding to the local_sigs above */
+   Type *local_types;
+ 
+   /* The type signature of the
+      return value of the method */
+   char *ret_sig;
+ 
+   /* The type of the return value
+      corresponding to the signature above */
+   Type ret_type;
+ 
+   /* The number of different exceptions that
+      this method is able to throw and not catch */
+   int num_throws;
+ 
+   /* A table of constant-pool entries to the classes
+      that this method throws */
+   int *throws;
+ } method_info, *method_info_ptr;
+ 
+ /* This global contains the method
+    we are currently working on */
+ extern method_info *miptr;
+ 
+ /* Forward declaration */
+ typedef struct Classfile Classfile;
+ /* Decompiles the given method's code */
+ int decompileblock(Classfile *c, method_info_ptr mi);
+ 
+ #endif


Index: llvm/test/Programs/MultiSource/Applications/hbd/op.cpp
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/op.cpp:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/op.cpp	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,30 ----
+ /* op.cpp */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ char *op2str[] = {
+   " + ", " - ", " * ", " / ", " %% ", ".", " = ", " << ",
+   " >> ", " >>> ", " & ", " | ", " ^ ", "~", "-", "(cast)",
+   "return ", "throw ", "new ", "goto ", " += ", " -= ", "++", "--",
+   " ? ", " : ", " error ", " cmp ", " == ", " != ", " < ", " >= ",
+   " > ", " <= ", "!", " && ", " || ", " instanceof ", ", ",
+   ""
+ };
+ int op_prec[] = {
+   27, 27, 29, 29, 29, 39,  2, 26,
+   26, 26, 19, 17, 18, 32, 32, 39,
+   38, 38, 38, 38,  2,  2, 32, 32,
+   14, 14, 39, 20, 20, 20, 22, 22,
+   22, 22, 32, 16, 15, 32,  1,
+   39
+ };
+ int op_assoc[] = {
+   0,0,0,0,0,0,1,0,  0,0,0,0,0,0,0,0,
+   0,0,1,1,0,0,0,0,  0,0,0,0,0,0,0,0,
+   0,0,0,0,0,0,0,
+   0
+ };


Index: llvm/test/Programs/MultiSource/Applications/hbd/op.h
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/op.h:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/op.h	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,36 ----
+ /* op.h */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #ifndef _OP_H_
+ #define _OP_H_
+ 
+ /* The operations that can go in
+    the op field of the Exp struct */
+ enum Op {
+   ADD, SUB, MUL, DIV,
+   MOD, DOT, ASSIGN, SHL,
+   SHR, USHR, AND, OR,
+   XOR, NOT, NEG, CAST,
+   RETURN, THROW, NEW, GOTO,
+   ADDASSIGN, SUBASSIGN, INC, DEC,
+   COND, COND_, CMP, DUMMY,
+   EQUAL, NOTEQUAL, LESS, GREATEROREQUAL,
+   GREATER, LESSOREQUAL, NOT_BOOL, AND_BOOL,
+   OR_BOOL, INSTANCEOF, COMMA, ID
+ };
+ 
+ /* The Java string representation of the operations */
+ extern char *op2str[];
+ 
+ /* The precedence of the ops */
+ extern int op_prec[];
+ 
+ /* The accociativity of the ops */
+ extern int op_assoc[];
+ 
+ #endif


Index: llvm/test/Programs/MultiSource/Applications/hbd/options.h
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/options.h:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/options.h	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,27 ----
+ /* options.h */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #ifndef _OPTIONS_H_
+ #define _OPTIONS_H_
+ 
+ #ifdef debug_optional
+ #define DEBUG_ON 1
+ #else
+ #define DEBUG_ON 0
+ #endif
+ 
+ /* The command-line options */
+ enum CL_Options {
+   OPT_DEBUG = DEBUG_ON,
+   OPT_DECOMPILE_OFF = 2
+ };
+ 
+ //void parse_cmdline(FILE **infile_ptr, FILE **outfile_ptr,
+ //                CL_Options *options, int argc, char **argv);
+ 
+ #endif


Index: llvm/test/Programs/MultiSource/Applications/hbd/sig.cpp
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/sig.cpp:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/sig.cpp	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,145 ----
+ /* sig.cpp */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #include <stdio.h>
+ #include <string.h>
+ #include "general.h"
+ #include "class.h"
+ #include "method.h"
+ #include "sig.h"
+ #include "err.h"
+ 
+ char *type2str[] = {
+   "void", "byte", "char", "short", "int", "long", "float", "double", "object"
+ };
+ 
+ Type sig2type(char* sig)
+ {
+   switch (*sig) {
+     case SIGNATURE_BYTE: return BYTE;
+     case SIGNATURE_CHAR: return CHAR;
+     case SIGNATURE_DOUBLE: return DOUBLE;
+     case SIGNATURE_FLOAT: return FLOAT;
+     case SIGNATURE_INT: return INT;
+     case SIGNATURE_LONG: return LONG;
+     case SIGNATURE_CLASS: return OBJECT;
+     case SIGNATURE_SHORT: return SHORT;
+     case SIGNATURE_BOOLEAN: return BOOLEAN;
+     case SIGNATURE_ARRAY: return OBJECT;
+     case SIGNATURE_FUNC: return FUNC;
+     case SIGNATURE_VOID: return VOID;
+     default:
+       fprintf(stderr, "Error converting signature to a type.\n");
+       exit(1);
+   }
+   return VOID;
+ }
+ 
+ int printsigname(Classfile *c, FILE* outfile, char *&sig, char *name, void *mip)
+ {
+   method_info_ptr mi = (method_info_ptr)mip;
+   int i;
+   char *t, *t2;
+   switch(*sig++) {
+     case SIGNATURE_BYTE: fprintf(outfile, "byte %s", name); return 0;
+     case SIGNATURE_CHAR: fprintf(outfile, "char %s", name); return 0;
+     case SIGNATURE_DOUBLE: fprintf(outfile, "double %s", name); return 0;
+     case SIGNATURE_FLOAT: fprintf(outfile, "float %s", name); return 0;
+     case SIGNATURE_INT: fprintf(outfile, "int %s", name); return 0;
+     case SIGNATURE_LONG: fprintf(outfile, "long %s", name); return 0;
+     case SIGNATURE_CLASS:
+       t = sig;
+       while (*sig++ != ';') ;
+       if ((t2 = new char[sig - t]) == 0) memerr();
+       strncpy(t2, t, sig - t - 1);
+       t2[sig - t - 1] = '\0';
+       t = t2;
+       if (!strncmp(t, "java/lang/", 10)) t += 10;
+       else while ((t2 = strchr(t2, '/')) != 0) *t2 = '.';
+       i = c->package_name?strlen(c->package_name):0;
+       if (c->package_name && !strncmp(t, c->package_name, i)) t += i + 1;
+       fprintf(outfile, "%s %s", t, name);
+       return 0;
+     case SIGNATURE_SHORT: fprintf(outfile, "short %s", name); return 0;
+     case SIGNATURE_BOOLEAN: fprintf(outfile, "boolean %s", name); return 0;
+     case SIGNATURE_ARRAY:
+       i = 0;
+       while ((*sig >= '0') && (*sig <= '9')) i = (i * 10) + *sig++ - '0';
+       printsigname(c, outfile, sig, name, mi);
+       if (i) fprintf(outfile, "[%d]", i); else fprintf(outfile, "[]");
+       return 0;
+     case SIGNATURE_FUNC:
+       if (!mi) {
+         fprintf(stderr, "Non-function with function sig!\n");
+         return 0;
+       }
+       t = sig;
+       while (*sig++ != SIGNATURE_ENDFUNC) /* skip for now */;
+       if (!strcmp(name, "<clinit>")) {
+ //      fprintf(outfile, "\b");
+         return 0;
+       }
+       if ((mi->ret_sig = new char[strlen(sig) + 1]) == 0) memerr();
+       strcpy(mi->ret_sig, sig);
+       mi->ret_type = sig2type(mi->ret_sig);
+       if (strcmp(name, "<init>"))
+         printsigname(c, outfile, sig, name, mi); /* return type and name */
+       else
+         fprintf(outfile, "%s", c->this_class_name);
+       fprintf(outfile, "(");
+       mi->max_locals++;
+       if (!mi->local_variable_table_length) {
+         if (((mi->local_names = new char_ptr[mi->max_locals]) == 0) ||
+             ((mi->local_sigs = new char_ptr[mi->max_locals]) == 0) ||
+             ((mi->local_types = new Type[mi->max_locals]) == 0) ||
+             ((mi->local_firstuses = new unsigned[mi->max_locals]) == 0)) memerr();
+         for (int it = mi->max_locals; it--; ) {
+           mi->local_firstuses[it] = 0;
+           mi->local_names[it] = mi->local_sigs[it] = 0;
+           mi->local_types[it] = VOID;
+         }
+         if ((mi->access_flags & ACC_STATIC) == 0) {
+           mi->local_names[0] = "this";
+           mi->local_sigs[0] = "L";
+           mi->local_types[0] = OBJECT;
+           mi->local_firstuses[0] = 0;
+         }
+       }
+       i = ((mi->access_flags & ACC_STATIC) == 0) ? 1 : 0;
+       while (*t != SIGNATURE_ENDFUNC) {
+         if (mi->local_variable_table_length) {
+           if (strcmp(t,mi->local_sigs[i])) {
+             fprintf(stderr, "Function Parameter type mismatch\n");
+             return 1;
+           }
+           printsigname(c, outfile, t,mi->local_names[i],mi);
+         } else {
+           if ((mi->local_names[i] = new char[6]) == 0) memerr();
+           sprintf(mi->local_names[i], "var%d", i);
+           char *t2 = t;
+           printsigname(c, outfile, t,mi->local_names[i],mi);
+           if ((mi->local_sigs[i] = new char[t - t2 + 1]) == 0) memerr();
+           strncpy(mi->local_sigs[i], t2, t-t2);
+           mi->local_sigs[i][t-t2] = '\0';
+           mi->local_types[i] = sig2type(mi->local_sigs[i]);
+           mi->local_firstuses[i] = 0;
+         }
+         if ((*(t-1) == 'D') || (*(t-1) == 'J')) i++;
+         i++;
+         if (*t != SIGNATURE_ENDFUNC) fprintf(outfile, ", ");
+       }
+       fprintf(outfile, ")");
+       return 0;
+     case SIGNATURE_VOID: fprintf(outfile, "void %s", name); return 0;
+ //    case 0: fprintf(outfile, "%s", name); return 0;
+     default:
+       fprintf(stderr, "Error reading type signature!\n");
+       return 1;
+   }
+ }
+ 


Index: llvm/test/Programs/MultiSource/Applications/hbd/sig.h
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/sig.h:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/sig.h	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,73 ----
+ /* sig.h */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #ifndef SIG_H
+ #define SIG_H
+ 
+ #include <stdio.h>
+ 
+ /* The Java types */
+ typedef enum {
+   VOID, BYTE, CHAR, SHORT,
+   INT, LONG, FLOAT, DOUBLE,
+   OBJECT, ARRAY, BOOLEAN, FUNC,
+   CMPTYPE, /* -1, 0, or 1 */
+   UNKNOWN, UNKNOWN_1, UNKNOWN_4,
+   UNKNOWN_8
+ } Type;
+ 
+ /* This converts a signature string to a type */
+ Type sig2type(char* sig);
+ 
+ /* This contains string representations of the types */
+ extern char *type2str[];
+ 
+ /* These defines are used for converting sigs */
+ #define SIGNATURE_ANY           'A'
+ #define SIGNATURE_ARRAY         '['
+ #define SIGNATURE_BYTE          'B'
+ #define SIGNATURE_CHAR          'C'
+ #define SIGNATURE_CLASS         'L'
+ #define SIGNATURE_ENDCLASS      ';'
+ #define SIGNATURE_ENUM          'E'
+ #define SIGNATURE_FLOAT         'F'
+ #define SIGNATURE_DOUBLE        'D'
+ #define SIGNATURE_FUNC          '('
+ #define SIGNATURE_ENDFUNC       ')'
+ #define SIGNATURE_INT           'I'
+ #define SIGNATURE_LONG          'J'
+ #define SIGNATURE_SHORT         'S'
+ #define SIGNATURE_VOID          'V'
+ #define SIGNATURE_BOOLEAN       'Z'
+ 
+ #define SIGNATURE_ANY_STRING            "A"
+ #define SIGNATURE_ARRAY_STRING          "["
+ #define SIGNATURE_BYTE_STRING           "B"
+ #define SIGNATURE_CHAR_STRING           "C"
+ #define SIGNATURE_CLASS_STRING          "L"
+ #define SIGNATURE_ENDCLASS_STRING       ";"
+ #define SIGNATURE_ENUM_STRING           "E"
+ #define SIGNATURE_FLOAT_STRING          "F"
+ #define SIGNATURE_DOUBLE_STRING         "D"
+ #define SIGNATURE_FUNC_STRING           "("
+ #define SIGNATURE_ENDFUNC_STRING        ")"
+ #define SIGNATURE_INT_STRING            "I"
+ #define SIGNATURE_LONG_STRING           "J"
+ #define SIGNATURE_SHORT_STRING          "S"
+ #define SIGNATURE_VOID_STRING           "V"
+ #define SIGNATURE_BOOLEAN_STRING        "Z"
+ 
+ /* Forward declaration */
+ struct Classfile;
+ 
+ /* This prints the method name with return type
+    and parameters in the format used in Java source files */
+ int printsigname(Classfile *c, FILE *outfile,
+                  char *&sig, char *name, void *mi);
+ 
+ #endif


Index: llvm/test/Programs/MultiSource/Applications/hbd/version.cpp
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/version.cpp:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/version.cpp	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,23 ----
+ /* version.cpp */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #include <stdio.h>
+ #include "general.h"
+ #include "version.h"
+ #include "file.h"
+ #include "err.h"
+ #include "class.h"
+ 
+ void ClassVersion::read(Classfile *c) {
+   minor_version = get16(c->infile, &c->infile_pos);
+   if ((major_version = get16(c->infile, &c->infile_pos)) != 45)
+     fatalerror(BAD_VERSION_ERR);
+   else if (minor_version != 3) {
+     fprintf(stderr, "Warning: Class Version 45.%d. (Program designed for ver 45.3)\n", minor_version);
+   }
+ }


Index: llvm/test/Programs/MultiSource/Applications/hbd/version.h
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/hbd/version.h:1.1.2.1
*** /dev/null	Mon Mar  1 17:59:20 2004
--- llvm/test/Programs/MultiSource/Applications/hbd/version.h	Mon Mar  1 17:59:10 2004
***************
*** 0 ****
--- 1,28 ----
+ /* version.h */
+ /*
+    Java Decompiler 
+    Copyright (c) 1994-2003, Pete Ryland.
+    Distributed under the GNU GPL Version 2.
+    This package is available from http://pdr.cx/hbd/
+ */
+ 
+ #ifndef VERSION_H
+ #define VERSION_H
+ 
+ #include "general.h"
+ 
+ /* Forward declaration */
+ struct Classfile;
+ 
+ /* This struct is for the class file version */
+ struct ClassVersion {
+   u16 minor_version;
+   u16 major_version;
+ 
+   /* read() is used by the decompiler to read
+      the version of the input class file and
+      make sure it is a version that we support */
+   void read(Classfile *c);
+ };
+ 
+ #endif





More information about the llvm-commits mailing list