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;
57 #define TOOLNAME "gjnih"
59 /* Nonzero if we're generating JNI output. */
62 #define TOOLNAME "gcjh"
67 /* When nonzero, warn when source file is newer than matching class
71 /* Directory to place resulting files in. Set by -d option. */
72 static const char *output_directory = "";
74 /* Directory to place temporary file. Set by -td option. Currently unused. */
75 static const char *temp_directory = "/tmp";
77 /* Number of friend functions we have to declare. */
78 static int friend_count;
80 /* A class can optionally have a `friend' function declared. If
81 non-NULL, this is that function. */
82 static char **friend_specs = NULL;
84 /* Number of lines we are prepending before the class. */
85 static int prepend_count;
87 /* We can prepend extra lines before the class's start. */
88 static char **prepend_specs = NULL;
90 /* Number of lines we are appending at the end of the class. */
93 /* We can append extra lines just before the class's end. */
94 static char **add_specs = NULL;
96 /* Number of lines we are appending after the class. */
97 static int append_count;
99 /* We can append extra lines after the class's end. */
100 static char **append_specs = NULL;
106 struct JCF *current_jcf;
108 /* This holds access information for the last field we examined. They
109 let us generate "private:", "public:", and "protected:" properly.
110 If 0 then we haven't previously examined any field. */
111 static JCF_u2 last_access;
113 /* Pass this macro the flags for a class and for a method. It will
114 return true if the method should be considered `final'. */
115 #define METHOD_IS_FINAL(Class, Method) \
116 (((Class) & ACC_FINAL) || ((Method) & (ACC_FINAL | ACC_PRIVATE)))
118 /* Pass this macro the flags for a method. It will return true if the
120 #define METHOD_IS_NATIVE(Method) \
121 ((Method) & ACC_NATIVE)
123 #define METHOD_IS_PRIVATE(Class, Method) \
124 (((Method) & ACC_PRIVATE) != 0)
126 /* We keep a linked list of all method names we have seen. This lets
127 us determine if a method name and a field name are in conflict. */
132 unsigned char *signature;
135 struct method_name *next;
138 /* List of method names we've seen. */
139 static struct method_name *method_name_list;
141 static void print_field_info (FILE*, JCF*, int, int, JCF_u2);
142 static void print_mangled_classname (FILE*, JCF*, const char*, int);
143 static int print_cxx_classname (FILE*, const char*, JCF*, int, int);
144 static void print_method_info (FILE*, JCF*, int, int, JCF_u2);
145 static void print_c_decl (FILE*, JCF*, int, int, int, const char *, int);
146 static void print_stub_or_jni (FILE*, JCF*, int, int, int, const char *, int);
147 static void print_full_cxx_name (FILE*, JCF*, int, int, int, const char *, int);
148 static void decompile_method (FILE*, JCF*, int);
149 static void add_class_decl (FILE*, JCF*, JCF_u2);
151 static void print_name (FILE *, JCF *, int);
152 static void print_base_classname (FILE *, JCF *, int);
153 static int utf8_cmp (const unsigned char *, int, const char *);
154 static char *cxx_keyword_subst (const unsigned char *, int);
155 static void generate_access (FILE *, JCF_u2);
156 static int name_is_method_p (const unsigned char *, int);
157 static char *get_field_name (JCF *, int, JCF_u2);
158 static void print_field_name (FILE *, JCF *, int, JCF_u2);
159 static const unsigned char *super_class_name (JCF *, int *);
160 static void print_include (FILE *, const unsigned char *, int);
161 static int gcjh_streq (const void *p1, const void *p2);
162 static int throwable_p (const unsigned char *signature);
163 static const unsigned char *
164 decode_signature_piece (FILE *, const unsigned char *,
165 const unsigned char *, int *);
166 static void print_class_decls (FILE *, JCF *, int);
167 static void error (const char *gmsgid, ...) ATTRIBUTE_PRINTF_1;
168 static void usage (void) ATTRIBUTE_NORETURN;
169 static void help (void) ATTRIBUTE_NORETURN;
170 static void version (void) ATTRIBUTE_NORETURN;
171 static int overloaded_jni_method_exists_p (const unsigned char *, int,
173 static void jni_print_char (FILE *, int);
174 static void jni_print_float (FILE *, jfloat);
175 static void jni_print_double (FILE *, jdouble);
176 static void decompile_return_statement (FILE *, JCF *, int, int, int);
178 static void handle_inner_classes (int);
180 JCF_u2 current_field_name;
181 JCF_u2 current_field_value;
182 JCF_u2 current_field_signature;
183 JCF_u2 current_field_flags;
185 #define HANDLE_START_FIELD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
186 ( current_field_name = (NAME), current_field_signature = (SIGNATURE), \
187 current_field_flags = (ACCESS_FLAGS), current_field_value = 0)
189 /* We pass over fields twice. The first time we just note the types
190 of the fields and then the start of the methods. Then we go back
191 and parse the fields for real. This is ugly. */
192 static int field_pass;
193 /* Likewise we pass over methods twice. The first time we generate
194 class decl information; the second time we generate actual method
196 static int method_pass;
198 #define HANDLE_END_FIELD() \
201 if (out && ! stubs) \
202 print_field_info (out, jcf, current_field_name, \
203 current_field_signature, \
204 current_field_flags); \
206 else if (! stubs && ! flag_jni) \
207 add_class_decl (out, jcf, current_field_signature);
209 #define HANDLE_CONSTANTVALUE(VALUEINDEX) current_field_value = (VALUEINDEX)
211 static int method_declared = 0;
212 static int method_access = 0;
213 static int method_printed = 0;
214 static int method_synthetic = 0;
215 static int method_signature = 0;
217 /* Set to 1 while the very first data member of a class is being handled. */
218 static int is_first_data_member = 0;
220 #define HANDLE_METHOD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
222 method_synthetic = 0; \
223 method_printed = 0; \
225 method_signature = SIGNATURE; \
226 if (ATTRIBUTE_COUNT) \
227 method_synthetic = peek_attribute (jcf, ATTRIBUTE_COUNT, \
228 (const char *)"Synthetic", 9); \
229 /* If a synthetic methods have been declared, its attribute aren't \
230 worth reading (and triggering side-effects). We skip them an \
231 set ATTRIBUTE_COUNT to zero so that they'll be skipped in \
232 jcf_parse_one_method. */ \
233 if (method_synthetic) \
235 skip_attribute (jcf, ATTRIBUTE_COUNT); \
236 ATTRIBUTE_COUNT = 0; \
238 if (method_pass && !method_synthetic) \
241 print_method_info (out, jcf, NAME, SIGNATURE, \
244 else if (!method_synthetic) \
246 print_method_info (NULL, jcf, NAME, SIGNATURE, \
248 if (! stubs && ! flag_jni) \
249 add_class_decl (out, jcf, SIGNATURE); \
253 #define HANDLE_CODE_ATTRIBUTE(MAX_STACK, MAX_LOCALS, CODE_LENGTH) \
254 if (out && method_declared) decompile_method (out, jcf, CODE_LENGTH);
256 static int decompiled = 0;
257 #define HANDLE_END_METHOD() \
258 if (out && method_printed && !method_synthetic) \
259 fputs (decompiled || stubs ? "\n" : ";\n", out);
261 #define HANDLE_INNERCLASSES_ATTRIBUTE(COUNT) handle_inner_classes (COUNT)
263 /* We're going to need {peek,skip}_attribute, enable their definition. */
264 #define NEED_PEEK_ATTRIBUTE
265 #define NEED_SKIP_ATTRIBUTE
267 #include "jcf-reader.c"
269 /* Print an error message and set found_error.
270 Not really gcc-internal-format message, but as error elsewhere
271 uses it, assume all users will use intersection between
272 c-format and gcc-internal-format. */
274 error (const char *gmsgid, ...)
278 va_start (ap, gmsgid);
280 fprintf (stderr, TOOLNAME ": ");
281 vfprintf (stderr, _(gmsgid), ap);
283 fprintf (stderr, "\n");
287 /* Print a single-precision float, suitable for parsing by g++. */
289 jni_print_float (FILE *stream, jfloat f)
291 /* It'd be nice to use __builtin_nan/__builtin_inf here but they don't
292 work in data initializers. FIXME. */
293 if (JFLOAT_FINITE (f))
301 fprintf (stream, "0x1.%.6xp%+df",
302 ((unsigned int)f.mantissa) << 1,
303 f.exponent - JFLOAT_EXP_BIAS);
305 /* Exponent of 0x01 is -125; exponent of 0x00 is *also* -125,
306 because the implicit leading 1 bit is no longer present. */
307 fprintf (stream, "0x0.%.6xp%+df",
308 ((unsigned int)f.mantissa) << 1,
309 f.exponent + 1 - JFLOAT_EXP_BIAS);
313 fputs (";\n", stream);
316 /* Print a double-precision float, suitable for parsing by g++. */
318 jni_print_double (FILE *stream, jdouble f)
320 /* It'd be nice to use __builtin_nan/__builtin_inf here but they don't
321 work in data initializers. FIXME. */
322 if (JDOUBLE_FINITE (f))
330 fprintf (stream, "0x1.%.5x%.8xp%+d",
331 f.mantissa0, f.mantissa1,
332 f.exponent - JDOUBLE_EXP_BIAS);
334 /* Exponent of 0x001 is -1022; exponent of 0x000 is *also* -1022,
335 because the implicit leading 1 bit is no longer present. */
336 fprintf (stream, "0x0.%.5x%.8xp%+d",
337 f.mantissa0, f.mantissa1,
338 f.exponent + 1 - JDOUBLE_EXP_BIAS);
341 fputs (flag_jni ? "\n" : ";\n", stream);
344 /* Print a character, appropriately mangled for JNI. */
347 jni_print_char (FILE *stream, int ch)
350 jcf_print_char (stream, ch);
351 else if (ch == '(' || ch == ')')
356 fputs ("_1", stream);
358 fputs ("_2", stream);
360 fputs ("_3", stream);
363 else if (ISALNUM (ch))
367 /* "Unicode" character. */
368 fprintf (stream, "_0%04x", ch);
372 /* Print a name from the class data. If the index does not point to a
373 string, an error results. */
376 print_name (FILE* stream, JCF* jcf, int name_index)
378 if (JPOOL_TAG (jcf, name_index) != CONSTANT_Utf8)
380 fprintf (stream, "<not a UTF8 constant>");
384 jcf_print_utf8 (stream, JPOOL_UTF_DATA (jcf, name_index),
385 JPOOL_UTF_LENGTH (jcf, name_index));
388 /* For JNI we must correctly quote each character. */
389 const unsigned char *str = JPOOL_UTF_DATA (jcf, name_index);
390 int length = JPOOL_UTF_LENGTH (jcf, name_index);
391 const unsigned char *limit = str + length;
394 int ch = UTF8_GET (str, limit);
397 fprintf (stream, "\\<invalid>");
400 jni_print_char (stream, ch);
405 /* Print base name of class. The base name is everything after the
409 print_base_classname (FILE *stream, JCF *jcf, int index)
411 int name_index = JPOOL_USHORT1 (jcf, index);
413 const unsigned char *s, *p, *limit;
415 s = JPOOL_UTF_DATA (jcf, name_index);
416 len = JPOOL_UTF_LENGTH (jcf, name_index);
421 int c = UTF8_GET (s, limit);
428 int ch = UTF8_GET (p, limit);
430 fputs ("::", stream);
432 jcf_print_char (stream, ch);
436 /* Return 0 if NAME is equal to STR, -1 if STR is "less" than NAME,
437 and 1 if STR is "greater" than NAME. */
440 utf8_cmp (const unsigned char *str, int length, const char *name)
442 const unsigned char *limit = str + length;
445 for (i = 0; name[i]; ++i)
447 int ch = UTF8_GET (str, limit);
452 return str == limit ? 0 : 1;
455 /* This is a sorted list of all C++ keywords. */
457 static const char *const cxx_keywords[] =
566 /* If NAME is the name of a C++ keyword, then return an override name.
567 This is a name that can be used in place of the keyword.
568 Otherwise, return NULL. The return value is malloc()d. */
571 cxx_keyword_subst (const unsigned char *str, int length)
573 int last = ARRAY_SIZE (cxx_keywords);
575 int mid = (last + first) / 2;
578 for (mid = (last + first) / 2;
580 old = mid, mid = (last + first) / 2)
582 int kwl = strlen (cxx_keywords[mid]);
583 int min_length = kwl > length ? length : kwl;
584 int r = utf8_cmp (str, min_length, cxx_keywords[mid]);
590 /* Skip all trailing `$'. */
591 for (i = min_length; i < length && str[i] == '$'; ++i)
593 /* We've only found a match if all the remaining characters
597 char *dup = xmalloc (2 + length - min_length + kwl);
598 strcpy (dup, cxx_keywords[mid]);
599 for (i = kwl; i < length + 1; ++i)
615 /* Generate an access control keyword based on FLAGS. */
618 generate_access (FILE *stream, JCF_u2 flags)
620 if ((flags & ACC_VISIBILITY) == last_access)
622 last_access = (flags & ACC_VISIBILITY);
627 fputs ("public: // actually package-private\n", stream);
630 fputs ("public:\n", stream);
633 fputs ("private:\n", stream);
636 fputs ("public: // actually protected\n", stream);
640 fprintf (stream, "#error unrecognized visibility %d\n",
641 (flags & ACC_VISIBILITY));
646 /* See if NAME is already the name of a method. */
648 name_is_method_p (const unsigned char *name, int length)
650 struct method_name *p;
652 for (p = method_name_list; p != NULL; p = p->next)
654 if (p->length == length && ! memcmp (p->name, name, length))
660 /* Free the method name list. */
662 free_method_name_list (void)
664 struct method_name *p = method_name_list;
667 struct method_name *next = p->next;
673 method_name_list = NULL;
676 /* If there is already a native method named NAME, whose signature is not
677 SIGNATURE, then return true. Otherwise return false. */
679 overloaded_jni_method_exists_p (const unsigned char *name, int length,
680 const char *signature, int sig_length)
682 struct method_name *p;
684 for (p = method_name_list; p != NULL; p = p->next)
687 && p->length == length
688 && ! memcmp (p->name, name, length)
689 && (p->sig_length != sig_length
690 || memcmp (p->signature, signature, sig_length)))
696 /* Get name of a field. This handles renamings due to C++ clash. */
698 get_field_name (JCF *jcf, int name_index, JCF_u2 flags)
700 unsigned char *name = JPOOL_UTF_DATA (jcf, name_index);
701 int length = JPOOL_UTF_LENGTH (jcf, name_index);
704 if (name_is_method_p (name, length))
706 /* This field name matches a method. So override the name with
707 a dummy name. This is yucky, but it isn't clear what else to
708 do. FIXME: if the field is static, then we'll be in real
710 if ((flags & ACC_STATIC))
712 error ("static field has same name as method");
716 override = xmalloc (length + 3);
717 memcpy (override, name, length);
718 strcpy (override + length, "__");
723 override = cxx_keyword_subst (name, length);
728 /* Print a field name. Convenience function for use with
731 print_field_name (FILE *stream, JCF *jcf, int name_index, JCF_u2 flags)
733 char *override = get_field_name (jcf, name_index, flags);
737 fputs (override, stream);
741 jcf_print_utf8 (stream, JPOOL_UTF_DATA (jcf, name_index),
742 JPOOL_UTF_LENGTH (jcf, name_index));
746 print_field_info (FILE *stream, JCF* jcf, int name_index, int sig_index,
749 char *override = NULL;
752 generate_access (stream, flags);
753 if (JPOOL_TAG (jcf, name_index) != CONSTANT_Utf8)
755 fprintf (stream, "<not a UTF8 constant>");
762 /* For JNI we only want to print real constants. */
764 if (! (flags & ACC_STATIC)
765 || ! (flags & ACC_FINAL)
766 || current_field_value <= 0)
768 val = JPOOL_TAG (jcf, current_field_value);
769 if (val != CONSTANT_Integer && val != CONSTANT_Long
770 && val != CONSTANT_Float && val != CONSTANT_Double)
775 /* Initial indentation. */
779 if ((flags & ACC_STATIC))
783 print_cxx_classname (stream, "#undef ", jcf, jcf->this_class, 1);
785 print_field_name (stream, jcf, name_index, 0);
786 fputs ("\n", stream);
787 print_cxx_classname (stream, "#define ", jcf, jcf->this_class, 1);
791 fputs ("static ", stream);
793 if ((flags & ACC_FINAL) && current_field_value > 0)
798 switch (JPOOL_TAG (jcf, current_field_value))
800 case CONSTANT_Integer:
803 int most_negative = 0;
805 fputs ("const jint ", stream);
806 print_field_name (stream, jcf, name_index, 0);
807 fputs (flag_jni ? " " : " = ", stream);
808 num = JPOOL_INT (jcf, current_field_value);
809 /* We single out the most negative number to print
810 specially. This avoids later warnings from g++. */
811 if (num == (jint) 0x80000000)
816 format_int (buffer, (jlong) num, 10);
817 fprintf (stream, "%sL%s%s\n", buffer,
818 most_negative ? " - 1" : "",
819 flag_jni ? "" : ";");
825 int most_negative = 0;
827 fputs ("const jlong ", stream);
828 print_field_name (stream, jcf, name_index, 0);
829 fputs (flag_jni ? " " : " = ", stream);
830 num = JPOOL_LONG (jcf, current_field_value);
831 /* We single out the most negative number to print
832 specially.. This avoids later warnings from g++. */
833 if (num == (jlong) 0x8000000000000000LL)
838 format_int (buffer, num, 10);
839 fprintf (stream, "%sLL%s%s\n", buffer,
840 most_negative ? " - 1" :"",
841 flag_jni ? "" : ";");
846 jfloat fnum = JPOOL_FLOAT (jcf, current_field_value);
848 fputs ("const jfloat ", stream);
849 print_field_name (stream, jcf, name_index, 0);
850 jni_print_float (stream, fnum);
853 case CONSTANT_Double:
855 jdouble dnum = JPOOL_DOUBLE (jcf, current_field_value);
857 fputs ("const jdouble ", stream);
858 print_field_name (stream, jcf, name_index, 0);
859 jni_print_double (stream, dnum);
863 /* We can't print this as a constant, but we can still
864 print something sensible. */
874 /* assert (! flag_jni); */
875 override = get_field_name (jcf, name_index, flags);
876 print_c_decl (stream, jcf, name_index, sig_index, 0, override, flags);
877 fputs (";\n", stream);
885 print_method_info (FILE *stream, JCF* jcf, int name_index, int sig_index,
888 const unsigned char *str;
889 int length, is_init = 0;
890 char *override = NULL;
893 method_access = flags;
894 if (stream && JPOOL_TAG (jcf, name_index) != CONSTANT_Utf8)
895 fprintf (stream, "<not a UTF8 constant>");
896 str = JPOOL_UTF_DATA (jcf, name_index);
897 length = JPOOL_UTF_LENGTH (jcf, name_index);
901 /* Ignore the internally generated method <clinit>. However,
902 treat <init> as a constructor. */
903 if (! utf8_cmp (str, length, "<init>"))
905 else if (! METHOD_IS_FINAL (jcf->access_flags, flags)
906 && ! (flags & ACC_STATIC))
908 /* FIXME: i18n bug here. Order of prints should not be
910 fprintf (stderr, _("ignored method '"));
911 jcf_print_utf8 (stderr, str, length);
912 fprintf (stderr, _("' marked virtual\n"));
920 /* During the first method pass, build a list of method names. This will
921 be used to determine if field names conflict with method names. */
924 struct method_name *nn;
926 nn = xmalloc (sizeof (struct method_name));
927 nn->name = xmalloc (length);
928 memcpy (nn->name, str, length);
930 nn->next = method_name_list;
931 nn->sig_length = JPOOL_UTF_LENGTH (jcf, sig_index);
932 nn->signature = xmalloc (nn->sig_length);
933 nn->is_native = METHOD_IS_NATIVE (flags);
934 memcpy (nn->signature, JPOOL_UTF_DATA (jcf, sig_index),
936 method_name_list = nn;
938 /* The rest of this function doesn't matter. */
942 /* We don't worry about overrides in JNI mode. */
945 /* We can't generate a method whose name is a C++ reserved word.
946 We can't just ignore the function, because that will cause
947 incorrect code to be generated if the function is virtual
948 (not only for calls to this function for for other functions
949 after it in the vtbl). So we give it a dummy name instead. */
950 override = cxx_keyword_subst (str, length);
953 if (! stubs && ! flag_jni)
957 generate_access (stream, flags);
960 if ((flags & ACC_STATIC))
961 fputs ("static ", out);
962 else if (! METHOD_IS_PRIVATE (jcf->access_flags, flags))
964 /* Don't print `virtual' if we have a constructor. */
966 fputs ("virtual ", out);
968 print_c_decl (out, jcf, name_index, sig_index, is_init, override, flags);
970 if ((flags & ACC_ABSTRACT))
977 if (METHOD_IS_NATIVE (flags))
980 print_stub_or_jni (out, jcf, name_index, sig_index,
981 is_init, override, flags);
989 /* A helper for the decompiler which prints a `return' statement where
990 the type is a reference type. If METHODTYPE and OBJECTTYPE are not
991 identical, we emit a cast. We do this because the C++ compiler
992 doesn't know that a reference can be cast to the type of an
993 interface it implements. METHODTYPE is the index of the method's
994 signature. NAMEINDEX is the index of the field name; -1 for
995 `this'. OBJECTTYPE is the index of the object's type. */
997 decompile_return_statement (FILE *out, JCF *jcf, int methodtype,
998 int nameindex, int objecttype)
1001 int obj_name_len, method_name_len;
1002 const unsigned char *obj_data, *method_data;
1004 obj_name_len = JPOOL_UTF_LENGTH (jcf, objecttype);
1005 obj_data = JPOOL_UTF_DATA (jcf, objecttype);
1007 method_name_len = JPOOL_UTF_LENGTH (jcf, methodtype);
1008 method_data = JPOOL_UTF_DATA (jcf, methodtype);
1010 /* Skip forward to return type part of method. */
1011 while (*method_data != ')')
1016 /* Skip past `)'. */
1020 /* If we see an `L', skip it and the trailing `;'. */
1021 if (method_data[0] == 'L' && method_data[method_name_len - 1] == ';')
1024 method_name_len -= 2;
1026 if (obj_data[0] == 'L' && obj_data[obj_name_len - 1] == ';')
1032 /* FIXME: if METHODTYPE is a superclass of OBJECTTYPE then we don't
1033 need a cast. Right now there is no way to determine if this is
1035 if (method_name_len != obj_name_len)
1040 for (i = 0; i < method_name_len; ++i)
1042 if (method_data[i] != obj_data[i])
1050 fputs (" { return ", out);
1054 int array_depth = 0;
1055 const unsigned char *limit;
1057 fputs ("reinterpret_cast<", out);
1059 while (*method_data == '[')
1064 fputs ("JArray<", out);
1067 /* Leading space to avoid C++ digraphs. */
1070 /* If we see an `L', skip it and the trailing `;'. Only do this
1071 if we've seen an array specification. If we don't have an
1072 array then the `L' was stripped earlier. */
1073 if (array_depth && method_data[0] == 'L'
1074 && method_data[method_name_len - 1] == ';')
1077 method_name_len -= 2;
1080 limit = method_data + method_name_len;
1081 while (method_data < limit)
1083 int ch = UTF8_GET (method_data, limit);
1087 jcf_print_char (out, ch);
1091 /* Close each array. */
1092 while (array_depth > 0)
1098 /* Close the cast. */
1102 if (nameindex == -1)
1103 fputs ("this", out);
1105 print_field_name (out, jcf, nameindex, 0);
1114 /* Try to decompile a method body. Right now we just try to handle a
1115 simple case that we can do. Expand as desired. */
1117 decompile_method (FILE *out, JCF *jcf, int code_len)
1119 const unsigned char *codes = jcf->read_ptr;
1121 uint16 name_and_type, name;
1123 /* If the method is synchronized, don't touch it. */
1124 if ((method_access & ACC_SYNCHRONIZED))
1128 && codes[0] == OPCODE_aload_0
1129 && codes[1] == OPCODE_getfield
1130 && (codes[4] == OPCODE_areturn
1131 || codes[4] == OPCODE_dreturn
1132 || codes[4] == OPCODE_freturn
1133 || codes[4] == OPCODE_ireturn
1134 || codes[4] == OPCODE_lreturn))
1136 /* Found code like `return FIELD'. */
1137 index = (codes[2] << 8) | codes[3];
1138 /* FIXME: ensure that tag is CONSTANT_Fieldref. */
1139 name_and_type = JPOOL_USHORT2 (jcf, index);
1140 /* FIXME: ensure that tag is CONSTANT_NameAndType. */
1141 name = JPOOL_USHORT1 (jcf, name_and_type);
1142 if (codes[4] == OPCODE_areturn)
1143 decompile_return_statement (out, jcf, method_signature,
1144 name, JPOOL_USHORT2 (jcf, name_and_type));
1147 fputs (" { return ", out);
1149 print_field_name (out, jcf, name, 0);
1154 else if (code_len == 2
1155 && codes[0] == OPCODE_aload_0
1156 && codes[1] == OPCODE_areturn
1157 /* We're going to generate `return this'. This only makes
1158 sense for non-static methods. */
1159 && ! (method_access & ACC_STATIC))
1161 decompile_return_statement (out, jcf, method_signature, -1,
1162 JPOOL_USHORT1 (jcf, jcf->this_class));
1165 else if (code_len == 1 && codes[0] == OPCODE_return)
1167 /* Found plain `return'. */
1168 fputs (" { }", out);
1171 else if (code_len == 2
1172 && codes[0] == OPCODE_aconst_null
1173 && codes[1] == OPCODE_areturn)
1175 /* Found `return null'. We don't want to depend on NULL being
1177 fputs (" { return 0; }", out);
1182 /* Like strcmp, but invert the return result for the hash table. This
1183 should probably be in hashtab.c to complement the existing string
1186 gcjh_streq (const void *p1, const void *p2)
1188 return ! strcmp ((char *) p1, (char *) p2);
1191 /* Return 1 if the initial part of CLNAME names a subclass of throwable,
1192 or 0 if not. CLNAME may be extracted from a signature, and can be
1193 terminated with either `;' or NULL. */
1195 throwable_p (const unsigned char *clname)
1198 unsigned char *current;
1202 /* We keep two hash tables of class names. In one we list all the
1203 classes which are subclasses of Throwable. In the other we will
1204 all other classes. We keep two tables to make the code a bit
1205 simpler; we don't have to have a structure mapping class name to
1206 a `throwable?' bit. */
1207 static htab_t throw_hash;
1208 static htab_t non_throw_hash;
1209 static int init_done = 0;
1216 /* Self-initializing. The cost of this really doesn't matter.
1217 We also don't care about freeing these, either. */
1218 throw_hash = htab_create (10, htab_hash_string, gcjh_streq,
1220 non_throw_hash = htab_create (10, htab_hash_string, gcjh_streq,
1223 /* Make sure the root classes show up in the tables. */
1224 str = (unsigned char *) xstrdup ("java.lang.Throwable");
1225 slot = htab_find_slot (throw_hash, str, INSERT);
1228 str = (unsigned char *) xstrdup ("java.lang.Object");
1229 slot = htab_find_slot (non_throw_hash, str, INSERT);
1235 for (length = 0; clname[length] != ';' && clname[length] != '\0'; ++length)
1237 current = ALLOC (length + 1);
1238 for (i = 0; i < length; ++i)
1239 current[i] = clname[i] == '/' ? '.' : clname[i];
1240 current[length] = '\0';
1242 /* We don't compute the hash slot here because the table might be
1243 modified by the recursion. In that case the slot could be
1245 if (htab_find (throw_hash, current))
1247 else if (htab_find (non_throw_hash, current))
1253 unsigned char *super, *tmp;
1254 int super_length = -1;
1255 const char *classfile_name = find_class ((char *) current, strlen ((const char *) current),
1258 if (! classfile_name)
1260 error ("couldn't find class %s", current);
1263 if (jcf_parse_preamble (&jcf) != 0
1264 || jcf_parse_constant_pool (&jcf) != 0
1265 || verify_constant_pool (&jcf) > 0)
1267 error ("parse error while reading %s", classfile_name);
1270 jcf_parse_class (&jcf);
1272 tmp = (unsigned char *) super_class_name (&jcf, &super_length);
1273 super = ALLOC (super_length + 1);
1274 memcpy (super, tmp, super_length);
1275 super[super_length] = '\0';
1277 result = throwable_p (super);
1278 slot = htab_find_slot (result ? throw_hash : non_throw_hash,
1289 /* Print one piece of a signature. Returns pointer to next parseable
1290 character on success, NULL on error. */
1291 static const unsigned char *
1292 decode_signature_piece (FILE *stream, const unsigned char *signature,
1293 const unsigned char *limit, int *need_space)
1296 int array_depth = 0;
1298 switch (signature[0])
1301 /* More spaghetti. */
1304 for (signature++; (signature < limit
1305 && ISDIGIT (*signature)); signature++)
1310 ctype = "jbyteArray";
1313 ctype = "jcharArray";
1316 ctype = "jdoubleArray";
1319 ctype = "jfloatArray";
1322 ctype = "jintArray";
1325 ctype = "jshortArray";
1328 ctype = "jlongArray";
1331 ctype = "jbooleanArray";
1334 /* We have a nested array. */
1337 fputs ("JArray<", stream);
1341 /* We have to generate a reference to JArray here, so that
1342 our output matches what the compiler does. */
1344 /* Space between `<' and `:' to avoid C++ digraphs. */
1346 fputs ("JArray< ::", stream);
1347 while (signature < limit && *signature != ';')
1349 int ch = UTF8_GET (signature, limit);
1353 fputs ("::", stream);
1355 jcf_print_char (stream, ch);
1359 fputs (" *> *", stream);
1364 /* Unparseable signature. */
1368 /* If the previous iterations left us with something to print,
1369 print it. For JNI, we always print `jobjectArray' in the
1371 if (flag_jni && (ctype == NULL || array_depth > 0))
1373 ctype = "jobjectArray";
1376 /* The `printit' case will advance SIGNATURE for us. If we
1377 don't go there, we must advance past the `;' ourselves. */
1385 /* This shouldn't happen. */
1388 case 'B': ctype = "jbyte"; goto printit;
1389 case 'C': ctype = "jchar"; goto printit;
1390 case 'D': ctype = "jdouble"; goto printit;
1391 case 'F': ctype = "jfloat"; goto printit;
1392 case 'I': ctype = "jint"; goto printit;
1393 case 'J': ctype = "jlong"; goto printit;
1394 case 'S': ctype = "jshort"; goto printit;
1395 case 'Z': ctype = "jboolean"; goto printit;
1396 case 'V': ctype = "void"; goto printit;
1400 /* We know about certain types and special-case their names. */
1401 if (! strncmp ((const char *) signature, "Ljava/lang/String;",
1402 sizeof ("Ljava/lang/String;") -1))
1404 else if (! strncmp ((const char *) signature, "Ljava/lang/Class;",
1405 sizeof ("Ljava/lang/Class;") - 1))
1407 /* Skip leading 'L' for throwable_p call. */
1408 else if (throwable_p (signature + 1))
1409 ctype = "jthrowable";
1413 while (*signature && *signature != ';')
1418 /* Print a leading "::" so we look in the right namespace. */
1419 fputs ("::", stream);
1421 while (*signature && *signature != ';')
1423 int ch = UTF8_GET (signature, limit);
1425 fputs ("::", stream);
1427 jcf_print_char (stream, ch);
1429 fputs (" *", stream);
1430 if (*signature == ';')
1436 jni_print_char (stream, *signature++);
1441 fputs (ctype, stream);
1447 while (array_depth-- > 0)
1448 fputs ("> *", stream);
1455 print_c_decl (FILE* stream, JCF* jcf, int name_index, int signature_index,
1456 int is_init, const char *name_override, int flags)
1458 if (JPOOL_TAG (jcf, signature_index) != CONSTANT_Utf8)
1460 fprintf (stream, "<not a UTF8 constant>");
1465 int length = JPOOL_UTF_LENGTH (jcf, signature_index);
1466 const unsigned char *str0 = JPOOL_UTF_DATA (jcf, signature_index);
1467 const unsigned char *str = str0;
1468 const unsigned char *limit = str + length;
1470 int is_method = str[0] == '(';
1471 const unsigned char *next;
1473 /* If printing a method, skip to the return signature and print
1474 that first. However, there is no return value if this is a
1476 if (is_method && ! is_init)
1486 /* If printing a field or an ordinary method, then print the
1487 "return value" now. */
1488 if (! is_method || ! is_init)
1490 next = decode_signature_piece (stream, str, limit, &need_space);
1493 error ("unparseable signature: '%s'", str0);
1498 /* Force the alignment of the first data member. This is
1499 because the "new" C++ ABI changed the alignment of non-POD
1500 classes. gcj, however, still uses the "old" alignment. */
1501 if (is_first_data_member && ! (flags & ACC_STATIC) && ! is_method)
1503 is_first_data_member = 0;
1504 print_cxx_classname (out, " __attribute__((aligned(__alignof__( ",
1505 jcf, jcf->super_class, 1);
1506 fputs (" )))) ", stream);
1509 /* Now print the name of the thing. */
1511 fputs (" ", stream);
1512 print_full_cxx_name (stream, jcf, name_index,
1513 signature_index, is_init, name_override,
1518 /* Print the unqualified method name followed by the signature. */
1520 print_full_cxx_name (FILE* stream, JCF* jcf, int name_index,
1521 int signature_index, int is_init,
1522 const char *name_override, int flags)
1524 int length = JPOOL_UTF_LENGTH (jcf, signature_index);
1525 const unsigned char *str0 = JPOOL_UTF_DATA (jcf, signature_index);
1526 const unsigned char *str = str0;
1527 const unsigned char *limit = str + length;
1529 int is_method = str[0] == '(';
1530 const unsigned char *next;
1533 fputs (name_override, stream);
1534 else if (name_index)
1536 /* Declare constructors specially. */
1538 print_base_classname (stream, jcf, jcf->this_class);
1540 print_name (stream, jcf, name_index);
1545 unsigned char *signature = JPOOL_UTF_DATA (jcf, signature_index);
1546 int sig_len = JPOOL_UTF_LENGTH (jcf, signature_index);
1547 if (overloaded_jni_method_exists_p (JPOOL_UTF_DATA (jcf, name_index),
1548 JPOOL_UTF_LENGTH (jcf, name_index),
1549 (const char *) signature, sig_len))
1551 /* If this method is overloaded by another native method,
1552 then include the argument information in the mangled
1554 unsigned char *limit = signature + sig_len;
1555 fputs ("__", stream);
1556 while (signature < limit)
1558 int ch = UTF8_GET (signature, limit);
1559 jni_print_char (stream, ch);
1571 /* Have a method or a constructor. Print signature pieces
1573 fputs (" (", stream);
1577 /* In JNI mode, add extra arguments. */
1580 /* FIXME: it would be nice to know if we are printing a decl
1581 or a definition, and only print `env' for the latter. */
1582 fputs ("JNIEnv *env", stream);
1584 fputs ((flags & ACC_STATIC) ? ", jclass" : ", jobject", stream);
1587 fputs (", ", stream);
1590 while (str < limit && *str != ')')
1592 next = decode_signature_piece (stream, str, limit, &need_space);
1595 error ("unparseable signature: '%s'", str0);
1599 if (next < limit && *next != ')')
1600 fputs (", ", stream);
1604 fputs (")", stream);
1608 /* This is a helper for print_stub_or_jni. */
1610 print_name_for_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 const char *const prefix = flag_jni ? "Java_" : "";
1615 print_cxx_classname (stream, prefix, jcf, jcf->this_class, 1);
1616 fputs (flag_jni ? "_" : "::", stream);
1617 print_full_cxx_name (stream, jcf, name_index,
1618 signature_index, is_init, name_override,
1623 print_stub_or_jni (FILE* stream, JCF* jcf, int name_index,
1624 int signature_index, int is_init,
1625 const char *name_override, int flags)
1627 if (JPOOL_TAG (jcf, signature_index) != CONSTANT_Utf8)
1629 fprintf (stream, "<not a UTF8 constant>");
1634 int length = JPOOL_UTF_LENGTH (jcf, signature_index);
1635 const unsigned char *str0 = JPOOL_UTF_DATA (jcf, signature_index);
1636 const unsigned char *str = str0;
1637 const unsigned char *limit = str + length;
1639 int is_method = str[0] == '(';
1640 const unsigned char *next;
1642 /* Don't print fields in the JNI case. */
1643 if (! is_method && flag_jni)
1646 if (flag_jni && ! stubs)
1647 fputs ("JNIEXPORT ", stream);
1649 /* If printing a method, skip to the return signature and print
1650 that first. However, there is no return value if this is a
1652 if (is_method && ! is_init)
1662 /* If printing a field or an ordinary method, then print the
1663 "return value" now. Note that a constructor can't be native,
1664 so we don't bother checking this in the JNI case. */
1665 if (! is_method || ! is_init)
1667 next = decode_signature_piece (stream, str, limit, &need_space);
1670 error ("unparseable signature: '%s'", str0);
1675 /* When printing a JNI header we need to respect the space. In
1676 other cases we're just going to insert a newline anyway. */
1677 fputs (need_space && ! stubs ? " " : "\n", stream);
1679 if (flag_jni && ! stubs)
1680 fputs ("JNICALL ", stream);
1682 /* Now print the name of the thing. */
1683 print_name_for_stub_or_jni (stream, jcf, name_index,
1684 signature_index, is_init, name_override,
1687 /* Print the body. */
1691 fputs ("\n{\n (*env)->FatalError (env, \"", stream);
1693 fputs ("\n{\n throw new ::java::lang::UnsupportedOperationException (JvNewStringLatin1 (\"", stream);
1694 print_name_for_stub_or_jni (stream, jcf, name_index,
1695 signature_index, is_init,
1698 fprintf (stream, " not implemented\")%s;\n}\n\n",
1699 flag_jni ? "" : ")");
1705 print_mangled_classname (FILE *stream, JCF *jcf, const char *prefix, int index)
1707 int name_index = JPOOL_USHORT1 (jcf, index);
1708 fputs (prefix, stream);
1709 jcf_print_utf8_replace (out,
1710 JPOOL_UTF_DATA (jcf, name_index),
1711 JPOOL_UTF_LENGTH (jcf, name_index),
1715 /* Print PREFIX, then a class name in C++ format. If the name refers
1716 to an array, ignore it and don't print PREFIX. Returns 1 if
1717 something was printed, 0 otherwise. */
1719 print_cxx_classname (FILE *stream, const char *prefix,
1720 JCF *jcf, int index, int add_scope)
1722 int name_index = JPOOL_USHORT1 (jcf, index);
1724 const unsigned char *s, *p, *limit;
1726 s = JPOOL_UTF_DATA (jcf, name_index);
1727 len = JPOOL_UTF_LENGTH (jcf, name_index);
1730 /* Explicitly omit arrays here. */
1732 c = UTF8_GET (p, limit);
1736 fputs (prefix, stream);
1738 /* Print a leading "::" so we look in the right namespace. */
1739 if (! flag_jni && ! stubs && add_scope)
1740 fputs ("::", stream);
1744 c = UTF8_GET (s, limit);
1746 fputs (flag_jni ? "_" : "::", stream);
1748 jni_print_char (stream, c);
1754 int written_class_count = 0;
1756 /* Return name of superclass. If LEN is not NULL, fill it with length
1758 static const unsigned char *
1759 super_class_name (JCF *derived_jcf, int *len)
1761 int supername_index = JPOOL_USHORT1 (derived_jcf, derived_jcf->super_class);
1762 int supername_length = JPOOL_UTF_LENGTH (derived_jcf, supername_index);
1763 const unsigned char *supername =
1764 JPOOL_UTF_DATA (derived_jcf, supername_index);
1767 *len = supername_length;
1773 handle_inner_classes (int count)
1777 if (out && ! flag_jni && ! stubs && count > 0)
1778 fprintf (out, "\n");
1780 for (i = 0; i < count; ++i)
1782 JCF_u2 inner_info_index = JCF_readu2 (current_jcf);
1784 /* There are a few more values here, but we don't care about
1785 them. The (void) cast is apparently the only way to avoid a
1787 (void) JCF_readu2 (current_jcf);
1788 (void) JCF_readu2 (current_jcf);
1789 (void) JCF_readu2 (current_jcf);
1791 if (out && ! flag_jni && ! stubs)
1793 print_mangled_classname (out, current_jcf, " friend class ",
1795 fprintf (out, ";\n");
1802 /* We keep track of all the `#include's we generate, so we can avoid
1807 struct include *next;
1810 /* List of all includes. */
1811 static struct include *all_includes = NULL;
1813 /* Generate a #include. */
1815 print_include (FILE *out, const unsigned char *utf8, int len)
1817 struct include *incl;
1823 len = strlen ((const char *) utf8);
1825 for (incl = all_includes; incl; incl = incl->next)
1827 /* We check the length because we might have a proper prefix. */
1828 if (len == (int) strlen (incl->name)
1829 && ! strncmp (incl->name, (const char *) utf8, len))
1833 incl = xmalloc (sizeof (struct include));
1834 incl->name = xmalloc (len + 1);
1835 strncpy (incl->name, (const char *) utf8, len);
1836 incl->name[len] = '\0';
1837 incl->next = all_includes;
1838 all_includes = incl;
1840 fputs ("#include <", out);
1841 jcf_print_utf8_replace (out, utf8, len,
1843 flag_jni ? '_' : '/');
1844 fputs (".h>\n", out);
1849 /* This is used to represent part of a package or class name. */
1852 /* The text of this part of the name. */
1854 /* True if this represents a class. */
1856 /* Linked list of all classes and packages inside this one. */
1857 struct namelet *subnamelets;
1858 /* Pointer to next sibling. */
1859 struct namelet *next;
1862 static void add_namelet (const unsigned char *, const unsigned char *,
1864 static void print_namelet (FILE *, struct namelet *, int);
1866 /* The special root namelet. */
1867 static struct namelet root =
1875 /* This extracts the next name segment from the full UTF-8 encoded
1876 package or class name and links it into the tree. It does this
1879 add_namelet (const unsigned char *name, const unsigned char *name_limit,
1880 struct namelet *parent)
1882 const unsigned char *p;
1883 struct namelet *n = NULL, *np;
1885 /* We want to skip the standard namespaces that we assume the
1886 runtime already knows about. We only do this at the top level,
1887 though, hence the check for `root'. */
1888 if (parent == &root)
1890 #define JAVALANG "java/lang/"
1891 #define JAVAIO "java/io/"
1892 #define JAVAUTIL "java/util/"
1893 if ((name_limit - name >= (int) sizeof (JAVALANG) - 1
1894 && ! strncmp ((const char *) name, JAVALANG, sizeof (JAVALANG) - 1))
1895 || (name_limit - name >= (int) sizeof (JAVAUTIL) - 1
1896 && ! strncmp ((const char *) name, JAVAUTIL, sizeof (JAVAUTIL) - 1))
1897 || (name_limit - name >= (int) sizeof (JAVAIO) - 1
1898 && ! strncmp ((const char *) name, JAVAIO, sizeof (JAVAIO) - 1)))
1902 for (p = name; p < name_limit && *p != '/'; ++p)
1905 /* Search for this name beneath the PARENT node. */
1906 for (np = parent->subnamelets; np != NULL; np = np->next)
1908 /* We check the length because we might have a proper prefix. */
1909 if ((int) strlen (np->name) == p - name &&
1910 ! strncmp ((const char *) name, np->name, p - name))
1919 n = xmalloc (sizeof (struct namelet));
1920 n->name = xmalloc (p - name + 1);
1921 strncpy (n->name, (const char *) name, p - name);
1922 n->name[p - name] = '\0';
1923 n->is_class = (p == name_limit);
1924 n->subnamelets = NULL;
1925 n->next = parent->subnamelets;
1926 parent->subnamelets = n;
1929 /* We recurse if there is more text, and if the trailing piece does
1930 not represent an inner class. */
1932 add_namelet (p + 1, name_limit, n);
1935 /* Print a single namelet. Destroys namelets while printing. */
1937 print_namelet (FILE *out, struct namelet *name, int depth)
1944 for (i = 0; i < depth; ++i)
1946 fprintf (out, "%s %s", name->is_class ? "class" : "namespace",
1948 if (name->is_class && name->subnamelets == NULL)
1954 for (i = 0; i < depth; ++i)
1960 c = name->subnamelets;
1963 struct namelet *next = c->next;
1964 print_namelet (out, c, depth + 2);
1967 name->subnamelets = NULL;
1973 for (i = 0; i < depth; ++i)
1976 /* Only print a `;' when printing a class. C++ is evil. */
1986 /* This is called to add some classes to the list of classes for which
1987 we need decls. The signature argument can be a function
1990 add_class_decl (FILE *out, JCF *jcf, JCF_u2 signature)
1992 const unsigned char *s = JPOOL_UTF_DATA (jcf, signature);
1993 int len = JPOOL_UTF_LENGTH (jcf, signature);
1996 for (i = 0; i < len; ++i)
2000 /* If we see an array, then we include the array header. */
2003 print_include (out, (const unsigned char *) "gcj/array", -1);
2007 /* We're looking for `L<stuff>;' -- everything else is
2012 for (start = ++i; i < len && s[i] != ';'; ++i)
2015 add_namelet (&s[start], &s[i], &root);
2019 /* Print declarations for all classes required by this class. Any
2020 class or package in the `java' package is assumed to be handled
2021 statically in libjava; we don't generate declarations for these.
2022 This makes the generated headers a bit easier to read. */
2024 print_class_decls (FILE *out, JCF *jcf, int self)
2026 /* Make sure to always add the current class to the list of things
2027 that should be declared. */
2028 int name_index = JPOOL_USHORT1 (jcf, self);
2030 const unsigned char *s;
2032 s = JPOOL_UTF_DATA (jcf, name_index);
2033 len = JPOOL_UTF_LENGTH (jcf, name_index);
2034 add_namelet (s, s + len, &root);
2036 if (root.subnamelets)
2038 fputs ("extern \"Java\"\n{\n", out);
2039 /* We use an initial offset of 0 because the root namelet
2040 doesn't cause anything to print. */
2041 print_namelet (out, &root, 0);
2042 fputs ("}\n\n", out);
2049 process_file (JCF *jcf, FILE *out)
2052 uint32 field_start, method_end, method_start;
2058 if (jcf_parse_preamble (jcf) != 0)
2060 error ("Not a valid Java .class file.");
2064 /* Parse and possibly print constant pool */
2065 code = jcf_parse_constant_pool (jcf);
2068 error ("error while parsing constant pool");
2071 code = verify_constant_pool (jcf);
2074 error ("error in constant pool entry #%d", code);
2078 jcf_parse_class (jcf);
2080 if (written_class_count++ == 0 && out)
2082 const char *cstart, *cstart2, *mode, *cend, *what, *jflag;
2097 mode = " -*- c++ -*-";
2103 fprintf (out, "%s DO NOT EDIT THIS FILE - it is machine generated%s%s\n\n",
2104 cstart, mode, cend);
2107 fprintf (out, "%s This file was created by `" TOOLNAME " -stubs%s'.%s\n\
2109 %s This file is intended to give you a head start on implementing native\n\
2110 %s methods using %s.\n\
2111 %s Be aware: running `" TOOLNAME " -stubs %s' once more for this class may\n\
2112 %s overwrite any edits you have made to this file.%s\n\n",
2113 cstart, jflag, mode,
2129 print_mangled_classname (out, jcf, "#ifndef __", jcf->this_class);
2130 fprintf (out, "__\n");
2132 print_mangled_classname (out, jcf, "#define __", jcf->this_class);
2133 fprintf (out, "__\n\n");
2137 fprintf (out, "#include <jni.h>\n\n");
2138 fprintf (out, "#ifdef __cplusplus\n");
2139 fprintf (out, "extern \"C\"\n");
2140 fprintf (out, "{\n");
2141 fprintf (out, "#endif\n");
2145 /* We do this to ensure that inline methods won't be
2146 `outlined' by g++. This works as long as method and
2147 fields are not added by the user. */
2148 fprintf (out, "#pragma interface\n");
2150 if (jcf->super_class)
2153 const unsigned char *supername =
2154 super_class_name (jcf, &super_length);
2157 print_include (out, supername, super_length);
2163 /* Strip off the ".class" portion of the name when printing
2164 the include file name. */
2166 int i, len = strlen (jcf->classname);
2167 if (len > 6 && ! strcmp (&jcf->classname[len - 6], ".class"))
2169 /* Turn the class name into a file name. */
2170 name = xmalloc (len + 1);
2171 for (i = 0; i < len; ++i)
2172 name[i] = jcf->classname[i] == '.' ? '/' : jcf->classname[i];
2174 print_include (out, (const unsigned char *) name, len);
2179 print_include (out, (const unsigned char *) "gcj/cni", -1);
2180 print_include (out, (const unsigned char *) "java/lang/UnsupportedOperationException",
2186 /* We want to parse the methods first. But we need to find where
2187 they start. So first we skip the fields, then parse the methods.
2188 Then we parse the fields and skip the methods. This is ugly, but
2189 not too bad since we need two full passes to get class decl
2190 information anyway. */
2192 field_start = JCF_TELL (jcf);
2193 jcf_parse_fields (jcf);
2195 method_start = JCF_TELL (jcf);
2197 jcf_parse_methods (jcf);
2202 if (out && ! flag_jni)
2205 print_class_decls (out, jcf, jcf->this_class);
2207 for (i = 0; i < prepend_count; ++i)
2208 fprintf (out, "%s\n", prepend_specs[i]);
2209 if (prepend_count > 0)
2214 if (! print_cxx_classname (out, "class ", jcf,
2215 jcf->this_class, 0))
2217 error ("class is of array type\n");
2220 if (jcf->super_class)
2222 if (! print_cxx_classname (out, " : public ",
2223 jcf, jcf->super_class, 1))
2225 error ("base class is of array type");
2230 fputs ("\n{\n", out);
2234 /* Now go back for second pass over methods and fields. */
2235 is_first_data_member = 1;
2237 JCF_SEEK (jcf, method_start);
2239 jcf_parse_methods (jcf);
2240 method_end = JCF_TELL (jcf);
2243 JCF_SEEK (jcf, field_start);
2244 jcf_parse_fields (jcf);
2245 JCF_SEEK (jcf, method_end);
2247 jcf_parse_final_attributes (jcf);
2253 fprintf (out, "\n#ifdef __cplusplus\n");
2254 fprintf (out, "}\n");
2255 fprintf (out, "#endif\n");
2259 /* Generate friend decl if we still must. */
2260 for (i = 0; i < friend_count; ++i)
2261 fprintf (out, " friend %s\n", friend_specs[i]);
2263 /* Generate extra declarations. */
2266 for (i = 0; i < add_count; ++i)
2267 fprintf (out, " %s\n", add_specs[i]);
2269 /* Generate an entry for the class object. */
2270 generate_access (out, ACC_PUBLIC);
2271 fprintf (out, "\n static ::java::lang::Class class$;\n");
2275 if (jcf->access_flags & ACC_INTERFACE)
2276 fputs (" __attribute__ ((java_interface))", out);
2280 if (append_count > 0)
2282 for (i = 0; i < append_count; ++i)
2283 fprintf (out, "%s\n", append_specs[i]);
2286 print_mangled_classname (out, jcf,
2287 "\n#endif /* __", jcf->this_class);
2288 fprintf (out, "__ */\n");
2294 /* This is used to mark options with no short value. */
2295 #define LONG_OPT(Num) ((Num) + 128)
2297 #define OPT_classpath LONG_OPT (0)
2298 #define OPT_CLASSPATH OPT_classpath
2299 #define OPT_bootclasspath LONG_OPT (1)
2300 #define OPT_extdirs LONG_OPT (2)
2301 #define OPT_HELP LONG_OPT (3)
2302 #define OPT_TEMP LONG_OPT (4)
2303 #define OPT_VERSION LONG_OPT (5)
2304 #define OPT_PREPEND LONG_OPT (6)
2305 #define OPT_FRIEND LONG_OPT (7)
2306 #define OPT_ADD LONG_OPT (8)
2307 #define OPT_APPEND LONG_OPT (9)
2308 #define OPT_M LONG_OPT (10)
2309 #define OPT_MM LONG_OPT (11)
2310 #define OPT_MG LONG_OPT (12)
2311 #define OPT_MD LONG_OPT (13)
2312 #define OPT_MMD LONG_OPT (14)
2313 #define OPT_FORCE LONG_OPT (15)
2314 #define OPT_OLD LONG_OPT (16)
2315 #define OPT_TRACE LONG_OPT (17)
2317 static const struct option options[] =
2319 { "classpath", required_argument, NULL, OPT_classpath },
2320 { "bootclasspath", required_argument, NULL, OPT_bootclasspath },
2321 { "extdirs", required_argument, NULL, OPT_extdirs },
2322 { "CLASSPATH", required_argument, NULL, OPT_CLASSPATH },
2323 { "help", no_argument, NULL, OPT_HELP },
2324 { "stubs", no_argument, &stubs, 1 },
2325 { "td", required_argument, NULL, OPT_TEMP },
2326 { "verbose", no_argument, NULL, 'v' },
2327 { "version", no_argument, NULL, OPT_VERSION },
2328 { "prepend", required_argument, NULL, OPT_PREPEND },
2329 { "friend", required_argument, NULL, OPT_FRIEND },
2330 { "add", required_argument, NULL, OPT_ADD },
2331 { "append", required_argument, NULL, OPT_APPEND },
2332 { "M", no_argument, NULL, OPT_M },
2333 { "MM", no_argument, NULL, OPT_MM },
2334 { "MG", no_argument, NULL, OPT_MG },
2335 { "MD", no_argument, NULL, OPT_MD },
2336 { "MMD", no_argument, NULL, OPT_MMD },
2337 { "jni", no_argument, &flag_jni, 1 },
2338 { "force", no_argument, NULL, OPT_FORCE },
2339 /* If the output file should be named "ld" then a space is needed
2340 between -o and its argument, ld. */
2341 { "old", no_argument, NULL, OPT_OLD },
2342 { "trace", no_argument, NULL, OPT_TRACE },
2343 { NULL, required_argument, NULL, 'J' },
2344 { NULL, no_argument, NULL, 0 }
2350 fprintf (stderr, _("Try '" TOOLNAME " --help' for more information.\n"));
2357 printf (_("Usage: " TOOLNAME " [OPTION]... CLASS...\n\n"));
2358 printf (_("Generate C or C++ header files from .class files\n\n"));
2359 printf (_(" -stubs Generate an implementation stub file\n"));
2360 printf (_(" -jni Generate a JNI header or stub\n"));
2361 printf (_(" -force Always overwrite output files\n"));
2362 printf (_(" -old Unused compatibility option\n"));
2363 printf (_(" -trace Unused compatibility option\n"));
2364 printf (_(" -J OPTION Unused compatibility option\n"));
2366 printf (_(" -add TEXT Insert TEXT into class body\n"));
2367 printf (_(" -append TEXT Insert TEXT after class declaration\n"));
2368 printf (_(" -friend TEXT Insert TEXT as 'friend' declaration\n"));
2369 printf (_(" -prepend TEXT Insert TEXT before start of class\n"));
2371 printf (_(" --classpath PATH Set path to find .class files\n"));
2372 printf (_(" -IDIR Append directory to class path\n"));
2373 printf (_(" --bootclasspath PATH Override built-in class path\n"));
2374 printf (_(" --extdirs PATH Set extensions directory path\n"));
2375 printf (_(" -d DIRECTORY Set output directory name\n"));
2376 printf (_(" -o FILE Set output file name\n"));
2377 printf (_(" -td DIRECTORY Set temporary directory name\n"));
2379 printf (_(" --help Print this help, then exit\n"));
2380 printf (_(" --version Print version number, then exit\n"));
2381 printf (_(" -v, --verbose Print extra information while running\n"));
2383 printf (_(" -M Print all dependencies to stdout;\n"
2384 " suppress ordinary output\n"));
2385 printf (_(" -MM Print non-system dependencies to stdout;\n"
2386 " suppress ordinary output\n"));
2387 printf (_(" -MD Print all dependencies to stdout\n"));
2388 printf (_(" -MMD Print non-system dependencies to stdout\n"));
2389 /* We omit -MG until it is implemented. */
2391 printf (_("For bug reporting instructions, please see:\n"
2392 "%s.\n"), bug_report_url);
2399 printf (TOOLNAME " (GCC) %s\n\n", version_string);
2400 printf ("Copyright %s 2004 Free Software Foundation, Inc.\n", _("(C)"));
2401 printf (_("This is free software; see the source for copying conditions. There is NO\n"
2402 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"));
2407 main (int argc, char** argv)
2411 char *output_file = NULL;
2412 int emit_dependencies = 0, suppress_output = 0;
2414 int local_found_error;
2416 /* Unlock the stdio streams. */
2417 unlock_std_streams ();
2419 gcc_init_libintl ();
2423 error ("no classes specified");
2429 /* We use getopt_long_only to allow single `-' long options. For
2430 some of our options this is more natural. */
2431 while ((opt = getopt_long_only (argc, argv, "J:I:d:o:v", options, NULL)) != -1)
2436 /* Already handled. */
2440 output_file = optarg;
2444 output_directory = optarg;
2448 jcf_path_include_arg (optarg);
2456 jcf_path_classpath_arg (optarg);
2459 case OPT_bootclasspath:
2460 jcf_path_bootclasspath_arg (optarg);
2464 jcf_path_extdirs_arg (optarg);
2472 temp_directory = optarg;
2480 if (prepend_count == 0)
2481 prepend_specs = ALLOC (argc * sizeof (char*));
2482 prepend_specs[prepend_count++] = optarg;
2486 if (friend_count == 0)
2487 friend_specs = ALLOC (argc * sizeof (char*));
2488 friend_specs[friend_count++] = optarg;
2493 add_specs = ALLOC (argc * sizeof (char*));
2494 add_specs[add_count++] = optarg;
2498 if (append_count == 0)
2499 append_specs = ALLOC (argc * sizeof (char*));
2500 append_specs[append_count++] = optarg;
2504 emit_dependencies = 1;
2505 suppress_output = 1;
2506 jcf_dependency_init (1);
2510 emit_dependencies = 1;
2511 suppress_output = 1;
2512 jcf_dependency_init (0);
2516 error ("'-MG' option is unimplemented");
2520 emit_dependencies = 1;
2521 jcf_dependency_init (1);
2525 emit_dependencies = 1;
2526 jcf_dependency_init (0);
2539 /* Ignore -J options. */
2550 error ("no classes specified");
2554 jcf_path_seal (verbose);
2556 if (output_file && emit_dependencies)
2558 error ("can't specify both -o and -MD");
2562 local_found_error = 0;
2563 for (argi = optind; argi < argc; argi++)
2565 char *classname = argv[argi];
2566 char *current_output_file = NULL;
2567 const char *classfile_name;
2569 /* We reset the error state here so that we can detect errors
2570 that occur when processing this file, so the output can be
2571 unlinked if need be. */
2575 printf (_("Processing %s\n"), classname);
2577 jcf_dependency_reset ();
2578 classfile_name = find_class (classname, strlen (classname), &jcf, 0);
2579 if (classfile_name == NULL)
2581 error ("%s: no such class", classname);
2585 printf (_("Found in %s\n"), classfile_name);
2588 if (strcmp (output_file, "-") == 0)
2590 else if (out == NULL)
2592 out = fopen (output_file, "w");
2596 perror (output_file);
2599 current_output_file = output_file;
2603 int dir_len = strlen (output_directory);
2604 int i, classname_length = strlen (classname);
2605 current_output_file = ALLOC (dir_len + classname_length + 5);
2606 strcpy (current_output_file, output_directory);
2607 if (dir_len > 0 && output_directory[dir_len-1] != '/')
2608 current_output_file[dir_len++] = '/';
2609 for (i = 0; classname[i] != '\0'; i++)
2611 char ch = classname[i];
2614 if (flag_jni && ch == '/')
2616 current_output_file[dir_len++] = ch;
2618 if (emit_dependencies)
2620 if (suppress_output)
2622 jcf_dependency_set_dep_file ("-");
2627 /* We use `.hd' and not `.d' to avoid clashes with
2628 dependency tracking from straight compilation. */
2629 strcpy (current_output_file + dir_len, ".hd");
2630 jcf_dependency_set_dep_file (current_output_file);
2633 strcpy (current_output_file + dir_len,
2634 stubs ? (flag_jni ? ".c" : ".cc") : ".h");
2635 jcf_dependency_set_target (current_output_file);
2636 if (! suppress_output)
2638 out = fopen (current_output_file, "w");
2641 perror (current_output_file);
2646 free_method_name_list ();
2647 process_file (&jcf, out);
2650 /* If we found an error and we're writing to a real file,
2652 if (found_error && ! suppress_output && current_output_file != NULL
2653 && strcmp (current_output_file, "-"))
2654 unlink (current_output_file);
2656 if (current_output_file != output_file)
2657 free (current_output_file);
2658 jcf_dependency_write ();
2660 local_found_error |= found_error;
2663 if (out != NULL && out != stdout)
2666 return local_found_error;