1 /* Program to write C++-suitable header files from a Java(TM) .class
2 file. This is similar to SUN's javah.
4 Copyright (C) 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
5 Free Software Foundation, Inc.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
14 GCC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING. If not, write to
21 the Free Software Foundation, 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA.
24 Java and all Java-based marks are trademarks or registered trademarks
25 of Sun Microsystems, Inc. in the United States and other countries.
26 The Free Software Foundation is independent of Sun Microsystems, Inc. */
28 /* Written by Per Bothner <bothner@cygnus.com>, February 1996. */
32 #include "coretypes.h"
40 #include "java-tree.h"
41 #include "java-opcodes.h"
50 /* The output file. */
53 /* Nonzero on failure. */
54 static int found_error = 0;
56 /* Nonzero if we're generating JNI output. */
59 /* When nonzero, warn when source file is newer than matching class
63 /* Directory to place resulting files in. Set by -d option. */
64 static const char *output_directory = "";
66 /* Directory to place temporary file. Set by -td option. Currently unused. */
67 static const char *temp_directory = "/tmp";
69 /* Number of friend functions we have to declare. */
70 static int friend_count;
72 /* A class can optionally have a `friend' function declared. If
73 non-NULL, this is that function. */
74 static char **friend_specs = NULL;
76 /* Number of lines we are prepending before the class. */
77 static int prepend_count;
79 /* We can prepend extra lines before the class's start. */
80 static char **prepend_specs = NULL;
82 /* Number of lines we are appending at the end of the class. */
85 /* We can append extra lines just before the class's end. */
86 static char **add_specs = NULL;
88 /* Number of lines we are appending after the class. */
89 static int append_count;
91 /* We can append extra lines after the class's end. */
92 static char **append_specs = NULL;
98 struct JCF *current_jcf;
100 /* This holds access information for the last field we examined. They
101 let us generate "private:", "public:", and "protected:" properly.
102 If 0 then we haven't previously examined any field. */
103 static JCF_u2 last_access;
105 /* Pass this macro the flags for a class and for a method. It will
106 return true if the method should be considered `final'. */
107 #define METHOD_IS_FINAL(Class, Method) \
108 (((Class) & ACC_FINAL) || ((Method) & (ACC_FINAL | ACC_PRIVATE)))
110 /* Pass this macro the flags for a method. It will return true if the
112 #define METHOD_IS_NATIVE(Method) \
113 ((Method) & ACC_NATIVE)
115 #define METHOD_IS_PRIVATE(Class, Method) \
116 (((Method) & ACC_PRIVATE) != 0)
118 /* We keep a linked list of all method names we have seen. This lets
119 us determine if a method name and a field name are in conflict. */
124 unsigned char *signature;
127 struct method_name *next;
130 /* List of method names we've seen. */
131 static struct method_name *method_name_list;
133 static void print_field_info (FILE*, JCF*, int, int, JCF_u2);
134 static void print_mangled_classname (FILE*, JCF*, const char*, int);
135 static int print_cxx_classname (FILE*, const char*, JCF*, int, int);
136 static void print_method_info (FILE*, JCF*, int, int, JCF_u2);
137 static void print_c_decl (FILE*, JCF*, int, int, int, const char *, int);
138 static void print_stub_or_jni (FILE*, JCF*, int, int, int, const char *, int);
139 static void print_full_cxx_name (FILE*, JCF*, int, int, int, const char *, int);
140 static void decompile_method (FILE*, JCF*, int);
141 static void add_class_decl (FILE*, JCF*, JCF_u2);
143 static void print_name (FILE *, JCF *, int);
144 static void print_base_classname (FILE *, JCF *, int);
145 static int utf8_cmp (const unsigned char *, int, const char *);
146 static char *cxx_keyword_subst (const unsigned char *, int);
147 static void generate_access (FILE *, JCF_u2);
148 static int name_is_method_p (const unsigned char *, int);
149 static char *get_field_name (JCF *, int, JCF_u2);
150 static void print_field_name (FILE *, JCF *, int, JCF_u2);
151 static const unsigned char *super_class_name (JCF *, int *);
152 static void print_include (FILE *, const unsigned char *, int);
153 static int gcjh_streq (const void *p1, const void *p2);
154 static int throwable_p (const unsigned char *signature);
155 static const unsigned char *
156 decode_signature_piece (FILE *, const unsigned char *,
157 const unsigned char *, int *);
158 static void print_class_decls (FILE *, JCF *, int);
159 static void error (const char *msgid, ...);
160 static void usage (void) ATTRIBUTE_NORETURN;
161 static void help (void) ATTRIBUTE_NORETURN;
162 static void version (void) ATTRIBUTE_NORETURN;
163 static int overloaded_jni_method_exists_p (const unsigned char *, int,
165 static void jni_print_char (FILE *, int);
166 static void jni_print_float (FILE *, jfloat);
167 static void jni_print_double (FILE *, jdouble);
168 static void decompile_return_statement (FILE *, JCF *, int, int, int);
170 static void handle_inner_classes (int);
172 JCF_u2 current_field_name;
173 JCF_u2 current_field_value;
174 JCF_u2 current_field_signature;
175 JCF_u2 current_field_flags;
177 #define HANDLE_START_FIELD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
178 ( current_field_name = (NAME), current_field_signature = (SIGNATURE), \
179 current_field_flags = (ACCESS_FLAGS), current_field_value = 0)
181 /* We pass over fields twice. The first time we just note the types
182 of the fields and then the start of the methods. Then we go back
183 and parse the fields for real. This is ugly. */
184 static int field_pass;
185 /* Likewise we pass over methods twice. The first time we generate
186 class decl information; the second time we generate actual method
188 static int method_pass;
190 #define HANDLE_END_FIELD() \
193 if (out && ! stubs) \
194 print_field_info (out, jcf, current_field_name, \
195 current_field_signature, \
196 current_field_flags); \
198 else if (! stubs && ! flag_jni) \
199 add_class_decl (out, jcf, current_field_signature);
201 #define HANDLE_CONSTANTVALUE(VALUEINDEX) current_field_value = (VALUEINDEX)
203 static int method_declared = 0;
204 static int method_access = 0;
205 static int method_printed = 0;
206 static int method_synthetic = 0;
207 static int method_signature = 0;
209 /* Set to 1 while the very first data member of a class is being handled. */
210 static int is_first_data_member = 0;
212 #define HANDLE_METHOD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
214 method_synthetic = 0; \
215 method_printed = 0; \
217 method_signature = SIGNATURE; \
218 if (ATTRIBUTE_COUNT) \
219 method_synthetic = peek_attribute (jcf, ATTRIBUTE_COUNT, \
220 (const char *)"Synthetic", 9); \
221 /* If a synthetic methods have been declared, its attribute aren't \
222 worth reading (and triggering side-effects). We skip them an \
223 set ATTRIBUTE_COUNT to zero so that they'll be skipped in \
224 jcf_parse_one_method. */ \
225 if (method_synthetic) \
227 skip_attribute (jcf, ATTRIBUTE_COUNT); \
228 ATTRIBUTE_COUNT = 0; \
230 if (method_pass && !method_synthetic) \
233 print_method_info (out, jcf, NAME, SIGNATURE, \
236 else if (!method_synthetic) \
238 print_method_info (NULL, jcf, NAME, SIGNATURE, \
240 if (! stubs && ! flag_jni) \
241 add_class_decl (out, jcf, SIGNATURE); \
245 #define HANDLE_CODE_ATTRIBUTE(MAX_STACK, MAX_LOCALS, CODE_LENGTH) \
246 if (out && method_declared) decompile_method (out, jcf, CODE_LENGTH);
248 static int decompiled = 0;
249 #define HANDLE_END_METHOD() \
250 if (out && method_printed && !method_synthetic) \
251 fputs (decompiled || stubs ? "\n" : ";\n", out);
253 #define HANDLE_INNERCLASSES_ATTRIBUTE(COUNT) handle_inner_classes (COUNT)
255 /* We're going to need {peek,skip}_attribute, enable their definition. */
256 #define NEED_PEEK_ATTRIBUTE
257 #define NEED_SKIP_ATTRIBUTE
259 #include "jcf-reader.c"
261 /* Print an error message and set found_error. */
263 error (const char *msgid, ...)
267 va_start (ap, msgid);
269 fprintf (stderr, "gcjh: ");
270 vfprintf (stderr, _(msgid), ap);
272 fprintf (stderr, "\n");
276 /* Print a single-precision float, suitable for parsing by g++. */
278 jni_print_float (FILE *stream, jfloat f)
280 /* It'd be nice to use __builtin_nan/__builtin_inf here but they don't
281 work in data initializers. FIXME. */
282 if (JFLOAT_FINITE (f))
290 fprintf (stream, "0x1.%.6xp%+df",
291 ((unsigned int)f.mantissa) << 1,
292 f.exponent - JFLOAT_EXP_BIAS);
294 /* Exponent of 0x01 is -125; exponent of 0x00 is *also* -125,
295 because the implicit leading 1 bit is no longer present. */
296 fprintf (stream, "0x0.%.6xp%+df",
297 ((unsigned int)f.mantissa) << 1,
298 f.exponent + 1 - JFLOAT_EXP_BIAS);
302 fputs (";\n", stream);
305 /* Print a double-precision float, suitable for parsing by g++. */
307 jni_print_double (FILE *stream, jdouble f)
309 /* It'd be nice to use __builtin_nan/__builtin_inf here but they don't
310 work in data initializers. FIXME. */
311 if (JDOUBLE_FINITE (f))
319 fprintf (stream, "0x1.%.5x%.8xp%+d",
320 f.mantissa0, f.mantissa1,
321 f.exponent - JDOUBLE_EXP_BIAS);
323 /* Exponent of 0x001 is -1022; exponent of 0x000 is *also* -1022,
324 because the implicit leading 1 bit is no longer present. */
325 fprintf (stream, "0x0.%.5x%.8xp%+d",
326 f.mantissa0, f.mantissa1,
327 f.exponent + 1 - JDOUBLE_EXP_BIAS);
330 fputs (flag_jni ? "\n" : ";\n", stream);
333 /* Print a character, appropriately mangled for JNI. */
336 jni_print_char (FILE *stream, int ch)
339 jcf_print_char (stream, ch);
340 else if (ch == '(' || ch == ')')
345 fputs ("_1", stream);
347 fputs ("_2", stream);
349 fputs ("_3", stream);
352 else if (ISALNUM (ch))
356 /* "Unicode" character. */
357 fprintf (stream, "_0%04x", ch);
361 /* Print a name from the class data. If the index does not point to a
362 string, an error results. */
365 print_name (FILE* stream, JCF* jcf, int name_index)
367 if (JPOOL_TAG (jcf, name_index) != CONSTANT_Utf8)
369 fprintf (stream, "<not a UTF8 constant>");
373 jcf_print_utf8 (stream, JPOOL_UTF_DATA (jcf, name_index),
374 JPOOL_UTF_LENGTH (jcf, name_index));
377 /* For JNI we must correctly quote each character. */
378 const unsigned char *str = JPOOL_UTF_DATA (jcf, name_index);
379 int length = JPOOL_UTF_LENGTH (jcf, name_index);
380 const unsigned char *limit = str + length;
383 int ch = UTF8_GET (str, limit);
386 fprintf (stream, "\\<invalid>");
389 jni_print_char (stream, ch);
394 /* Print base name of class. The base name is everything after the
398 print_base_classname (FILE *stream, JCF *jcf, int index)
400 int name_index = JPOOL_USHORT1 (jcf, index);
402 const unsigned char *s, *p, *limit;
404 s = JPOOL_UTF_DATA (jcf, name_index);
405 len = JPOOL_UTF_LENGTH (jcf, name_index);
410 int c = UTF8_GET (s, limit);
417 int ch = UTF8_GET (p, limit);
419 fputs ("::", stream);
421 jcf_print_char (stream, ch);
425 /* Return 0 if NAME is equal to STR, -1 if STR is "less" than NAME,
426 and 1 if STR is "greater" than NAME. */
429 utf8_cmp (const unsigned char *str, int length, const char *name)
431 const unsigned char *limit = str + length;
434 for (i = 0; name[i]; ++i)
436 int ch = UTF8_GET (str, limit);
441 return str == limit ? 0 : 1;
444 /* This is a sorted list of all C++ keywords. */
446 static const char *const cxx_keywords[] =
555 /* If NAME is the name of a C++ keyword, then return an override name.
556 This is a name that can be used in place of the keyword.
557 Otherwise, return NULL. The return value is malloc()d. */
560 cxx_keyword_subst (const unsigned char *str, int length)
562 int last = ARRAY_SIZE (cxx_keywords);
564 int mid = (last + first) / 2;
567 for (mid = (last + first) / 2;
569 old = mid, mid = (last + first) / 2)
571 int kwl = strlen (cxx_keywords[mid]);
572 int min_length = kwl > length ? length : kwl;
573 int r = utf8_cmp (str, min_length, cxx_keywords[mid]);
579 /* Skip all trailing `$'. */
580 for (i = min_length; i < length && str[i] == '$'; ++i)
582 /* We've only found a match if all the remaining characters
586 char *dup = xmalloc (2 + length - min_length + kwl);
587 strcpy (dup, cxx_keywords[mid]);
588 for (i = kwl; i < length + 1; ++i)
604 /* Generate an access control keyword based on FLAGS. */
607 generate_access (FILE *stream, JCF_u2 flags)
609 if ((flags & ACC_VISIBILITY) == last_access)
611 last_access = (flags & ACC_VISIBILITY);
616 fputs ("public: // actually package-private\n", stream);
619 fputs ("public:\n", stream);
622 fputs ("private:\n", stream);
625 fputs ("public: // actually protected\n", stream);
629 fprintf (stream, "#error unrecognized visibility %d\n",
630 (flags & ACC_VISIBILITY));
635 /* See if NAME is already the name of a method. */
637 name_is_method_p (const unsigned char *name, int length)
639 struct method_name *p;
641 for (p = method_name_list; p != NULL; p = p->next)
643 if (p->length == length && ! memcmp (p->name, name, length))
649 /* Free the method name list. */
651 free_method_name_list (void)
653 struct method_name *p = method_name_list;
656 struct method_name *next = p->next;
662 method_name_list = NULL;
665 /* If there is already a native method named NAME, whose signature is not
666 SIGNATURE, then return true. Otherwise return false. */
668 overloaded_jni_method_exists_p (const unsigned char *name, int length,
669 const char *signature, int sig_length)
671 struct method_name *p;
673 for (p = method_name_list; p != NULL; p = p->next)
676 && p->length == length
677 && ! memcmp (p->name, name, length)
678 && (p->sig_length != sig_length
679 || memcmp (p->signature, signature, sig_length)))
685 /* Get name of a field. This handles renamings due to C++ clash. */
687 get_field_name (JCF *jcf, int name_index, JCF_u2 flags)
689 unsigned char *name = JPOOL_UTF_DATA (jcf, name_index);
690 int length = JPOOL_UTF_LENGTH (jcf, name_index);
693 if (name_is_method_p (name, length))
695 /* This field name matches a method. So override the name with
696 a dummy name. This is yucky, but it isn't clear what else to
697 do. FIXME: if the field is static, then we'll be in real
699 if ((flags & ACC_STATIC))
701 error ("static field has same name as method");
705 override = xmalloc (length + 3);
706 memcpy (override, name, length);
707 strcpy (override + length, "__");
710 override = cxx_keyword_subst (name, length);
715 /* Print a field name. Convenience function for use with
718 print_field_name (FILE *stream, JCF *jcf, int name_index, JCF_u2 flags)
720 char *override = get_field_name (jcf, name_index, flags);
724 fputs (override, stream);
728 jcf_print_utf8 (stream, JPOOL_UTF_DATA (jcf, name_index),
729 JPOOL_UTF_LENGTH (jcf, name_index));
733 print_field_info (FILE *stream, JCF* jcf, int name_index, int sig_index,
736 char *override = NULL;
739 generate_access (stream, flags);
740 if (JPOOL_TAG (jcf, name_index) != CONSTANT_Utf8)
742 fprintf (stream, "<not a UTF8 constant>");
749 /* For JNI we only want to print real constants. */
751 if (! (flags & ACC_STATIC)
752 || ! (flags & ACC_FINAL)
753 || current_field_value <= 0)
755 val = JPOOL_TAG (jcf, current_field_value);
756 if (val != CONSTANT_Integer && val != CONSTANT_Long
757 && val != CONSTANT_Float && val != CONSTANT_Double)
762 /* Initial indentation. */
766 if ((flags & ACC_STATIC))
770 print_cxx_classname (stream, "#undef ", jcf, jcf->this_class, 1);
772 print_field_name (stream, jcf, name_index, 0);
773 fputs ("\n", stream);
774 print_cxx_classname (stream, "#define ", jcf, jcf->this_class, 1);
778 fputs ("static ", stream);
780 if ((flags & ACC_FINAL) && current_field_value > 0)
785 switch (JPOOL_TAG (jcf, current_field_value))
787 case CONSTANT_Integer:
790 int most_negative = 0;
792 fputs ("const jint ", stream);
793 print_field_name (stream, jcf, name_index, 0);
794 fputs (flag_jni ? " " : " = ", stream);
795 num = JPOOL_INT (jcf, current_field_value);
796 /* We single out the most negative number to print
797 specially. This avoids later warnings from g++. */
798 if (num == (jint) 0x80000000)
803 format_int (buffer, (jlong) num, 10);
804 fprintf (stream, "%sL%s%s\n", buffer,
805 most_negative ? " - 1" : "",
806 flag_jni ? "" : ";");
812 int most_negative = 0;
814 fputs ("const jlong ", stream);
815 print_field_name (stream, jcf, name_index, 0);
816 fputs (flag_jni ? " " : " = ", stream);
817 num = JPOOL_LONG (jcf, current_field_value);
818 /* We single out the most negative number to print
819 specially.. This avoids later warnings from g++. */
820 if (num == (jlong) 0x8000000000000000LL)
825 format_int (buffer, num, 10);
826 fprintf (stream, "%sLL%s%s\n", buffer,
827 most_negative ? " - 1" :"",
828 flag_jni ? "" : ";");
833 jfloat fnum = JPOOL_FLOAT (jcf, current_field_value);
835 fputs ("const jfloat ", stream);
836 print_field_name (stream, jcf, name_index, 0);
837 jni_print_float (stream, fnum);
840 case CONSTANT_Double:
842 jdouble dnum = JPOOL_DOUBLE (jcf, current_field_value);
844 fputs ("const jdouble ", stream);
845 print_field_name (stream, jcf, name_index, 0);
846 jni_print_double (stream, dnum);
850 /* We can't print this as a constant, but we can still
851 print something sensible. */
861 /* assert (! flag_jni); */
862 override = get_field_name (jcf, name_index, flags);
863 print_c_decl (stream, jcf, name_index, sig_index, 0, override, flags);
864 fputs (";\n", stream);
872 print_method_info (FILE *stream, JCF* jcf, int name_index, int sig_index,
875 const unsigned char *str;
876 int length, is_init = 0;
877 char *override = NULL;
880 method_access = flags;
881 if (stream && JPOOL_TAG (jcf, name_index) != CONSTANT_Utf8)
882 fprintf (stream, "<not a UTF8 constant>");
883 str = JPOOL_UTF_DATA (jcf, name_index);
884 length = JPOOL_UTF_LENGTH (jcf, name_index);
888 /* Ignore the internally generated method <clinit>. However,
889 treat <init> as a constructor. */
890 if (! utf8_cmp (str, length, "<init>"))
892 else if (! METHOD_IS_FINAL (jcf->access_flags, flags)
893 && ! (flags & ACC_STATIC))
895 /* FIXME: i18n bug here. Order of prints should not be
897 fprintf (stderr, _("ignored method '"));
898 jcf_print_utf8 (stderr, str, length);
899 fprintf (stderr, _("' marked virtual\n"));
907 /* During the first method pass, build a list of method names. This will
908 be used to determine if field names conflict with method names. */
911 struct method_name *nn;
913 nn = xmalloc (sizeof (struct method_name));
914 nn->name = xmalloc (length);
915 memcpy (nn->name, str, length);
917 nn->next = method_name_list;
918 nn->sig_length = JPOOL_UTF_LENGTH (jcf, sig_index);
919 nn->signature = xmalloc (nn->sig_length);
920 nn->is_native = METHOD_IS_NATIVE (flags);
921 memcpy (nn->signature, JPOOL_UTF_DATA (jcf, sig_index),
923 method_name_list = nn;
925 /* The rest of this function doesn't matter. */
929 /* We don't worry about overrides in JNI mode. */
932 /* We can't generate a method whose name is a C++ reserved word.
933 We can't just ignore the function, because that will cause
934 incorrect code to be generated if the function is virtual
935 (not only for calls to this function for for other functions
936 after it in the vtbl). So we give it a dummy name instead. */
937 override = cxx_keyword_subst (str, length);
940 if (! stubs && ! flag_jni)
944 generate_access (stream, flags);
947 if ((flags & ACC_STATIC))
948 fputs ("static ", out);
949 else if (! METHOD_IS_PRIVATE (jcf->access_flags, flags))
951 /* Don't print `virtual' if we have a constructor. */
953 fputs ("virtual ", out);
955 print_c_decl (out, jcf, name_index, sig_index, is_init, override, flags);
957 if ((flags & ACC_ABSTRACT))
964 if (METHOD_IS_NATIVE (flags))
967 print_stub_or_jni (out, jcf, name_index, sig_index,
968 is_init, override, flags);
976 /* A helper for the decompiler which prints a `return' statement where
977 the type is a reference type. If METHODTYPE and OBJECTTYPE are not
978 identical, we emit a cast. We do this because the C++ compiler
979 doesn't know that a reference can be cast to the type of an
980 interface it implements. METHODTYPE is the index of the method's
981 signature. NAMEINDEX is the index of the field name; -1 for
982 `this'. OBJECTTYPE is the index of the object's type. */
984 decompile_return_statement (FILE *out, JCF *jcf, int methodtype,
985 int nameindex, int objecttype)
988 int obj_name_len, method_name_len;
989 const unsigned char *obj_data, *method_data;
991 obj_name_len = JPOOL_UTF_LENGTH (jcf, objecttype);
992 obj_data = JPOOL_UTF_DATA (jcf, objecttype);
994 method_name_len = JPOOL_UTF_LENGTH (jcf, methodtype);
995 method_data = JPOOL_UTF_DATA (jcf, methodtype);
997 /* Skip forward to return type part of method. */
998 while (*method_data != ')')
1003 /* Skip past `)'. */
1007 /* If we see an `L', skip it and the trailing `;'. */
1008 if (method_data[0] == 'L' && method_data[method_name_len - 1] == ';')
1011 method_name_len -= 2;
1013 if (obj_data[0] == 'L' && obj_data[obj_name_len - 1] == ';')
1019 /* FIXME: if METHODTYPE is a superclass of OBJECTTYPE then we don't
1020 need a cast. Right now there is no way to determine if this is
1022 if (method_name_len != obj_name_len)
1027 for (i = 0; i < method_name_len; ++i)
1029 if (method_data[i] != obj_data[i])
1037 fputs (" { return ", out);
1041 int array_depth = 0;
1042 const unsigned char *limit;
1044 fputs ("reinterpret_cast<", out);
1046 while (*method_data == '[')
1051 fputs ("JArray<", out);
1054 /* Leading space to avoid C++ digraphs. */
1057 /* If we see an `L', skip it and the trailing `;'. Only do this
1058 if we've seen an array specification. If we don't have an
1059 array then the `L' was stripped earlier. */
1060 if (array_depth && method_data[0] == 'L'
1061 && method_data[method_name_len - 1] == ';')
1064 method_name_len -= 2;
1067 limit = method_data + method_name_len;
1068 while (method_data < limit)
1070 int ch = UTF8_GET (method_data, limit);
1074 jcf_print_char (out, ch);
1078 /* Close each array. */
1079 while (array_depth > 0)
1085 /* Close the cast. */
1089 if (nameindex == -1)
1090 fputs ("this", out);
1092 print_field_name (out, jcf, nameindex, 0);
1101 /* Try to decompile a method body. Right now we just try to handle a
1102 simple case that we can do. Expand as desired. */
1104 decompile_method (FILE *out, JCF *jcf, int code_len)
1106 const unsigned char *codes = jcf->read_ptr;
1108 uint16 name_and_type, name;
1110 /* If the method is synchronized, don't touch it. */
1111 if ((method_access & ACC_SYNCHRONIZED))
1115 && codes[0] == OPCODE_aload_0
1116 && codes[1] == OPCODE_getfield
1117 && (codes[4] == OPCODE_areturn
1118 || codes[4] == OPCODE_dreturn
1119 || codes[4] == OPCODE_freturn
1120 || codes[4] == OPCODE_ireturn
1121 || codes[4] == OPCODE_lreturn))
1123 /* Found code like `return FIELD'. */
1124 index = (codes[2] << 8) | codes[3];
1125 /* FIXME: ensure that tag is CONSTANT_Fieldref. */
1126 name_and_type = JPOOL_USHORT2 (jcf, index);
1127 /* FIXME: ensure that tag is CONSTANT_NameAndType. */
1128 name = JPOOL_USHORT1 (jcf, name_and_type);
1129 if (codes[4] == OPCODE_areturn)
1130 decompile_return_statement (out, jcf, method_signature,
1131 name, JPOOL_USHORT2 (jcf, name_and_type));
1134 fputs (" { return ", out);
1136 print_field_name (out, jcf, name, 0);
1141 else if (code_len == 2
1142 && codes[0] == OPCODE_aload_0
1143 && codes[1] == OPCODE_areturn
1144 /* We're going to generate `return this'. This only makes
1145 sense for non-static methods. */
1146 && ! (method_access & ACC_STATIC))
1148 decompile_return_statement (out, jcf, method_signature, -1,
1149 JPOOL_USHORT1 (jcf, jcf->this_class));
1152 else if (code_len == 1 && codes[0] == OPCODE_return)
1154 /* Found plain `return'. */
1155 fputs (" { }", out);
1158 else if (code_len == 2
1159 && codes[0] == OPCODE_aconst_null
1160 && codes[1] == OPCODE_areturn)
1162 /* Found `return null'. We don't want to depend on NULL being
1164 fputs (" { return 0; }", out);
1169 /* Like strcmp, but invert the return result for the hash table. This
1170 should probably be in hashtab.c to complement the existing string
1173 gcjh_streq (const void *p1, const void *p2)
1175 return ! strcmp ((char *) p1, (char *) p2);
1178 /* Return 1 if the initial part of CLNAME names a subclass of throwable,
1179 or 0 if not. CLNAME may be extracted from a signature, and can be
1180 terminated with either `;' or NULL. */
1182 throwable_p (const unsigned char *clname)
1185 unsigned char *current;
1189 /* We keep two hash tables of class names. In one we list all the
1190 classes which are subclasses of Throwable. In the other we will
1191 all other classes. We keep two tables to make the code a bit
1192 simpler; we don't have to have a structure mapping class name to
1193 a `throwable?' bit. */
1194 static htab_t throw_hash;
1195 static htab_t non_throw_hash;
1196 static int init_done = 0;
1203 /* Self-initializing. The cost of this really doesn't matter.
1204 We also don't care about freeing these, either. */
1205 throw_hash = htab_create (10, htab_hash_string, gcjh_streq,
1207 non_throw_hash = htab_create (10, htab_hash_string, gcjh_streq,
1210 /* Make sure the root classes show up in the tables. */
1211 str = (unsigned char *) xstrdup ("java.lang.Throwable");
1212 slot = htab_find_slot (throw_hash, str, INSERT);
1215 str = (unsigned char *) xstrdup ("java.lang.Object");
1216 slot = htab_find_slot (non_throw_hash, str, INSERT);
1222 for (length = 0; clname[length] != ';' && clname[length] != '\0'; ++length)
1224 current = ALLOC (length + 1);
1225 for (i = 0; i < length; ++i)
1226 current[i] = clname[i] == '/' ? '.' : clname[i];
1227 current[length] = '\0';
1229 /* We don't compute the hash slot here because the table might be
1230 modified by the recursion. In that case the slot could be
1232 if (htab_find (throw_hash, current))
1234 else if (htab_find (non_throw_hash, current))
1240 unsigned char *super, *tmp;
1241 int super_length = -1;
1242 const char *classfile_name = find_class ((char *) current, strlen ((const char *) current),
1245 if (! classfile_name)
1247 error ("couldn't find class %s", current);
1250 if (jcf_parse_preamble (&jcf) != 0
1251 || jcf_parse_constant_pool (&jcf) != 0
1252 || verify_constant_pool (&jcf) > 0)
1254 error ("parse error while reading %s", classfile_name);
1257 jcf_parse_class (&jcf);
1259 tmp = (unsigned char *) super_class_name (&jcf, &super_length);
1260 super = ALLOC (super_length + 1);
1261 memcpy (super, tmp, super_length);
1262 super[super_length] = '\0';
1264 result = throwable_p (super);
1265 slot = htab_find_slot (result ? throw_hash : non_throw_hash,
1276 /* Print one piece of a signature. Returns pointer to next parseable
1277 character on success, NULL on error. */
1278 static const unsigned char *
1279 decode_signature_piece (FILE *stream, const unsigned char *signature,
1280 const unsigned char *limit, int *need_space)
1283 int array_depth = 0;
1285 switch (signature[0])
1288 /* More spaghetti. */
1291 for (signature++; (signature < limit
1292 && ISDIGIT (*signature)); signature++)
1297 ctype = "jbyteArray";
1300 ctype = "jcharArray";
1303 ctype = "jdoubleArray";
1306 ctype = "jfloatArray";
1309 ctype = "jintArray";
1312 ctype = "jshortArray";
1315 ctype = "jlongArray";
1318 ctype = "jbooleanArray";
1321 /* We have a nested array. */
1324 fputs ("JArray<", stream);
1328 /* We have to generate a reference to JArray here, so that
1329 our output matches what the compiler does. */
1331 /* Space between `<' and `:' to avoid C++ digraphs. */
1333 fputs ("JArray< ::", stream);
1334 while (signature < limit && *signature != ';')
1336 int ch = UTF8_GET (signature, limit);
1340 fputs ("::", stream);
1342 jcf_print_char (stream, ch);
1346 fputs (" *> *", stream);
1351 /* Unparseable signature. */
1355 /* If the previous iterations left us with something to print,
1356 print it. For JNI, we always print `jobjectArray' in the
1358 if (flag_jni && (ctype == NULL || array_depth > 0))
1360 ctype = "jobjectArray";
1363 /* The `printit' case will advance SIGNATURE for us. If we
1364 don't go there, we must advance past the `;' ourselves. */
1372 /* This shouldn't happen. */
1375 case 'B': ctype = "jbyte"; goto printit;
1376 case 'C': ctype = "jchar"; goto printit;
1377 case 'D': ctype = "jdouble"; goto printit;
1378 case 'F': ctype = "jfloat"; goto printit;
1379 case 'I': ctype = "jint"; goto printit;
1380 case 'J': ctype = "jlong"; goto printit;
1381 case 'S': ctype = "jshort"; goto printit;
1382 case 'Z': ctype = "jboolean"; goto printit;
1383 case 'V': ctype = "void"; goto printit;
1387 /* We know about certain types and special-case their names. */
1388 if (! strncmp ((const char *) signature, "Ljava/lang/String;",
1389 sizeof ("Ljava/lang/String;") -1))
1391 else if (! strncmp ((const char *) signature, "Ljava/lang/Class;",
1392 sizeof ("Ljava/lang/Class;") - 1))
1394 /* Skip leading 'L' for throwable_p call. */
1395 else if (throwable_p (signature + 1))
1396 ctype = "jthrowable";
1400 while (*signature && *signature != ';')
1405 /* Print a leading "::" so we look in the right namespace. */
1406 fputs ("::", stream);
1408 while (*signature && *signature != ';')
1410 int ch = UTF8_GET (signature, limit);
1412 fputs ("::", stream);
1414 jcf_print_char (stream, ch);
1416 fputs (" *", stream);
1417 if (*signature == ';')
1423 jni_print_char (stream, *signature++);
1428 fputs (ctype, stream);
1434 while (array_depth-- > 0)
1435 fputs ("> *", stream);
1442 print_c_decl (FILE* stream, JCF* jcf, int name_index, int signature_index,
1443 int is_init, const char *name_override, int flags)
1445 if (JPOOL_TAG (jcf, signature_index) != CONSTANT_Utf8)
1447 fprintf (stream, "<not a UTF8 constant>");
1452 int length = JPOOL_UTF_LENGTH (jcf, signature_index);
1453 const unsigned char *str0 = JPOOL_UTF_DATA (jcf, signature_index);
1454 const unsigned char *str = str0;
1455 const unsigned char *limit = str + length;
1457 int is_method = str[0] == '(';
1458 const unsigned char *next;
1460 /* If printing a method, skip to the return signature and print
1461 that first. However, there is no return value if this is a
1463 if (is_method && ! is_init)
1473 /* If printing a field or an ordinary method, then print the
1474 "return value" now. */
1475 if (! is_method || ! is_init)
1477 next = decode_signature_piece (stream, str, limit, &need_space);
1480 error ("unparseable signature: '%s'", str0);
1485 /* Force the alignment of the first data member. This is
1486 because the "new" C++ ABI changed the alignment of non-POD
1487 classes. gcj, however, still uses the "old" alignment. */
1488 if (is_first_data_member && ! (flags & ACC_STATIC) && ! is_method)
1490 is_first_data_member = 0;
1491 print_cxx_classname (out, " __attribute__((aligned(__alignof__( ",
1492 jcf, jcf->super_class, 1);
1493 fputs (" )))) ", stream);
1496 /* Now print the name of the thing. */
1498 fputs (" ", stream);
1499 print_full_cxx_name (stream, jcf, name_index,
1500 signature_index, is_init, name_override,
1505 /* Print the unqualified method name followed by the signature. */
1507 print_full_cxx_name (FILE* stream, JCF* jcf, int name_index,
1508 int signature_index, int is_init,
1509 const char *name_override, int flags)
1511 int length = JPOOL_UTF_LENGTH (jcf, signature_index);
1512 const unsigned char *str0 = JPOOL_UTF_DATA (jcf, signature_index);
1513 const unsigned char *str = str0;
1514 const unsigned char *limit = str + length;
1516 int is_method = str[0] == '(';
1517 const unsigned char *next;
1520 fputs (name_override, stream);
1521 else if (name_index)
1523 /* Declare constructors specially. */
1525 print_base_classname (stream, jcf, jcf->this_class);
1527 print_name (stream, jcf, name_index);
1532 unsigned char *signature = JPOOL_UTF_DATA (jcf, signature_index);
1533 int sig_len = JPOOL_UTF_LENGTH (jcf, signature_index);
1534 if (overloaded_jni_method_exists_p (JPOOL_UTF_DATA (jcf, name_index),
1535 JPOOL_UTF_LENGTH (jcf, name_index),
1536 (const char *) signature, sig_len))
1538 /* If this method is overloaded by another native method,
1539 then include the argument information in the mangled
1541 unsigned char *limit = signature + sig_len;
1542 fputs ("__", stream);
1543 while (signature < limit)
1545 int ch = UTF8_GET (signature, limit);
1546 jni_print_char (stream, ch);
1558 /* Have a method or a constructor. Print signature pieces
1560 fputs (" (", stream);
1564 /* In JNI mode, add extra arguments. */
1567 /* FIXME: it would be nice to know if we are printing a decl
1568 or a definition, and only print `env' for the latter. */
1569 fputs ("JNIEnv *env", stream);
1571 fputs ((flags & ACC_STATIC) ? ", jclass" : ", jobject", stream);
1574 fputs (", ", stream);
1577 while (str < limit && *str != ')')
1579 next = decode_signature_piece (stream, str, limit, &need_space);
1582 error ("unparseable signature: '%s'", str0);
1586 if (next < limit && *next != ')')
1587 fputs (", ", stream);
1591 fputs (")", stream);
1595 /* This is a helper for print_stub_or_jni. */
1597 print_name_for_stub_or_jni (FILE *stream, JCF *jcf, int name_index,
1598 int signature_index, int is_init,
1599 const char *name_override, int flags)
1601 const char *const prefix = flag_jni ? "Java_" : "";
1602 print_cxx_classname (stream, prefix, jcf, jcf->this_class, 1);
1603 fputs (flag_jni ? "_" : "::", stream);
1604 print_full_cxx_name (stream, jcf, name_index,
1605 signature_index, is_init, name_override,
1610 print_stub_or_jni (FILE* stream, JCF* jcf, int name_index,
1611 int signature_index, int is_init,
1612 const char *name_override, int flags)
1614 if (JPOOL_TAG (jcf, signature_index) != CONSTANT_Utf8)
1616 fprintf (stream, "<not a UTF8 constant>");
1621 int length = JPOOL_UTF_LENGTH (jcf, signature_index);
1622 const unsigned char *str0 = JPOOL_UTF_DATA (jcf, signature_index);
1623 const unsigned char *str = str0;
1624 const unsigned char *limit = str + length;
1626 int is_method = str[0] == '(';
1627 const unsigned char *next;
1629 /* Don't print fields in the JNI case. */
1630 if (! is_method && flag_jni)
1633 if (flag_jni && ! stubs)
1634 fputs ("JNIEXPORT ", stream);
1636 /* If printing a method, skip to the return signature and print
1637 that first. However, there is no return value if this is a
1639 if (is_method && ! is_init)
1649 /* If printing a field or an ordinary method, then print the
1650 "return value" now. Note that a constructor can't be native,
1651 so we don't bother checking this in the JNI case. */
1652 if (! is_method || ! is_init)
1654 next = decode_signature_piece (stream, str, limit, &need_space);
1657 error ("unparseable signature: '%s'", str0);
1662 /* When printing a JNI header we need to respect the space. In
1663 other cases we're just going to insert a newline anyway. */
1664 fputs (need_space && ! stubs ? " " : "\n", stream);
1666 if (flag_jni && ! stubs)
1667 fputs ("JNICALL ", stream);
1669 /* Now print the name of the thing. */
1670 print_name_for_stub_or_jni (stream, jcf, name_index,
1671 signature_index, is_init, name_override,
1674 /* Print the body. */
1678 fputs ("\n{\n (*env)->FatalError (env, \"", stream);
1680 fputs ("\n{\n throw new ::java::lang::UnsupportedOperationException (JvNewStringLatin1 (\"", stream);
1681 print_name_for_stub_or_jni (stream, jcf, name_index,
1682 signature_index, is_init,
1685 fprintf (stream, " not implemented\")%s;\n}\n\n",
1686 flag_jni ? "" : ")");
1692 print_mangled_classname (FILE *stream, JCF *jcf, const char *prefix, int index)
1694 int name_index = JPOOL_USHORT1 (jcf, index);
1695 fputs (prefix, stream);
1696 jcf_print_utf8_replace (out,
1697 JPOOL_UTF_DATA (jcf, name_index),
1698 JPOOL_UTF_LENGTH (jcf, name_index),
1702 /* Print PREFIX, then a class name in C++ format. If the name refers
1703 to an array, ignore it and don't print PREFIX. Returns 1 if
1704 something was printed, 0 otherwise. */
1706 print_cxx_classname (FILE *stream, const char *prefix,
1707 JCF *jcf, int index, int add_scope)
1709 int name_index = JPOOL_USHORT1 (jcf, index);
1711 const unsigned char *s, *p, *limit;
1713 s = JPOOL_UTF_DATA (jcf, name_index);
1714 len = JPOOL_UTF_LENGTH (jcf, name_index);
1717 /* Explicitly omit arrays here. */
1719 c = UTF8_GET (p, limit);
1723 fputs (prefix, stream);
1725 /* Print a leading "::" so we look in the right namespace. */
1726 if (! flag_jni && ! stubs && add_scope)
1727 fputs ("::", stream);
1731 c = UTF8_GET (s, limit);
1733 fputs (flag_jni ? "_" : "::", stream);
1735 jni_print_char (stream, c);
1741 int written_class_count = 0;
1743 /* Return name of superclass. If LEN is not NULL, fill it with length
1745 static const unsigned char *
1746 super_class_name (JCF *derived_jcf, int *len)
1748 int supername_index = JPOOL_USHORT1 (derived_jcf, derived_jcf->super_class);
1749 int supername_length = JPOOL_UTF_LENGTH (derived_jcf, supername_index);
1750 const unsigned char *supername =
1751 JPOOL_UTF_DATA (derived_jcf, supername_index);
1754 *len = supername_length;
1760 handle_inner_classes (int count)
1764 if (out && ! flag_jni && ! stubs && count > 0)
1765 fprintf (out, "\n");
1767 for (i = 0; i < count; ++i)
1769 JCF_u2 inner_info_index = JCF_readu2 (current_jcf);
1771 /* There are a few more values here, but we don't care about
1772 them. The (void) cast is apparently the only way to avoid a
1774 (void) JCF_readu2 (current_jcf);
1775 (void) JCF_readu2 (current_jcf);
1776 (void) JCF_readu2 (current_jcf);
1778 if (out && ! flag_jni && ! stubs)
1780 print_mangled_classname (out, current_jcf, " friend class ",
1782 fprintf (out, ";\n");
1789 /* We keep track of all the `#include's we generate, so we can avoid
1794 struct include *next;
1797 /* List of all includes. */
1798 static struct include *all_includes = NULL;
1800 /* Generate a #include. */
1802 print_include (FILE *out, const unsigned char *utf8, int len)
1804 struct include *incl;
1810 len = strlen ((const char *) utf8);
1812 for (incl = all_includes; incl; incl = incl->next)
1814 /* We check the length because we might have a proper prefix. */
1815 if (len == (int) strlen (incl->name)
1816 && ! strncmp (incl->name, (const char *) utf8, len))
1820 incl = xmalloc (sizeof (struct include));
1821 incl->name = xmalloc (len + 1);
1822 strncpy (incl->name, (const char *) utf8, len);
1823 incl->name[len] = '\0';
1824 incl->next = all_includes;
1825 all_includes = incl;
1827 fputs ("#include <", out);
1828 jcf_print_utf8_replace (out, utf8, len,
1830 flag_jni ? '_' : '/');
1831 fputs (".h>\n", out);
1836 /* This is used to represent part of a package or class name. */
1839 /* The text of this part of the name. */
1841 /* True if this represents a class. */
1843 /* Linked list of all classes and packages inside this one. */
1844 struct namelet *subnamelets;
1845 /* Pointer to next sibling. */
1846 struct namelet *next;
1849 static void add_namelet (const unsigned char *, const unsigned char *,
1851 static void print_namelet (FILE *, struct namelet *, int);
1853 /* The special root namelet. */
1854 static struct namelet root =
1862 /* This extracts the next name segment from the full UTF-8 encoded
1863 package or class name and links it into the tree. It does this
1866 add_namelet (const unsigned char *name, const unsigned char *name_limit,
1867 struct namelet *parent)
1869 const unsigned char *p;
1870 struct namelet *n = NULL, *np;
1872 /* We want to skip the standard namespaces that we assume the
1873 runtime already knows about. We only do this at the top level,
1874 though, hence the check for `root'. */
1875 if (parent == &root)
1877 #define JAVALANG "java/lang/"
1878 #define JAVAIO "java/io/"
1879 #define JAVAUTIL "java/util/"
1880 if ((name_limit - name >= (int) sizeof (JAVALANG) - 1
1881 && ! strncmp ((const char *) name, JAVALANG, sizeof (JAVALANG) - 1))
1882 || (name_limit - name >= (int) sizeof (JAVAUTIL) - 1
1883 && ! strncmp ((const char *) name, JAVAUTIL, sizeof (JAVAUTIL) - 1))
1884 || (name_limit - name >= (int) sizeof (JAVAIO) - 1
1885 && ! strncmp ((const char *) name, JAVAIO, sizeof (JAVAIO) - 1)))
1889 for (p = name; p < name_limit && *p != '/'; ++p)
1892 /* Search for this name beneath the PARENT node. */
1893 for (np = parent->subnamelets; np != NULL; np = np->next)
1895 /* We check the length because we might have a proper prefix. */
1896 if ((int) strlen (np->name) == p - name &&
1897 ! strncmp ((const char *) name, np->name, p - name))
1906 n = xmalloc (sizeof (struct namelet));
1907 n->name = xmalloc (p - name + 1);
1908 strncpy (n->name, (const char *) name, p - name);
1909 n->name[p - name] = '\0';
1910 n->is_class = (p == name_limit);
1911 n->subnamelets = NULL;
1912 n->next = parent->subnamelets;
1913 parent->subnamelets = n;
1916 /* We recurse if there is more text, and if the trailing piece does
1917 not represent an inner class. */
1919 add_namelet (p + 1, name_limit, n);
1922 /* Print a single namelet. Destroys namelets while printing. */
1924 print_namelet (FILE *out, struct namelet *name, int depth)
1931 for (i = 0; i < depth; ++i)
1933 fprintf (out, "%s %s", name->is_class ? "class" : "namespace",
1935 if (name->is_class && name->subnamelets == NULL)
1941 for (i = 0; i < depth; ++i)
1947 c = name->subnamelets;
1950 struct namelet *next = c->next;
1951 print_namelet (out, c, depth + 2);
1954 name->subnamelets = NULL;
1960 for (i = 0; i < depth; ++i)
1963 /* Only print a `;' when printing a class. C++ is evil. */
1973 /* This is called to add some classes to the list of classes for which
1974 we need decls. The signature argument can be a function
1977 add_class_decl (FILE *out, JCF *jcf, JCF_u2 signature)
1979 const unsigned char *s = JPOOL_UTF_DATA (jcf, signature);
1980 int len = JPOOL_UTF_LENGTH (jcf, signature);
1983 for (i = 0; i < len; ++i)
1987 /* If we see an array, then we include the array header. */
1990 print_include (out, (const unsigned char *) "gcj/array", -1);
1994 /* We're looking for `L<stuff>;' -- everything else is
1999 for (start = ++i; i < len && s[i] != ';'; ++i)
2002 add_namelet (&s[start], &s[i], &root);
2006 /* Print declarations for all classes required by this class. Any
2007 class or package in the `java' package is assumed to be handled
2008 statically in libjava; we don't generate declarations for these.
2009 This makes the generated headers a bit easier to read. */
2011 print_class_decls (FILE *out, JCF *jcf, int self)
2013 /* Make sure to always add the current class to the list of things
2014 that should be declared. */
2015 int name_index = JPOOL_USHORT1 (jcf, self);
2017 const unsigned char *s;
2019 s = JPOOL_UTF_DATA (jcf, name_index);
2020 len = JPOOL_UTF_LENGTH (jcf, name_index);
2021 add_namelet (s, s + len, &root);
2023 if (root.subnamelets)
2025 fputs ("extern \"Java\"\n{\n", out);
2026 /* We use an initial offset of 0 because the root namelet
2027 doesn't cause anything to print. */
2028 print_namelet (out, &root, 0);
2029 fputs ("}\n\n", out);
2036 process_file (JCF *jcf, FILE *out)
2039 uint32 field_start, method_end, method_start;
2045 if (jcf_parse_preamble (jcf) != 0)
2047 error ("Not a valid Java .class file.");
2051 /* Parse and possibly print constant pool */
2052 code = jcf_parse_constant_pool (jcf);
2055 error ("error while parsing constant pool");
2058 code = verify_constant_pool (jcf);
2061 error ("error in constant pool entry #%d", code);
2065 jcf_parse_class (jcf);
2067 if (written_class_count++ == 0 && out)
2069 const char *cstart, *cstart2, *mode, *cend, *what, *jflag;
2084 mode = " -*- c++ -*-";
2090 fprintf (out, "%s DO NOT EDIT THIS FILE - it is machine generated%s%s\n\n",
2091 cstart, mode, cend);
2094 fprintf (out, "%s This file was created by `gcjh -stubs%s'.%s\n\
2096 %s This file is intended to give you a head start on implementing native\n\
2097 %s methods using %s.\n\
2098 %s Be aware: running `gcjh -stubs %s' once more for this class may\n\
2099 %s overwrite any edits you have made to this file.%s\n\n",
2100 cstart, jflag, mode,
2116 print_mangled_classname (out, jcf, "#ifndef __", jcf->this_class);
2117 fprintf (out, "__\n");
2119 print_mangled_classname (out, jcf, "#define __", jcf->this_class);
2120 fprintf (out, "__\n\n");
2124 fprintf (out, "#include <jni.h>\n\n");
2125 fprintf (out, "#ifdef __cplusplus\n");
2126 fprintf (out, "extern \"C\"\n");
2127 fprintf (out, "{\n");
2128 fprintf (out, "#endif\n");
2132 /* We do this to ensure that inline methods won't be
2133 `outlined' by g++. This works as long as method and
2134 fields are not added by the user. */
2135 fprintf (out, "#pragma interface\n");
2137 if (jcf->super_class)
2140 const unsigned char *supername =
2141 super_class_name (jcf, &super_length);
2144 print_include (out, supername, super_length);
2150 /* Strip off the ".class" portion of the name when printing
2151 the include file name. */
2153 int i, len = strlen (jcf->classname);
2154 if (len > 6 && ! strcmp (&jcf->classname[len - 6], ".class"))
2156 /* Turn the class name into a file name. */
2157 name = xmalloc (len + 1);
2158 for (i = 0; i < len; ++i)
2159 name[i] = jcf->classname[i] == '.' ? '/' : jcf->classname[i];
2161 print_include (out, (const unsigned char *) name, len);
2166 print_include (out, (const unsigned char *) "gcj/cni", -1);
2167 print_include (out, (const unsigned char *) "java/lang/UnsupportedOperationException",
2173 /* We want to parse the methods first. But we need to find where
2174 they start. So first we skip the fields, then parse the methods.
2175 Then we parse the fields and skip the methods. This is ugly, but
2176 not too bad since we need two full passes to get class decl
2177 information anyway. */
2179 field_start = JCF_TELL (jcf);
2180 jcf_parse_fields (jcf);
2182 method_start = JCF_TELL (jcf);
2184 jcf_parse_methods (jcf);
2189 if (out && ! flag_jni)
2192 print_class_decls (out, jcf, jcf->this_class);
2194 for (i = 0; i < prepend_count; ++i)
2195 fprintf (out, "%s\n", prepend_specs[i]);
2196 if (prepend_count > 0)
2201 if (! print_cxx_classname (out, "class ", jcf,
2202 jcf->this_class, 0))
2204 error ("class is of array type\n");
2207 if (jcf->super_class)
2209 if (! print_cxx_classname (out, " : public ",
2210 jcf, jcf->super_class, 1))
2212 error ("base class is of array type");
2217 fputs ("\n{\n", out);
2221 /* Now go back for second pass over methods and fields. */
2222 is_first_data_member = 1;
2224 JCF_SEEK (jcf, method_start);
2226 jcf_parse_methods (jcf);
2227 method_end = JCF_TELL (jcf);
2230 JCF_SEEK (jcf, field_start);
2231 jcf_parse_fields (jcf);
2232 JCF_SEEK (jcf, method_end);
2234 jcf_parse_final_attributes (jcf);
2240 fprintf (out, "\n#ifdef __cplusplus\n");
2241 fprintf (out, "}\n");
2242 fprintf (out, "#endif\n");
2246 /* Generate friend decl if we still must. */
2247 for (i = 0; i < friend_count; ++i)
2248 fprintf (out, " friend %s\n", friend_specs[i]);
2250 /* Generate extra declarations. */
2253 for (i = 0; i < add_count; ++i)
2254 fprintf (out, " %s\n", add_specs[i]);
2256 /* Generate an entry for the class object. */
2257 generate_access (out, ACC_PUBLIC);
2258 fprintf (out, "\n static ::java::lang::Class class$;\n");
2262 if (jcf->access_flags & ACC_INTERFACE)
2263 fputs (" __attribute__ ((java_interface))", out);
2267 if (append_count > 0)
2269 for (i = 0; i < append_count; ++i)
2270 fprintf (out, "%s\n", append_specs[i]);
2273 print_mangled_classname (out, jcf,
2274 "\n#endif /* __", jcf->this_class);
2275 fprintf (out, "__ */\n");
2281 /* This is used to mark options with no short value. */
2282 #define LONG_OPT(Num) ((Num) + 128)
2284 #define OPT_classpath LONG_OPT (0)
2285 #define OPT_CLASSPATH OPT_classpath
2286 #define OPT_bootclasspath LONG_OPT (1)
2287 #define OPT_extdirs LONG_OPT (2)
2288 #define OPT_HELP LONG_OPT (3)
2289 #define OPT_TEMP LONG_OPT (4)
2290 #define OPT_VERSION LONG_OPT (5)
2291 #define OPT_PREPEND LONG_OPT (6)
2292 #define OPT_FRIEND LONG_OPT (7)
2293 #define OPT_ADD LONG_OPT (8)
2294 #define OPT_APPEND LONG_OPT (9)
2295 #define OPT_M LONG_OPT (10)
2296 #define OPT_MM LONG_OPT (11)
2297 #define OPT_MG LONG_OPT (12)
2298 #define OPT_MD LONG_OPT (13)
2299 #define OPT_MMD LONG_OPT (14)
2301 static const struct option options[] =
2303 { "classpath", required_argument, NULL, OPT_classpath },
2304 { "bootclasspath", required_argument, NULL, OPT_bootclasspath },
2305 { "extdirs", required_argument, NULL, OPT_extdirs },
2306 { "CLASSPATH", required_argument, NULL, OPT_CLASSPATH },
2307 { "help", no_argument, NULL, OPT_HELP },
2308 { "stubs", no_argument, &stubs, 1 },
2309 { "td", required_argument, NULL, OPT_TEMP },
2310 { "verbose", no_argument, NULL, 'v' },
2311 { "version", no_argument, NULL, OPT_VERSION },
2312 { "prepend", required_argument, NULL, OPT_PREPEND },
2313 { "friend", required_argument, NULL, OPT_FRIEND },
2314 { "add", required_argument, NULL, OPT_ADD },
2315 { "append", required_argument, NULL, OPT_APPEND },
2316 { "M", no_argument, NULL, OPT_M },
2317 { "MM", no_argument, NULL, OPT_MM },
2318 { "MG", no_argument, NULL, OPT_MG },
2319 { "MD", no_argument, NULL, OPT_MD },
2320 { "MMD", no_argument, NULL, OPT_MMD },
2321 { "jni", no_argument, &flag_jni, 1 },
2322 { NULL, no_argument, NULL, 0 }
2328 fprintf (stderr, _("Try 'gcjh --help' for more information.\n"));
2335 printf (_("Usage: gcjh [OPTION]... CLASS...\n\n"));
2336 printf (_("Generate C++ header files from .class files\n\n"));
2337 printf (_(" -stubs Generate an implementation stub file\n"));
2338 printf (_(" -jni Generate a JNI header or stub\n"));
2340 printf (_(" -add TEXT Insert TEXT into class body\n"));
2341 printf (_(" -append TEXT Insert TEXT after class declaration\n"));
2342 printf (_(" -friend TEXT Insert TEXT as 'friend' declaration\n"));
2343 printf (_(" -prepend TEXT Insert TEXT before start of class\n"));
2345 printf (_(" --classpath PATH Set path to find .class files\n"));
2346 printf (_(" -IDIR Append directory to class path\n"));
2347 printf (_(" --bootclasspath PATH Override built-in class path\n"));
2348 printf (_(" --extdirs PATH Set extensions directory path\n"));
2349 printf (_(" -d DIRECTORY Set output directory name\n"));
2350 printf (_(" -o FILE Set output file name\n"));
2351 printf (_(" -td DIRECTORY Set temporary directory name\n"));
2353 printf (_(" --help Print this help, then exit\n"));
2354 printf (_(" --version Print version number, then exit\n"));
2355 printf (_(" -v, --verbose Print extra information while running\n"));
2357 printf (_(" -M Print all dependencies to stdout;\n"
2358 " suppress ordinary output\n"));
2359 printf (_(" -MM Print non-system dependencies to stdout;\n"
2360 " suppress ordinary output\n"));
2361 printf (_(" -MD Print all dependencies to stdout\n"));
2362 printf (_(" -MMD Print non-system dependencies to stdout\n"));
2363 /* We omit -MG until it is implemented. */
2365 printf (_("For bug reporting instructions, please see:\n"
2366 "%s.\n"), bug_report_url);
2373 printf ("gcjh (GCC) %s\n\n", version_string);
2374 printf ("Copyright %s 2004 Free Software Foundation, Inc.\n", _("(C)"));
2375 printf (_("This is free software; see the source for copying conditions. There is NO\n"
2376 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"));
2381 main (int argc, char** argv)
2385 char *output_file = NULL;
2386 int emit_dependencies = 0, suppress_output = 0;
2389 gcc_init_libintl ();
2393 error ("no classes specified");
2399 /* We use getopt_long_only to allow single `-' long options. For
2400 some of our options this is more natural. */
2401 while ((opt = getopt_long_only (argc, argv, "I:d:o:v", options, NULL)) != -1)
2406 /* Already handled. */
2410 output_file = optarg;
2414 output_directory = optarg;
2418 jcf_path_include_arg (optarg);
2426 jcf_path_classpath_arg (optarg);
2429 case OPT_bootclasspath:
2430 jcf_path_bootclasspath_arg (optarg);
2434 jcf_path_extdirs_arg (optarg);
2442 temp_directory = optarg;
2450 if (prepend_count == 0)
2451 prepend_specs = ALLOC (argc * sizeof (char*));
2452 prepend_specs[prepend_count++] = optarg;
2456 if (friend_count == 0)
2457 friend_specs = ALLOC (argc * sizeof (char*));
2458 friend_specs[friend_count++] = optarg;
2463 add_specs = ALLOC (argc * sizeof (char*));
2464 add_specs[add_count++] = optarg;
2468 if (append_count == 0)
2469 append_specs = ALLOC (argc * sizeof (char*));
2470 append_specs[append_count++] = optarg;
2474 emit_dependencies = 1;
2475 suppress_output = 1;
2476 jcf_dependency_init (1);
2480 emit_dependencies = 1;
2481 suppress_output = 1;
2482 jcf_dependency_init (0);
2486 error ("'-MG' option is unimplemented");
2490 emit_dependencies = 1;
2491 jcf_dependency_init (1);
2495 emit_dependencies = 1;
2496 jcf_dependency_init (0);
2507 error ("no classes specified");
2511 jcf_path_seal (verbose);
2513 if (output_file && emit_dependencies)
2515 error ("can't specify both -o and -MD");
2519 for (argi = optind; argi < argc; argi++)
2521 char *classname = argv[argi];
2522 char *current_output_file;
2523 const char *classfile_name;
2526 printf (_("Processing %s\n"), classname);
2528 jcf_dependency_reset ();
2529 classfile_name = find_class (classname, strlen (classname), &jcf, 0);
2530 if (classfile_name == NULL)
2532 error ("%s: no such class", classname);
2536 printf (_("Found in %s\n"), classfile_name);
2539 if (strcmp (output_file, "-") == 0)
2541 else if (out == NULL)
2543 out = fopen (output_file, "w");
2547 perror (output_file);
2550 current_output_file = output_file;
2554 int dir_len = strlen (output_directory);
2555 int i, classname_length = strlen (classname);
2556 current_output_file = ALLOC (dir_len + classname_length + 5);
2557 strcpy (current_output_file, output_directory);
2558 if (dir_len > 0 && output_directory[dir_len-1] != '/')
2559 current_output_file[dir_len++] = '/';
2560 for (i = 0; classname[i] != '\0'; i++)
2562 char ch = classname[i];
2565 if (flag_jni && ch == '/')
2567 current_output_file[dir_len++] = ch;
2569 if (emit_dependencies)
2571 if (suppress_output)
2573 jcf_dependency_set_dep_file ("-");
2578 /* We use `.hd' and not `.d' to avoid clashes with
2579 dependency tracking from straight compilation. */
2580 strcpy (current_output_file + dir_len, ".hd");
2581 jcf_dependency_set_dep_file (current_output_file);
2584 strcpy (current_output_file + dir_len,
2585 stubs ? (flag_jni ? ".c" : ".cc") : ".h");
2586 jcf_dependency_set_target (current_output_file);
2587 if (! suppress_output)
2589 out = fopen (current_output_file, "w");
2592 perror (current_output_file);
2597 free_method_name_list ();
2598 process_file (&jcf, out);
2600 if (current_output_file != output_file)
2601 free (current_output_file);
2602 jcf_dependency_write ();
2605 if (out != NULL && out != stdout)