Remove spurious warnings of the like '__objc_class_ref_NSObject defined but
[official-gcc.git] / gcc / java / gjavah.c
blobdb3e16a9e346f9f90c934d91089cca19a2b0923f
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 Free Software Foundation, Inc.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
21 Java and all Java-based marks are trademarks or registered trademarks
22 of Sun Microsystems, Inc. in the United States and other countries.
23 The Free Software Foundation is independent of Sun Microsystems, Inc. */
25 /* Written by Per Bothner <bothner@cygnus.com>, February 1996. */
27 #include "config.h"
28 #include "system.h"
29 #include <math.h>
31 #include "jcf.h"
32 #include "tree.h"
33 #include "javaop.h"
34 #include "java-tree.h"
35 #include "java-opcodes.h"
37 #include <getopt.h>
41 /* The output file. */
42 FILE *out = NULL;
44 /* Nonzero on failure. */
45 static int found_error = 0;
47 /* Nonzero if we're generating JNI output. */
48 static int flag_jni = 0;
50 /* When non zero, warn when source file is newer than matching class
51 file. */
52 int flag_newer = 1;
54 /* Directory to place resulting files in. Set by -d option. */
55 const char *output_directory = "";
57 /* Directory to place temporary file. Set by -td option. Currently unused. */
58 const char *temp_directory = "/tmp";
60 /* Number of friend functions we have to declare. */
61 static int friend_count;
63 /* A class can optionally have a `friend' function declared. If
64 non-NULL, this is that function. */
65 static char **friend_specs = NULL;
67 /* Number of lines we are prepending before the class. */
68 static int prepend_count;
70 /* We can prepend extra lines before the class's start. */
71 static char **prepend_specs = NULL;
73 /* Number of lines we are appending at the end of the class. */
74 static int add_count;
76 /* We can append extra lines just before the class's end. */
77 static char **add_specs = NULL;
79 /* Number of lines we are appending after the class. */
80 static int append_count;
82 /* We can append extra lines after the class's end. */
83 static char **append_specs = NULL;
85 int verbose = 0;
87 int stubs = 0;
89 struct JCF *current_jcf;
91 /* This holds access information for the last field we examined. They
92 let us generate "private:", "public:", and "protected:" properly.
93 If 0 then we haven't previously examined any field. */
94 static JCF_u2 last_access;
96 /* Pass this macro the flags for a class and for a method. It will
97 return true if the method should be considered `final'. */
98 #define METHOD_IS_FINAL(Class, Method) \
99 (((Class) & ACC_FINAL) || ((Method) & (ACC_FINAL | ACC_PRIVATE)))
101 /* Pass this macro the flags for a method. It will return true if the
102 method is native. */
103 #define METHOD_IS_NATIVE(Method) \
104 ((Method) & ACC_NATIVE)
106 /* We keep a linked list of all method names we have seen. This lets
107 us determine if a method name and a field name are in conflict. */
108 struct method_name
110 unsigned char *name;
111 int length;
112 unsigned char *signature;
113 int sig_length;
114 struct method_name *next;
117 /* List of method names we've seen. */
118 static struct method_name *method_name_list;
120 static void print_field_info PARAMS ((FILE*, JCF*, int, int, JCF_u2));
121 static void print_mangled_classname PARAMS ((FILE*, JCF*, const char*, int));
122 static int print_cxx_classname PARAMS ((FILE*, const char*, JCF*, int));
123 static void print_method_info PARAMS ((FILE*, JCF*, int, int, JCF_u2));
124 static void print_c_decl PARAMS ((FILE*, JCF*, int, int, int, const char *,
125 int));
126 static void print_stub_or_jni PARAMS ((FILE*, JCF*, int, int, int,
127 const char *, int));
128 static void print_full_cxx_name PARAMS ((FILE*, JCF*, int, int, int,
129 const char *, int));
130 static void decompile_method PARAMS ((FILE*, JCF*, int));
131 static void add_class_decl PARAMS ((FILE*, JCF*, JCF_u2));
133 static int java_float_finite PARAMS ((jfloat));
134 static int java_double_finite PARAMS ((jdouble));
135 static void print_name PARAMS ((FILE *, JCF *, int));
136 static void print_base_classname PARAMS ((FILE *, JCF *, int));
137 static int utf8_cmp PARAMS ((const unsigned char *, int, const char *));
138 static char *cxx_keyword_subst PARAMS ((const unsigned char *, int));
139 static void generate_access PARAMS ((FILE *, JCF_u2));
140 static int name_is_method_p PARAMS ((const unsigned char *, int));
141 static char *get_field_name PARAMS ((JCF *, int, JCF_u2));
142 static void print_field_name PARAMS ((FILE *, JCF *, int, JCF_u2));
143 static const unsigned char *super_class_name PARAMS ((JCF *, int *));
144 static void print_include PARAMS ((FILE *, const unsigned char *, int));
145 static const unsigned char *decode_signature_piece
146 PARAMS ((FILE *, const unsigned char *, const unsigned char *, int *));
147 static void print_class_decls PARAMS ((FILE *, JCF *, int));
148 static void usage PARAMS ((void)) ATTRIBUTE_NORETURN;
149 static void help PARAMS ((void)) ATTRIBUTE_NORETURN;
150 static void version PARAMS ((void)) ATTRIBUTE_NORETURN;
151 static int overloaded_jni_method_exists_p PARAMS ((const unsigned char *, int,
152 const char *, int));
153 static void jni_print_char PARAMS ((FILE *, int));
154 static void decompile_return_statement PARAMS ((FILE *, JCF *, int, int, int));
156 JCF_u2 current_field_name;
157 JCF_u2 current_field_value;
158 JCF_u2 current_field_signature;
159 JCF_u2 current_field_flags;
161 #define HANDLE_START_FIELD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
162 ( current_field_name = (NAME), current_field_signature = (SIGNATURE), \
163 current_field_flags = (ACCESS_FLAGS), current_field_value = 0)
165 /* We pass over fields twice. The first time we just note the types
166 of the fields and then the start of the methods. Then we go back
167 and parse the fields for real. This is ugly. */
168 static int field_pass;
169 /* Likewise we pass over methods twice. The first time we generate
170 class decl information; the second time we generate actual method
171 decls. */
172 static int method_pass;
174 #define HANDLE_END_FIELD() \
175 if (field_pass) \
177 if (out && ! stubs && ! flag_jni) \
178 print_field_info (out, jcf, current_field_name, \
179 current_field_signature, \
180 current_field_flags); \
182 else if (! stubs && ! flag_jni) \
183 add_class_decl (out, jcf, current_field_signature);
185 #define HANDLE_CONSTANTVALUE(VALUEINDEX) current_field_value = (VALUEINDEX)
187 static int method_declared = 0;
188 static int method_access = 0;
189 static int method_printed = 0;
190 static int method_synthetic = 0;
191 static int method_signature = 0;
193 #define HANDLE_METHOD(ACCESS_FLAGS, NAME, SIGNATURE, ATTRIBUTE_COUNT) \
195 method_synthetic = 0; \
196 method_printed = 0; \
197 decompiled = 0; \
198 method_signature = SIGNATURE; \
199 if (ATTRIBUTE_COUNT) \
200 method_synthetic = peek_attribute (jcf, ATTRIBUTE_COUNT, \
201 (const char *)"Synthetic", 9); \
202 /* If a synthetic methods have been declared, its attribute aren't \
203 worth reading (and triggering side-effects). We skip them an \
204 set ATTRIBUTE_COUNT to zero so that they'll be skipped in \
205 jcf_parse_one_method. */ \
206 if (method_synthetic) \
208 skip_attribute (jcf, ATTRIBUTE_COUNT); \
209 ATTRIBUTE_COUNT = 0; \
211 if (method_pass && !method_synthetic) \
213 if (out) \
214 print_method_info (out, jcf, NAME, SIGNATURE, \
215 ACCESS_FLAGS); \
217 else if (!method_synthetic) \
219 print_method_info (NULL, jcf, NAME, SIGNATURE, \
220 ACCESS_FLAGS); \
221 if (! stubs && ! flag_jni) \
222 add_class_decl (out, jcf, SIGNATURE); \
226 #define HANDLE_CODE_ATTRIBUTE(MAX_STACK, MAX_LOCALS, CODE_LENGTH) \
227 if (out && method_declared) decompile_method (out, jcf, CODE_LENGTH);
229 static int decompiled = 0;
230 #define HANDLE_END_METHOD() \
231 if (out && method_printed && !method_synthetic) \
232 fputs (decompiled || stubs ? "\n" : ";\n", out);
234 /* We're going to need {peek,skip}_attribute, enable their definition. */
235 #define NEED_PEEK_ATTRIBUTE
236 #define NEED_SKIP_ATTRIBUTE
238 #include "jcf-reader.c"
240 /* Some useful constants. */
241 #define F_NAN_MASK 0x7f800000
242 #if (1 == HOST_FLOAT_WORDS_BIG_ENDIAN) && ! defined (HOST_WORDS_BIG_ENDIAN)
243 #define D_NAN_MASK 0x000000007ff00000LL
244 #else
245 #define D_NAN_MASK 0x7ff0000000000000LL
246 #endif
248 /* Return 1 if F is not Inf or NaN. */
249 static int
250 java_float_finite (f)
251 jfloat f;
253 union Word u;
254 u.f = f;
256 /* We happen to know that F_NAN_MASK will match all NaN values, and
257 also positive and negative infinity. That's why we only need one
258 test here. See The Java Language Specification, section 20.9. */
259 return (u.i & F_NAN_MASK) != F_NAN_MASK;
262 /* Return 1 if D is not Inf or NaN. */
263 static int
264 java_double_finite (d)
265 jdouble d;
267 union DWord u;
268 u.d = d;
270 /* Now check for all NaNs. */
271 return (u.l & D_NAN_MASK) != D_NAN_MASK;
274 /* Print a character, appropriately mangled for JNI. */
276 static void
277 jni_print_char (stream, ch)
278 FILE *stream;
279 int ch;
281 if (! flag_jni)
282 jcf_print_char (stream, ch);
283 else if (ch == '(' || ch == ')')
285 /* Ignore. */
287 else if (ch == '_')
288 fputs ("_1", stream);
289 else if (ch == ';')
290 fputs ("_2", stream);
291 else if (ch == '[')
292 fputs ("_3", stream);
293 else if (ch == '/')
294 fputs ("_", stream);
295 else if (ISALNUM (ch))
296 fputc (ch, stream);
297 else
299 /* "Unicode" character. */
300 fprintf (stream, "_0%04x", ch);
304 /* Print a name from the class data. If the index does not point to a
305 string, an error results. */
307 static void
308 DEFUN(print_name, (stream, jcf, name_index),
309 FILE* stream AND JCF* jcf AND int name_index)
311 if (JPOOL_TAG (jcf, name_index) != CONSTANT_Utf8)
313 fprintf (stream, "<not a UTF8 constant>");
314 found_error = 1;
316 else if (! flag_jni)
317 jcf_print_utf8 (stream, JPOOL_UTF_DATA (jcf, name_index),
318 JPOOL_UTF_LENGTH (jcf, name_index));
319 else
321 /* For JNI we must correctly quote each character. */
322 const unsigned char *str = JPOOL_UTF_DATA (jcf, name_index);
323 int length = JPOOL_UTF_LENGTH (jcf, name_index);
324 const unsigned char *limit = str + length;
325 while (str < limit)
327 int ch = UTF8_GET (str, limit);
328 if (ch < 0)
330 fprintf (stream, "\\<invalid>");
331 return;
333 jni_print_char (stream, ch);
338 /* Print base name of class. The base name is everything after the
339 final separator. */
341 static void
342 print_base_classname (stream, jcf, index)
343 FILE *stream;
344 JCF *jcf;
345 int index;
347 int name_index = JPOOL_USHORT1 (jcf, index);
348 int len;
349 const unsigned char *s, *p, *limit;
351 s = JPOOL_UTF_DATA (jcf, name_index);
352 len = JPOOL_UTF_LENGTH (jcf, name_index);
353 limit = s + len;
354 p = s;
355 while (s < limit)
357 int c = UTF8_GET (s, limit);
358 if (c == '/')
359 p = s;
362 while (p < limit)
364 int ch = UTF8_GET (p, limit);
365 if (ch == '/')
366 fputs ("::", stream);
367 else
368 jcf_print_char (stream, ch);
372 /* Return 0 if NAME is equal to STR, -1 if STR is "less" than NAME,
373 and 1 if STR is "greater" than NAME. */
375 static int
376 utf8_cmp (str, length, name)
377 const unsigned char *str;
378 int length;
379 const char *name;
381 const unsigned char *limit = str + length;
382 int i;
384 for (i = 0; name[i]; ++i)
386 int ch = UTF8_GET (str, limit);
387 if (ch != name[i])
388 return ch - name[i];
391 return str == limit ? 0 : 1;
394 /* This is a sorted list of all C++ keywords. */
396 static const char *const cxx_keywords[] =
398 "_Complex",
399 "__alignof",
400 "__alignof__",
401 "__asm",
402 "__asm__",
403 "__attribute",
404 "__attribute__",
405 "__builtin_va_arg",
406 "__complex",
407 "__complex__",
408 "__const",
409 "__const__",
410 "__extension__",
411 "__imag",
412 "__imag__",
413 "__inline",
414 "__inline__",
415 "__label__",
416 "__null",
417 "__real",
418 "__real__",
419 "__restrict",
420 "__restrict__",
421 "__signed",
422 "__signed__",
423 "__typeof",
424 "__typeof__",
425 "__volatile",
426 "__volatile__",
427 "and",
428 "and_eq",
429 "asm",
430 "auto",
431 "bitand",
432 "bitor",
433 "bool",
434 "break",
435 "case",
436 "catch",
437 "char",
438 "class",
439 "compl",
440 "const",
441 "const_cast",
442 "continue",
443 "default",
444 "delete",
445 "do",
446 "double",
447 "dynamic_cast",
448 "else",
449 "enum",
450 "explicit",
451 "export",
452 "extern",
453 "false",
454 "float",
455 "for",
456 "friend",
457 "goto",
458 "if",
459 "inline",
460 "int",
461 "long",
462 "mutable",
463 "namespace",
464 "new",
465 "not",
466 "not_eq",
467 "operator",
468 "or",
469 "or_eq",
470 "private",
471 "protected",
472 "public",
473 "register",
474 "reinterpret_cast",
475 "return",
476 "short",
477 "signed",
478 "sizeof",
479 "static",
480 "static_cast",
481 "struct",
482 "switch",
483 "template",
484 "this",
485 "throw",
486 "true",
487 "try",
488 "typedef",
489 "typeid",
490 "typename",
491 "typeof",
492 "union",
493 "unsigned",
494 "using",
495 "virtual",
496 "void",
497 "volatile",
498 "wchar_t",
499 "while",
500 "xor",
501 "xor_eq"
505 /* If NAME is the name of a C++ keyword, then return an override name.
506 This is a name that can be used in place of the keyword.
507 Otherwise, return NULL. The return value is malloc()d. */
509 static char *
510 cxx_keyword_subst (str, length)
511 const unsigned char *str;
512 int length;
514 int last = ARRAY_SIZE (cxx_keywords);
515 int first = 0;
516 int mid = (last + first) / 2;
517 int old = -1;
519 for (mid = (last + first) / 2;
520 mid != old;
521 old = mid, mid = (last + first) / 2)
523 int kwl = strlen (cxx_keywords[mid]);
524 int min_length = kwl > length ? length : kwl;
525 int r = utf8_cmp (str, min_length, cxx_keywords[mid]);
527 if (r == 0)
529 int i;
531 /* Skip all trailing `$'. */
532 for (i = min_length; i < length && str[i] == '$'; ++i)
534 /* We've only found a match if all the remaining characters
535 are `$'. */
536 if (i == length)
538 char *dup = xmalloc (2 + length - min_length + kwl);
539 strcpy (dup, cxx_keywords[mid]);
540 for (i = kwl; i < length + 1; ++i)
541 dup[i] = '$';
542 dup[i] = '\0';
543 return dup;
545 r = 1;
548 if (r < 0)
549 last = mid;
550 else
551 first = mid;
553 return NULL;
556 /* Generate an access control keyword based on FLAGS. */
558 static void
559 generate_access (stream, flags)
560 FILE *stream;
561 JCF_u2 flags;
563 if ((flags & ACC_VISIBILITY) == last_access)
564 return;
565 last_access = (flags & ACC_VISIBILITY);
567 switch (last_access)
569 case 0:
570 fputs ("public: // actually package-private\n", stream);
571 break;
572 case ACC_PUBLIC:
573 fputs ("public:\n", stream);
574 break;
575 case ACC_PRIVATE:
576 fputs ("private:\n", stream);
577 break;
578 case ACC_PROTECTED:
579 fputs ("public: // actually protected\n", stream);
580 break;
581 default:
582 found_error = 1;
583 fprintf (stream, "#error unrecognized visibility %d\n",
584 (flags & ACC_VISIBILITY));
585 break;
589 /* See if NAME is already the name of a method. */
590 static int
591 name_is_method_p (name, length)
592 const unsigned char *name;
593 int length;
595 struct method_name *p;
597 for (p = method_name_list; p != NULL; p = p->next)
599 if (p->length == length && ! memcmp (p->name, name, length))
600 return 1;
602 return 0;
605 /* If there is already a method named NAME, whose signature is not
606 SIGNATURE, then return true. Otherwise return false. */
607 static int
608 overloaded_jni_method_exists_p (name, length, signature, sig_length)
609 const unsigned char *name;
610 int length;
611 const char *signature;
612 int sig_length;
614 struct method_name *p;
616 for (p = method_name_list; p != NULL; p = p->next)
618 if (p->length == length
619 && ! memcmp (p->name, name, length)
620 && (p->sig_length != sig_length
621 || memcmp (p->signature, signature, sig_length)))
622 return 1;
624 return 0;
627 /* Get name of a field. This handles renamings due to C++ clash. */
628 static char *
629 get_field_name (jcf, name_index, flags)
630 JCF *jcf;
631 int name_index;
632 JCF_u2 flags;
634 unsigned char *name = JPOOL_UTF_DATA (jcf, name_index);
635 int length = JPOOL_UTF_LENGTH (jcf, name_index);
636 char *override;
638 if (name_is_method_p (name, length))
640 /* This field name matches a method. So override the name with
641 a dummy name. This is yucky, but it isn't clear what else to
642 do. FIXME: if the field is static, then we'll be in real
643 trouble. */
644 if ((flags & ACC_STATIC))
646 fprintf (stderr, "static field has same name as method\n");
647 found_error = 1;
648 return NULL;
651 override = xmalloc (length + 3);
652 memcpy (override, name, length);
653 strcpy (override + length, "__");
655 else
656 override = cxx_keyword_subst (name, length);
658 return override;
661 /* Print a field name. Convenience function for use with
662 get_field_name. */
663 static void
664 print_field_name (stream, jcf, name_index, flags)
665 FILE *stream;
666 JCF *jcf;
667 int name_index;
668 JCF_u2 flags;
670 char *override = get_field_name (jcf, name_index, flags);
672 if (override)
674 fputs (override, stream);
675 free (override);
677 else
678 jcf_print_utf8 (stream, JPOOL_UTF_DATA (jcf, name_index),
679 JPOOL_UTF_LENGTH (jcf, name_index));
682 static void
683 DEFUN(print_field_info, (stream, jcf, name_index, sig_index, flags),
684 FILE *stream AND JCF* jcf
685 AND int name_index AND int sig_index AND JCF_u2 flags)
687 char *override = NULL;
689 generate_access (stream, flags);
690 if (JPOOL_TAG (jcf, name_index) != CONSTANT_Utf8)
692 fprintf (stream, "<not a UTF8 constant>");
693 found_error = 1;
694 return;
697 fputs (" ", out);
698 if ((flags & ACC_STATIC))
699 fputs ("static ", out);
701 if ((flags & ACC_FINAL))
703 if (current_field_value > 0)
705 char buffer[25];
706 int done = 1;
708 switch (JPOOL_TAG (jcf, current_field_value))
710 case CONSTANT_Integer:
712 jint num;
713 int most_negative = 0;
714 fputs ("const jint ", out);
715 print_field_name (out, jcf, name_index, 0);
716 fputs (" = ", out);
717 num = JPOOL_INT (jcf, current_field_value);
718 /* We single out the most negative number to print
719 specially. This avoids later warnings from g++. */
720 if (num == (jint) 0x80000000)
722 most_negative = 1;
723 ++num;
725 format_int (buffer, (jlong) num, 10);
726 fprintf (out, "%sL%s;\n", buffer, most_negative ? " - 1" : "");
728 break;
729 case CONSTANT_Long:
731 jlong num;
732 int most_negative = 0;
733 fputs ("const jlong ", out);
734 print_field_name (out, jcf, name_index, 0);
735 fputs (" = ", out);
736 num = JPOOL_LONG (jcf, current_field_value);
737 /* We single out the most negative number to print
738 specially.. This avoids later warnings from g++. */
739 if (num == (jlong) 0x8000000000000000LL)
741 most_negative = 1;
742 ++num;
744 format_int (buffer, num, 10);
745 fprintf (out, "%sLL%s;\n", buffer, most_negative ? " - 1" :"");
747 break;
748 case CONSTANT_Float:
750 jfloat fnum = JPOOL_FLOAT (jcf, current_field_value);
751 fputs ("const jfloat ", out);
752 print_field_name (out, jcf, name_index, 0);
753 if (! java_float_finite (fnum))
754 fputs (";\n", out);
755 else
756 fprintf (out, " = %.10g;\n", fnum);
758 break;
759 case CONSTANT_Double:
761 jdouble dnum = JPOOL_DOUBLE (jcf, current_field_value);
762 fputs ("const jdouble ", out);
763 print_field_name (out, jcf, name_index, 0);
764 if (! java_double_finite (dnum))
765 fputs (";\n", out);
766 else
767 fprintf (out, " = %.17g;\n", dnum);
769 break;
770 default:
771 /* We can't print this as a constant, but we can still
772 print something sensible. */
773 done = 0;
774 break;
777 if (done)
778 return;
782 override = get_field_name (jcf, name_index, flags);
783 print_c_decl (out, jcf, name_index, sig_index, 0, override, flags);
784 fputs (";\n", out);
786 if (override)
787 free (override);
791 static void
792 DEFUN(print_method_info, (stream, jcf, name_index, sig_index, flags),
793 FILE *stream AND JCF* jcf
794 AND int name_index AND int sig_index AND JCF_u2 flags)
796 const unsigned char *str;
797 int length, is_init = 0;
798 char *override = NULL;
800 method_declared = 0;
801 method_access = flags;
802 if (stream && JPOOL_TAG (jcf, name_index) != CONSTANT_Utf8)
803 fprintf (stream, "<not a UTF8 constant>");
804 str = JPOOL_UTF_DATA (jcf, name_index);
805 length = JPOOL_UTF_LENGTH (jcf, name_index);
807 if (str[0] == '<')
809 /* Ignore the internally generated method <clinit>. However,
810 treat <init> as a constructor. */
811 if (! utf8_cmp (str, length, "<init>"))
812 is_init = 1;
813 else if (! METHOD_IS_FINAL (jcf->access_flags, flags)
814 && ! (flags & ACC_STATIC))
816 /* FIXME: i18n bug here. Order of prints should not be
817 fixed. */
818 fprintf (stderr, "ignored method `");
819 jcf_print_utf8 (stderr, str, length);
820 fprintf (stderr, "' marked virtual\n");
821 found_error = 1;
822 return;
824 else
825 return;
828 /* During the first method pass, build a list of method names. This will
829 be used to determine if field names conflict with method names. */
830 if (! stream)
832 struct method_name *nn;
834 nn = (struct method_name *) xmalloc (sizeof (struct method_name));
835 nn->name = (char *) xmalloc (length);
836 memcpy (nn->name, str, length);
837 nn->length = length;
838 nn->next = method_name_list;
839 nn->sig_length = JPOOL_UTF_LENGTH (jcf, sig_index);
840 nn->signature = (char *) xmalloc (nn->sig_length);
841 memcpy (nn->signature, JPOOL_UTF_DATA (jcf, sig_index),
842 nn->sig_length);
843 method_name_list = nn;
845 /* The rest of this function doesn't matter. */
846 return;
849 /* We don't worry about overrides in JNI mode. */
850 if (! flag_jni)
852 /* We can't generate a method whose name is a C++ reserved word.
853 We can't just ignore the function, because that will cause
854 incorrect code to be generated if the function is virtual
855 (not only for calls to this function for for other functions
856 after it in the vtbl). So we give it a dummy name instead. */
857 override = cxx_keyword_subst (str, length);
860 if (! stubs && ! flag_jni)
862 method_printed = 1;
864 generate_access (stream, flags);
866 fputs (" ", out);
867 if ((flags & ACC_STATIC))
868 fputs ("static ", out);
869 else if (! METHOD_IS_FINAL (jcf->access_flags, flags))
871 /* Don't print `virtual' if we have a constructor. */
872 if (! is_init)
873 fputs ("virtual ", out);
875 print_c_decl (out, jcf, name_index, sig_index, is_init, override, flags);
877 if ((flags & ACC_ABSTRACT))
878 fputs (" = 0", out);
879 else
880 method_declared = 1;
882 else
884 if (METHOD_IS_NATIVE (flags))
886 method_printed = 1;
887 print_stub_or_jni (out, jcf, name_index, sig_index,
888 is_init, override, flags);
892 if (override)
893 free (override);
896 /* A helper for the decompiler which prints a `return' statement where
897 the type is a reference type. If METHODTYPE and OBJECTTYPE are not
898 identical, we emit a cast. We do this because the C++ compiler
899 doesn't know that a reference can be cast to the type of an
900 interface it implements. METHODTYPE is the index of the method's
901 signature. NAMEINDEX is the index of the field name; -1 for
902 `this'. OBJECTTYPE is the index of the object's type. */
903 static void
904 decompile_return_statement (out, jcf, methodtype, nameindex, objecttype)
905 FILE *out;
906 JCF *jcf;
907 int methodtype, nameindex, objecttype;
909 int cast = 0;
910 int obj_name_len, method_name_len;
911 const unsigned char *obj_data, *method_data;
913 obj_name_len = JPOOL_UTF_LENGTH (jcf, objecttype);
914 obj_data = JPOOL_UTF_DATA (jcf, objecttype);
916 method_name_len = JPOOL_UTF_LENGTH (jcf, methodtype);
917 method_data = JPOOL_UTF_DATA (jcf, methodtype);
919 /* Skip forward to return type part of method. */
920 while (*method_data != ')')
922 ++method_data;
923 --method_name_len;
925 /* Skip past `)'. */
926 ++method_data;
927 --method_name_len;
929 /* If we see an `L', skip it and the trailing `;'. */
930 if (method_data[0] == 'L' && method_data[method_name_len - 1] == ';')
932 ++method_data;
933 method_name_len -= 2;
935 if (obj_data[0] == 'L' && obj_data[obj_name_len - 1] == ';')
937 ++obj_data;
938 obj_name_len -= 2;
941 /* FIXME: if METHODTYPE is a superclass of OBJECTTYPE then we don't
942 need a cast. Right now there is no way to determine if this is
943 the case. */
944 if (method_name_len != obj_name_len)
945 cast = 1;
946 else
948 int i;
949 for (i = 0; i < method_name_len; ++i)
951 if (method_data[i] != obj_data[i])
953 cast = 1;
954 break;
959 fputs (" { return ", out);
961 if (cast)
963 int array_depth = 0;
964 const unsigned char *limit;
966 fputs ("reinterpret_cast<", out);
968 while (*method_data == '[')
970 ++method_data;
971 ++array_depth;
972 --method_name_len;
973 fputs ("JArray<", out);
976 /* Leading space to avoid C++ digraphs. */
977 fputs (" ::", out);
979 /* If we see an `L', skip it and the trailing `;'. Only do this
980 if we've seen an array specification. If we don't have an
981 array then the `L' was stripped earlier. */
982 if (array_depth && method_data[0] == 'L'
983 && method_data[method_name_len - 1] == ';')
985 ++method_data;
986 method_name_len -= 2;
989 limit = method_data + method_name_len;
990 while (method_data < limit)
992 int ch = UTF8_GET (method_data, limit);
993 if (ch == '/')
994 fputs ("::", out);
995 else
996 jcf_print_char (out, ch);
998 fputs (" *", out);
1000 /* Close each array. */
1001 while (array_depth > 0)
1003 fputs ("> *", out);
1004 --array_depth;
1007 /* Close the cast. */
1008 fputs ("> (", out);
1011 if (nameindex == -1)
1012 fputs ("this", out);
1013 else
1014 print_field_name (out, jcf, nameindex, 0);
1016 if (cast)
1017 fputs (")", out);
1019 fputs ("; }", out);
1023 /* Try to decompile a method body. Right now we just try to handle a
1024 simple case that we can do. Expand as desired. */
1025 static void
1026 decompile_method (out, jcf, code_len)
1027 FILE *out;
1028 JCF *jcf;
1029 int code_len;
1031 const unsigned char *codes = jcf->read_ptr;
1032 int index;
1033 uint16 name_and_type, name;
1035 /* If the method is synchronized, don't touch it. */
1036 if ((method_access & ACC_SYNCHRONIZED))
1037 return;
1039 if (code_len == 5
1040 && codes[0] == OPCODE_aload_0
1041 && codes[1] == OPCODE_getfield
1042 && (codes[4] == OPCODE_areturn
1043 || codes[4] == OPCODE_dreturn
1044 || codes[4] == OPCODE_freturn
1045 || codes[4] == OPCODE_ireturn
1046 || codes[4] == OPCODE_lreturn))
1048 /* Found code like `return FIELD'. */
1049 index = (codes[2] << 8) | codes[3];
1050 /* FIXME: ensure that tag is CONSTANT_Fieldref. */
1051 name_and_type = JPOOL_USHORT2 (jcf, index);
1052 /* FIXME: ensure that tag is CONSTANT_NameAndType. */
1053 name = JPOOL_USHORT1 (jcf, name_and_type);
1054 if (codes[4] == OPCODE_areturn)
1055 decompile_return_statement (out, jcf, method_signature,
1056 name, JPOOL_USHORT2 (jcf, name_and_type));
1057 else
1059 fputs (" { return ", out);
1060 /* FIXME: flags. */
1061 print_field_name (out, jcf, name, 0);
1062 fputs ("; }", out);
1064 decompiled = 1;
1066 else if (code_len == 2
1067 && codes[0] == OPCODE_aload_0
1068 && codes[1] == OPCODE_areturn
1069 /* We're going to generate `return this'. This only makes
1070 sense for non-static methods. */
1071 && ! (method_access & ACC_STATIC))
1073 decompile_return_statement (out, jcf, method_signature, -1,
1074 JPOOL_USHORT1 (jcf, jcf->this_class));
1075 decompiled = 1;
1077 else if (code_len == 1 && codes[0] == OPCODE_return)
1079 /* Found plain `return'. */
1080 fputs (" { }", out);
1081 decompiled = 1;
1083 else if (code_len == 2
1084 && codes[0] == OPCODE_aconst_null
1085 && codes[1] == OPCODE_areturn)
1087 /* Found `return null'. We don't want to depend on NULL being
1088 defined. */
1089 fputs (" { return 0; }", out);
1090 decompiled = 1;
1094 /* Print one piece of a signature. Returns pointer to next parseable
1095 character on success, NULL on error. */
1096 static const unsigned char *
1097 decode_signature_piece (stream, signature, limit, need_space)
1098 FILE *stream;
1099 const unsigned char *signature, *limit;
1100 int *need_space;
1102 const char *ctype;
1103 int array_depth = 0;
1105 switch (signature[0])
1107 case '[':
1108 /* More spaghetti. */
1110 array_loop:
1111 for (signature++; (signature < limit
1112 && ISDIGIT (*signature)); signature++)
1114 switch (*signature)
1116 case 'B':
1117 ctype = "jbyteArray";
1118 break;
1119 case 'C':
1120 ctype = "jcharArray";
1121 break;
1122 case 'D':
1123 ctype = "jdoubleArray";
1124 break;
1125 case 'F':
1126 ctype = "jfloatArray";
1127 break;
1128 case 'I':
1129 ctype = "jintArray";
1130 break;
1131 case 'S':
1132 ctype = "jshortArray";
1133 break;
1134 case 'J':
1135 ctype = "jlongArray";
1136 break;
1137 case 'Z':
1138 ctype = "jbooleanArray";
1139 break;
1140 case '[':
1141 /* We have a nested array. */
1142 ++array_depth;
1143 if (! flag_jni)
1144 fputs ("JArray<", stream);
1145 goto array_loop;
1147 case 'L':
1148 /* We have to generate a reference to JArray here, so that
1149 our output matches what the compiler does. */
1150 ++signature;
1151 /* Space between `<' and `:' to avoid C++ digraphs. */
1152 if (! flag_jni)
1153 fputs ("JArray< ::", stream);
1154 while (signature < limit && *signature != ';')
1156 int ch = UTF8_GET (signature, limit);
1157 if (! flag_jni)
1159 if (ch == '/')
1160 fputs ("::", stream);
1161 else
1162 jcf_print_char (stream, ch);
1165 if (! flag_jni)
1166 fputs (" *> *", stream);
1167 *need_space = 0;
1168 ctype = NULL;
1169 break;
1170 default:
1171 /* Unparseable signature. */
1172 return NULL;
1175 /* If the previous iterations left us with something to print,
1176 print it. For JNI, we always print `jobjectArray' in the
1177 nested cases. */
1178 if (flag_jni && ctype == NULL)
1180 ctype = "jobjectArray";
1181 *need_space = 1;
1183 /* The `printit' case will advance SIGNATURE for us. If we
1184 don't go there, we must advance past the `;' ourselves. */
1185 if (ctype != NULL)
1186 goto printit;
1187 ++signature;
1188 break;
1190 case '(':
1191 case ')':
1192 /* This shouldn't happen. */
1193 return NULL;
1195 case 'B': ctype = "jbyte"; goto printit;
1196 case 'C': ctype = "jchar"; goto printit;
1197 case 'D': ctype = "jdouble"; goto printit;
1198 case 'F': ctype = "jfloat"; goto printit;
1199 case 'I': ctype = "jint"; goto printit;
1200 case 'J': ctype = "jlong"; goto printit;
1201 case 'S': ctype = "jshort"; goto printit;
1202 case 'Z': ctype = "jboolean"; goto printit;
1203 case 'V': ctype = "void"; goto printit;
1204 case 'L':
1205 if (flag_jni)
1207 /* We know about certain types and special-case their
1208 names.
1209 FIXME: something like java.lang.Exception should be
1210 printed as `jthrowable', because it is a subclass. This
1211 means that gcjh must read the entire hierarchy and
1212 comprehend it. */
1213 if (! strncmp (signature, "Ljava/lang/String;",
1214 sizeof ("Ljava/lang/String;") -1))
1215 ctype = "jstring";
1216 else if (! strncmp (signature, "Ljava/lang/Class;",
1217 sizeof ("Ljava/lang/Class;") - 1))
1218 ctype = "jclass";
1219 else if (! strncmp (signature, "Ljava/lang/Throwable;",
1220 sizeof ("Ljava/lang/Throwable;") - 1))
1221 ctype = "jthrowable";
1222 else if (! strncmp (signature, "Ljava/lang/ref/WeakReference;",
1223 sizeof ("Ljava/lang/ref/WeakReference;") - 1))
1224 ctype = "jweak";
1225 else
1226 ctype = "jobject";
1228 while (*signature && *signature != ';')
1229 ++signature;
1231 goto printit;
1233 /* Print a leading "::" so we look in the right namespace. */
1234 fputs ("::", stream);
1235 ++signature;
1236 while (*signature && *signature != ';')
1238 int ch = UTF8_GET (signature, limit);
1239 if (ch == '/')
1240 fputs ("::", stream);
1241 else
1242 jcf_print_char (stream, ch);
1244 fputs (" *", stream);
1245 if (*signature == ';')
1246 signature++;
1247 *need_space = 0;
1248 break;
1249 default:
1250 *need_space = 1;
1251 jni_print_char (stream, *signature++);
1252 break;
1253 printit:
1254 signature++;
1255 *need_space = 1;
1256 fputs (ctype, stream);
1257 break;
1260 if (! flag_jni)
1262 while (array_depth-- > 0)
1263 fputs ("> *", stream);
1266 return signature;
1269 static void
1270 DEFUN(print_c_decl, (stream, jcf, name_index, signature_index, is_init,
1271 name_override, flags),
1272 FILE* stream AND JCF* jcf
1273 AND int name_index AND int signature_index
1274 AND int is_init AND const char *name_override AND int flags)
1276 if (JPOOL_TAG (jcf, signature_index) != CONSTANT_Utf8)
1278 fprintf (stream, "<not a UTF8 constant>");
1279 found_error = 1;
1281 else
1283 int length = JPOOL_UTF_LENGTH (jcf, signature_index);
1284 const unsigned char *str0 = JPOOL_UTF_DATA (jcf, signature_index);
1285 register const unsigned char *str = str0;
1286 const unsigned char *limit = str + length;
1287 int need_space = 0;
1288 int is_method = str[0] == '(';
1289 const unsigned char *next;
1291 /* If printing a method, skip to the return signature and print
1292 that first. However, there is no return value if this is a
1293 constructor. */
1294 if (is_method && ! is_init)
1296 while (str < limit)
1298 int ch = *str++;
1299 if (ch == ')')
1300 break;
1304 /* If printing a field or an ordinary method, then print the
1305 "return value" now. */
1306 if (! is_method || ! is_init)
1308 next = decode_signature_piece (stream, str, limit, &need_space);
1309 if (! next)
1311 fprintf (stderr, "unparseable signature: `%s'\n", str0);
1312 found_error = 1;
1313 return;
1317 /* Now print the name of the thing. */
1318 if (need_space)
1319 fputs (" ", stream);
1320 print_full_cxx_name (stream, jcf, name_index,
1321 signature_index, is_init, name_override,
1322 flags);
1326 /* Print the unqualified method name followed by the signature. */
1327 static void
1328 DEFUN(print_full_cxx_name, (stream, jcf, name_index, signature_index,
1329 is_init, name_override, flags),
1330 FILE* stream AND JCF* jcf
1331 AND int name_index AND int signature_index AND int is_init
1332 AND const char *name_override AND int flags)
1334 int length = JPOOL_UTF_LENGTH (jcf, signature_index);
1335 const unsigned char *str0 = JPOOL_UTF_DATA (jcf, signature_index);
1336 register const unsigned char *str = str0;
1337 const unsigned char *limit = str + length;
1338 int need_space = 0;
1339 int is_method = str[0] == '(';
1340 const unsigned char *next;
1342 if (name_override)
1343 fputs (name_override, stream);
1344 else if (name_index)
1346 /* Declare constructors specially. */
1347 if (is_init)
1348 print_base_classname (stream, jcf, jcf->this_class);
1349 else
1350 print_name (stream, jcf, name_index);
1353 if (flag_jni)
1355 unsigned char *signature = JPOOL_UTF_DATA (jcf, signature_index);
1356 int sig_len = JPOOL_UTF_LENGTH (jcf, signature_index);
1357 if (overloaded_jni_method_exists_p (JPOOL_UTF_DATA (jcf, name_index),
1358 JPOOL_UTF_LENGTH (jcf, name_index),
1359 signature, sig_len))
1361 /* If this method is overloaded by another native method,
1362 then include the argument information in the mangled
1363 name. */
1364 unsigned char *limit = signature + sig_len;
1365 fputs ("__", stream);
1366 while (signature < limit)
1368 int ch = UTF8_GET (signature, limit);
1369 jni_print_char (stream, ch);
1370 if (ch == ')')
1372 /* Done. */
1373 break;
1379 if (is_method)
1381 /* Have a method or a constructor. Print signature pieces
1382 until done. */
1383 fputs (" (", stream);
1385 str = str0 + 1;
1387 /* In JNI mode, add extra arguments. */
1388 if (flag_jni)
1390 /* FIXME: it would be nice to know if we are printing a decl
1391 or a definition, and only print `env' for the latter. */
1392 fputs ("JNIEnv *env", stream);
1394 fputs ((flags & ACC_STATIC) ? ", jclass" : ", jobject", stream);
1396 if (*str != ')')
1397 fputs (", ", stream);
1400 while (str < limit && *str != ')')
1402 next = decode_signature_piece (stream, str, limit, &need_space);
1403 if (! next)
1405 fprintf (stderr, "unparseable signature: `%s'\n", str0);
1406 found_error = 1;
1407 return;
1410 if (next < limit && *next != ')')
1411 fputs (", ", stream);
1412 str = next;
1415 fputs (")", stream);
1419 /* This is a helper for print_stub_or_jni. */
1420 static void
1421 DEFUN (print_name_for_stub_or_jni, (stream, jcf, name_index, signature_index,
1422 is_init, name_override, flags),
1423 FILE *stream AND JCF *jcf
1424 AND int name_index AND int signature_index
1425 AND int is_init AND const char *name_override AND int flags)
1427 const char *const prefix = flag_jni ? "Java_" : "";
1428 print_cxx_classname (stream, prefix, jcf, jcf->this_class);
1429 fputs (flag_jni ? "_" : "::", stream);
1430 print_full_cxx_name (stream, jcf, name_index,
1431 signature_index, is_init, name_override,
1432 flags);
1435 static void
1436 DEFUN(print_stub_or_jni, (stream, jcf, name_index, signature_index, is_init,
1437 name_override, flags),
1438 FILE* stream AND JCF* jcf
1439 AND int name_index AND int signature_index
1440 AND int is_init AND const char *name_override AND int flags)
1442 if (JPOOL_TAG (jcf, signature_index) != CONSTANT_Utf8)
1444 fprintf (stream, "<not a UTF8 constant>");
1445 found_error = 1;
1447 else
1449 int length = JPOOL_UTF_LENGTH (jcf, signature_index);
1450 const unsigned char *str0 = JPOOL_UTF_DATA (jcf, signature_index);
1451 register const unsigned char *str = str0;
1452 const unsigned char *limit = str + length;
1453 int need_space = 0;
1454 int is_method = str[0] == '(';
1455 const unsigned char *next;
1457 /* Don't print fields in the JNI case. */
1458 if (! is_method && flag_jni)
1459 return;
1461 if (flag_jni && ! stubs)
1462 fputs ("extern ", stream);
1464 /* If printing a method, skip to the return signature and print
1465 that first. However, there is no return value if this is a
1466 constructor. */
1467 if (is_method && ! is_init)
1469 while (str < limit)
1471 int ch = *str++;
1472 if (ch == ')')
1473 break;
1477 /* If printing a field or an ordinary method, then print the
1478 "return value" now. Note that a constructor can't be native,
1479 so we don't bother checking this in the JNI case. */
1480 if (! is_method || ! is_init)
1482 next = decode_signature_piece (stream, str, limit, &need_space);
1483 if (! next)
1485 fprintf (stderr, "unparseable signature: `%s'\n", str0);
1486 found_error = 1;
1487 return;
1491 /* When printing a JNI header we need to respect the space. In
1492 other cases we're just going to insert a newline anyway. */
1493 fputs (need_space && ! stubs ? " " : "\n", stream);
1495 /* Now print the name of the thing. */
1496 print_name_for_stub_or_jni (stream, jcf, name_index,
1497 signature_index, is_init, name_override,
1498 flags);
1500 /* Print the body. */
1501 if (stubs)
1503 if (flag_jni)
1504 fputs ("\n{\n (*env)->FatalError (\"", stream);
1505 else
1506 fputs ("\n{\n JvFail (\"", stream);
1507 print_name_for_stub_or_jni (stream, jcf, name_index,
1508 signature_index, is_init,
1509 name_override,
1510 flags);
1511 fputs (" not implemented\");\n}\n\n", stream);
1516 static void
1517 DEFUN(print_mangled_classname, (stream, jcf, prefix, index),
1518 FILE *stream AND JCF *jcf AND const char *prefix AND int index)
1520 int name_index = JPOOL_USHORT1 (jcf, index);
1521 fputs (prefix, stream);
1522 jcf_print_utf8_replace (out,
1523 JPOOL_UTF_DATA (jcf, name_index),
1524 JPOOL_UTF_LENGTH (jcf, name_index),
1525 '/', '_');
1528 /* Print PREFIX, then a class name in C++ format. If the name refers
1529 to an array, ignore it and don't print PREFIX. Returns 1 if
1530 something was printed, 0 otherwise. */
1531 static int
1532 print_cxx_classname (stream, prefix, jcf, index)
1533 FILE *stream;
1534 const char *prefix;
1535 JCF *jcf;
1536 int index;
1538 int name_index = JPOOL_USHORT1 (jcf, index);
1539 int len, c;
1540 const unsigned char *s, *p, *limit;
1542 s = JPOOL_UTF_DATA (jcf, name_index);
1543 len = JPOOL_UTF_LENGTH (jcf, name_index);
1544 limit = s + len;
1546 /* Explicitly omit arrays here. */
1547 p = s;
1548 c = UTF8_GET (p, limit);
1549 if (c == '[')
1550 return 0;
1552 fputs (prefix, stream);
1554 /* Print a leading "::" so we look in the right namespace. */
1555 if (! flag_jni && ! stubs)
1556 fputs ("::", stream);
1558 while (s < limit)
1560 c = UTF8_GET (s, limit);
1561 if (c == '/')
1562 fputs (flag_jni ? "_" : "::", stream);
1563 else
1564 jni_print_char (stream, c);
1567 return 1;
1570 int written_class_count = 0;
1572 /* Return name of superclass. If LEN is not NULL, fill it with length
1573 of name. */
1574 static const unsigned char *
1575 super_class_name (derived_jcf, len)
1576 JCF *derived_jcf;
1577 int *len;
1579 int supername_index = JPOOL_USHORT1 (derived_jcf, derived_jcf->super_class);
1580 int supername_length = JPOOL_UTF_LENGTH (derived_jcf, supername_index);
1581 const unsigned char *supername =
1582 JPOOL_UTF_DATA (derived_jcf, supername_index);
1584 if (len)
1585 *len = supername_length;
1587 return supername;
1592 /* We keep track of all the `#include's we generate, so we can avoid
1593 duplicates. */
1594 struct include
1596 char *name;
1597 struct include *next;
1600 /* List of all includes. */
1601 static struct include *all_includes = NULL;
1603 /* Generate a #include. */
1604 static void
1605 print_include (out, utf8, len)
1606 FILE *out;
1607 const unsigned char *utf8;
1608 int len;
1610 struct include *incl;
1612 if (! out)
1613 return;
1615 if (len == -1)
1616 len = strlen (utf8);
1618 for (incl = all_includes; incl; incl = incl->next)
1620 /* We check the length because we might have a proper prefix. */
1621 if (len == (int) strlen (incl->name)
1622 && ! strncmp (incl->name, utf8, len))
1623 return;
1626 incl = (struct include *) xmalloc (sizeof (struct include));
1627 incl->name = xmalloc (len + 1);
1628 strncpy (incl->name, utf8, len);
1629 incl->name[len] = '\0';
1630 incl->next = all_includes;
1631 all_includes = incl;
1633 fputs ("#include <", out);
1634 jcf_print_utf8_replace (out, utf8, len,
1635 '/',
1636 flag_jni ? '_' : '/');
1637 fputs (".h>\n", out);
1642 /* This is used to represent part of a package or class name. */
1643 struct namelet
1645 /* The text of this part of the name. */
1646 char *name;
1647 /* True if this represents a class. */
1648 int is_class;
1649 /* Linked list of all classes and packages inside this one. */
1650 struct namelet *subnamelets;
1651 /* Pointer to next sibling. */
1652 struct namelet *next;
1655 static void add_namelet PARAMS ((const unsigned char *,
1656 const unsigned char *, struct namelet *));
1657 static void print_namelet PARAMS ((FILE *, struct namelet *, int));
1659 /* The special root namelet. */
1660 static struct namelet root =
1662 NULL,
1664 NULL,
1665 NULL
1668 /* This extracts the next name segment from the full UTF-8 encoded
1669 package or class name and links it into the tree. It does this
1670 recursively. */
1671 static void
1672 add_namelet (name, name_limit, parent)
1673 const unsigned char *name, *name_limit;
1674 struct namelet *parent;
1676 const unsigned char *p;
1677 struct namelet *n = NULL, *np;
1679 /* We want to skip the standard namespaces that we assume the
1680 runtime already knows about. We only do this at the top level,
1681 though, hence the check for `root'. */
1682 if (parent == &root)
1684 #define JAVALANG "java/lang/"
1685 #define JAVAIO "java/io/"
1686 #define JAVAUTIL "java/util/"
1687 if ((name_limit - name >= (int) sizeof (JAVALANG) - 1
1688 && ! strncmp (name, JAVALANG, sizeof (JAVALANG) - 1))
1689 || (name_limit - name >= (int) sizeof (JAVAUTIL) - 1
1690 && ! strncmp (name, JAVAUTIL, sizeof (JAVAUTIL) - 1))
1691 || (name_limit - name >= (int) sizeof (JAVAIO) - 1
1692 && ! strncmp (name, JAVAIO, sizeof (JAVAIO) - 1)))
1693 return;
1696 for (p = name; p < name_limit && *p != '/'; ++p)
1699 /* Search for this name beneath the PARENT node. */
1700 for (np = parent->subnamelets; np != NULL; np = np->next)
1702 /* We check the length because we might have a proper prefix. */
1703 if ((int) strlen (np->name) == p - name &&
1704 ! strncmp (name, np->name, p - name))
1706 n = np;
1707 break;
1711 if (n == NULL)
1713 n = (struct namelet *) xmalloc (sizeof (struct namelet));
1714 n->name = xmalloc (p - name + 1);
1715 strncpy (n->name, name, p - name);
1716 n->name[p - name] = '\0';
1717 n->is_class = (p == name_limit);
1718 n->subnamelets = NULL;
1719 n->next = parent->subnamelets;
1720 parent->subnamelets = n;
1723 /* We recurse if there is more text, and if the trailing piece does
1724 not represent an inner class. */
1725 if (p < name_limit)
1726 add_namelet (p + 1, name_limit, n);
1729 /* Print a single namelet. Destroys namelets while printing. */
1730 static void
1731 print_namelet (out, name, depth)
1732 FILE *out;
1733 struct namelet *name;
1734 int depth;
1736 int i, term = 0;
1737 struct namelet *c;
1739 if (name->name)
1741 for (i = 0; i < depth; ++i)
1742 fputc (' ', out);
1743 fprintf (out, "%s %s", name->is_class ? "class" : "namespace",
1744 name->name);
1745 if (name->is_class && name->subnamelets == NULL)
1746 fputs (";\n", out);
1747 else
1749 term = 1;
1750 fputs ("\n", out);
1751 for (i = 0; i < depth; ++i)
1752 fputc (' ', out);
1753 fputs ("{\n", out);
1757 c = name->subnamelets;
1758 while (c != NULL)
1760 struct namelet *next = c->next;
1761 print_namelet (out, c, depth + 2);
1762 c = next;
1764 name->subnamelets = NULL;
1766 if (name->name)
1768 if (term)
1770 for (i = 0; i < depth; ++i)
1771 fputc (' ', out);
1772 fputs ("}\n", out);
1773 /* Only print a `;' when printing a class. C++ is evil. */
1774 if (name->is_class)
1775 fputs (";", out);
1778 free (name->name);
1779 free (name);
1783 /* This is called to add some classes to the list of classes for which
1784 we need decls. The signature argument can be a function
1785 signature. */
1786 static void
1787 add_class_decl (out, jcf, signature)
1788 FILE *out;
1789 JCF *jcf;
1790 JCF_u2 signature;
1792 const unsigned char *s = JPOOL_UTF_DATA (jcf, signature);
1793 int len = JPOOL_UTF_LENGTH (jcf, signature);
1794 int i;
1796 for (i = 0; i < len; ++i)
1798 int start;
1800 /* If we see an array, then we include the array header. */
1801 if (s[i] == '[')
1803 print_include (out, "gcj/array", -1);
1804 continue;
1807 /* We're looking for `L<stuff>;' -- everything else is
1808 ignorable. */
1809 if (s[i] != 'L')
1810 continue;
1812 for (start = ++i; i < len && s[i] != ';'; ++i)
1815 add_namelet (&s[start], &s[i], &root);
1819 /* Print declarations for all classes required by this class. Any
1820 class or package in the `java' package is assumed to be handled
1821 statically in libjava; we don't generate declarations for these.
1822 This makes the generated headers a bit easier to read. */
1823 static void
1824 print_class_decls (out, jcf, self)
1825 FILE *out;
1826 JCF *jcf;
1827 int self;
1829 /* Make sure to always add the current class to the list of things
1830 that should be declared. */
1831 int name_index = JPOOL_USHORT1 (jcf, self);
1832 int len;
1833 const unsigned char *s;
1835 s = JPOOL_UTF_DATA (jcf, name_index);
1836 len = JPOOL_UTF_LENGTH (jcf, name_index);
1837 add_namelet (s, s + len, &root);
1839 if (root.subnamelets)
1841 fputs ("extern \"Java\"\n{\n", out);
1842 /* We use an initial offset of 0 because the root namelet
1843 doesn't cause anything to print. */
1844 print_namelet (out, &root, 0);
1845 fputs ("};\n\n", out);
1851 static void
1852 DEFUN(process_file, (jcf, out),
1853 JCF *jcf AND FILE *out)
1855 int code, i;
1856 uint32 field_start, method_end, method_start;
1858 current_jcf = jcf;
1860 last_access = -1;
1862 if (jcf_parse_preamble (jcf) != 0)
1864 fprintf (stderr, "Not a valid Java .class file.\n");
1865 found_error = 1;
1866 return;
1869 /* Parse and possibly print constant pool */
1870 code = jcf_parse_constant_pool (jcf);
1871 if (code != 0)
1873 fprintf (stderr, "error while parsing constant pool\n");
1874 found_error = 1;
1875 return;
1877 code = verify_constant_pool (jcf);
1878 if (code > 0)
1880 fprintf (stderr, "error in constant pool entry #%d\n", code);
1881 found_error = 1;
1882 return;
1885 jcf_parse_class (jcf);
1887 if (written_class_count++ == 0 && out)
1889 const char *cstart, *cstart2, *mode, *cend, *what, *jflag;
1890 if (flag_jni)
1892 cstart = "/*";
1893 cstart2 = " ";
1894 cend = " */";
1895 mode = "";
1896 what = "JNI";
1897 jflag = " -jni";
1899 else
1901 cstart = "//";
1902 cstart2 = "//";
1903 cend = "";
1904 mode = " -*- c++ -*-";
1905 what = "CNI";
1906 jflag = "";
1909 if (! stubs)
1910 fprintf (out, "%s DO NOT EDIT THIS FILE - it is machine generated%s%s\n\n",
1911 cstart, mode, cend);
1912 else
1914 fprintf (out, "%s This file was created by `gcjh -stubs%s'.%s\n\
1915 %s\n\
1916 %s This file is intended to give you a head start on implementing native\n\
1917 %s methods using %s.\n\
1918 %s Be aware: running `gcjh -stubs %s' once more for this class may\n\
1919 %s overwrite any edits you have made to this file.%s\n\n",
1920 cstart, jflag, mode,
1921 cstart2,
1922 cstart2,
1923 cstart2,
1924 what,
1925 cstart2,
1926 jflag,
1927 cstart2,
1928 cend);
1932 if (out)
1934 if (! stubs)
1936 print_mangled_classname (out, jcf, "#ifndef __", jcf->this_class);
1937 fprintf (out, "__\n");
1939 print_mangled_classname (out, jcf, "#define __", jcf->this_class);
1940 fprintf (out, "__\n\n");
1942 if (flag_jni)
1944 fprintf (out, "#include <jni.h>\n\n");
1945 fprintf (out, "#ifdef __cplusplus\n");
1946 fprintf (out, "extern \"C\"\n");
1947 fprintf (out, "{\n");
1948 fprintf (out, "#endif\n");
1950 else
1952 /* We do this to ensure that inline methods won't be
1953 `outlined' by g++. This works as long as method and
1954 fields are not added by the user. */
1955 fprintf (out, "#pragma interface\n");
1957 if (jcf->super_class)
1959 int super_length;
1960 const unsigned char *supername =
1961 super_class_name (jcf, &super_length);
1963 fputs ("\n", out);
1964 print_include (out, supername, super_length);
1968 else
1970 /* Strip off the ".class" portion of the name when printing
1971 the include file name. */
1972 int len = strlen (jcf->classname);
1973 if (len > 6 && ! strcmp (&jcf->classname[len - 6], ".class"))
1974 len -= 6;
1975 print_include (out, jcf->classname, len);
1976 if (! flag_jni)
1977 print_include (out, "gcj/cni", -1);
1981 /* We want to parse the methods first. But we need to find where
1982 they start. So first we skip the fields, then parse the methods.
1983 Then we parse the fields and skip the methods. This is ugly, but
1984 not too bad since we need two full passes to get class decl
1985 information anyway. */
1986 field_pass = 0;
1987 field_start = JCF_TELL (jcf);
1988 jcf_parse_fields (jcf);
1990 method_start = JCF_TELL (jcf);
1991 method_pass = 0;
1992 jcf_parse_methods (jcf);
1994 if (out)
1995 fputs ("\n", out);
1997 if (out && ! flag_jni)
1999 if (! stubs)
2000 print_class_decls (out, jcf, jcf->this_class);
2002 for (i = 0; i < prepend_count; ++i)
2003 fprintf (out, "%s\n", prepend_specs[i]);
2004 if (prepend_count > 0)
2005 fputc ('\n', out);
2007 if (! stubs)
2009 if (! print_cxx_classname (out, "class ", jcf, jcf->this_class))
2011 fprintf (stderr, "class is of array type\n");
2012 found_error = 1;
2013 return;
2015 if (jcf->super_class)
2017 if (! print_cxx_classname (out, " : public ",
2018 jcf, jcf->super_class))
2020 fprintf (stderr, "base class is of array type\n");
2021 found_error = 1;
2022 return;
2026 fputs ("\n{\n", out);
2030 /* Now go back for second pass over methods and fields. */
2031 JCF_SEEK (jcf, method_start);
2032 method_pass = 1;
2033 jcf_parse_methods (jcf);
2034 method_end = JCF_TELL (jcf);
2036 field_pass = 1;
2037 JCF_SEEK (jcf, field_start);
2038 jcf_parse_fields (jcf);
2039 JCF_SEEK (jcf, method_end);
2041 jcf_parse_final_attributes (jcf);
2043 if (out && ! stubs)
2045 if (flag_jni)
2047 fprintf (out, "\n#ifdef __cplusplus\n");
2048 fprintf (out, "}\n");
2049 fprintf (out, "#endif\n");
2051 else
2053 /* Generate friend decl if we still must. */
2054 for (i = 0; i < friend_count; ++i)
2055 fprintf (out, " friend %s\n", friend_specs[i]);
2057 /* Generate extra declarations. */
2058 if (add_count > 0)
2059 fputc ('\n', out);
2060 for (i = 0; i < add_count; ++i)
2061 fprintf (out, " %s\n", add_specs[i]);
2063 /* Generate an entry for the class object. */
2064 generate_access (out, ACC_PUBLIC);
2065 fprintf (out, "\n static ::java::lang::Class class$;\n");
2067 fputs ("}", out);
2069 if (jcf->access_flags & ACC_INTERFACE)
2070 fputs (" __attribute__ ((java_interface))", out);
2072 fputs (";\n", out);
2074 if (append_count > 0)
2075 fputc ('\n', out);
2076 for (i = 0; i < append_count; ++i)
2077 fprintf (out, "%s\n", append_specs[i]);
2080 print_mangled_classname (out, jcf,
2081 "\n#endif /* __", jcf->this_class);
2082 fprintf (out, "__ */\n");
2088 /* This is used to mark options with no short value. */
2089 #define LONG_OPT(Num) ((Num) + 128)
2091 #define OPT_classpath LONG_OPT (0)
2092 #define OPT_CLASSPATH LONG_OPT (1)
2093 #define OPT_HELP LONG_OPT (2)
2094 #define OPT_TEMP LONG_OPT (3)
2095 #define OPT_VERSION LONG_OPT (4)
2096 #define OPT_PREPEND LONG_OPT (5)
2097 #define OPT_FRIEND LONG_OPT (6)
2098 #define OPT_ADD LONG_OPT (7)
2099 #define OPT_APPEND LONG_OPT (8)
2100 #define OPT_M LONG_OPT (9)
2101 #define OPT_MM LONG_OPT (10)
2102 #define OPT_MG LONG_OPT (11)
2103 #define OPT_MD LONG_OPT (12)
2104 #define OPT_MMD LONG_OPT (13)
2106 static const struct option options[] =
2108 { "classpath", required_argument, NULL, OPT_classpath },
2109 { "CLASSPATH", required_argument, NULL, OPT_CLASSPATH },
2110 { "help", no_argument, NULL, OPT_HELP },
2111 { "stubs", no_argument, &stubs, 1 },
2112 { "td", required_argument, NULL, OPT_TEMP },
2113 { "verbose", no_argument, NULL, 'v' },
2114 { "version", no_argument, NULL, OPT_VERSION },
2115 { "prepend", required_argument, NULL, OPT_PREPEND },
2116 { "friend", required_argument, NULL, OPT_FRIEND },
2117 { "add", required_argument, NULL, OPT_ADD },
2118 { "append", required_argument, NULL, OPT_APPEND },
2119 { "M", no_argument, NULL, OPT_M },
2120 { "MM", no_argument, NULL, OPT_MM },
2121 { "MG", no_argument, NULL, OPT_MG },
2122 { "MD", no_argument, NULL, OPT_MD },
2123 { "MMD", no_argument, NULL, OPT_MMD },
2124 { "jni", no_argument, &flag_jni, 1 },
2125 { NULL, no_argument, NULL, 0 }
2128 static void
2129 usage ()
2131 fprintf (stderr, "Try `gcjh --help' for more information.\n");
2132 exit (1);
2135 static void
2136 help ()
2138 printf ("Usage: gcjh [OPTION]... CLASS...\n\n");
2139 printf ("Generate C++ header files from .class files\n\n");
2140 printf (" -stubs Generate an implementation stub file\n");
2141 printf (" -jni Generate a JNI header or stub\n");
2142 printf ("\n");
2143 printf (" -add TEXT Insert TEXT into class body\n");
2144 printf (" -append TEXT Insert TEXT after class declaration\n");
2145 printf (" -friend TEXT Insert TEXT as `friend' declaration\n");
2146 printf (" -prepend TEXT Insert TEXT before start of class\n");
2147 printf ("\n");
2148 printf (" --classpath PATH Set path to find .class files\n");
2149 printf (" --CLASSPATH PATH Set path to find .class files\n");
2150 printf (" -IDIR Append directory to class path\n");
2151 printf (" -d DIRECTORY Set output directory name\n");
2152 printf (" -o FILE Set output file name\n");
2153 printf (" -td DIRECTORY Set temporary directory name\n");
2154 printf ("\n");
2155 printf (" --help Print this help, then exit\n");
2156 printf (" --version Print version number, then exit\n");
2157 printf (" -v, --verbose Print extra information while running\n");
2158 printf ("\n");
2159 printf (" -M Print all dependencies to stdout;\n");
2160 printf (" suppress ordinary output\n");
2161 printf (" -MM Print non-system dependencies to stdout;\n");
2162 printf (" suppress ordinary output\n");
2163 printf (" -MD Print all dependencies to stdout\n");
2164 printf (" -MMD Print non-system dependencies to stdout\n");
2165 /* We omit -MG until it is implemented. */
2166 printf ("\n");
2167 printf ("For bug reporting instructions, please see:\n");
2168 printf ("%s.\n", GCCBUGURL);
2169 exit (0);
2172 static void
2173 version ()
2175 printf ("gcjh (%s)\n\n", version_string);
2176 printf ("Copyright (C) 2001 Free Software Foundation, Inc.\n");
2177 printf ("This is free software; see the source for copying conditions. There is NO\n");
2178 printf ("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
2179 exit (0);
2183 DEFUN(main, (argc, argv),
2184 int argc AND char** argv)
2186 JCF jcf;
2187 int argi;
2188 char *output_file = NULL;
2189 int emit_dependencies = 0, suppress_output = 0;
2190 int opt;
2192 if (argc <= 1)
2194 fprintf (stderr, "gcjh: no classes specified\n");
2195 usage ();
2198 jcf_path_init ();
2200 /* We use getopt_long_only to allow single `-' long options. For
2201 some of our options this is more natural. */
2202 while ((opt = getopt_long_only (argc, argv, "I:d:o:v", options, NULL)) != -1)
2204 switch (opt)
2206 case 0:
2207 /* Already handled. */
2208 break;
2210 case 'o':
2211 output_file = optarg;
2212 break;
2214 case 'd':
2215 output_directory = optarg;
2216 break;
2218 case 'I':
2219 jcf_path_include_arg (optarg);
2220 break;
2222 case 'v':
2223 verbose++;
2224 break;
2226 case OPT_classpath:
2227 jcf_path_classpath_arg (optarg);
2228 break;
2230 case OPT_CLASSPATH:
2231 jcf_path_CLASSPATH_arg (optarg);
2232 break;
2234 case OPT_HELP:
2235 help ();
2236 break;
2238 case OPT_TEMP:
2239 temp_directory = optarg;
2240 break;
2242 case OPT_VERSION:
2243 version ();
2244 break;
2246 case OPT_PREPEND:
2247 if (prepend_count == 0)
2248 prepend_specs = (char**) ALLOC (argc * sizeof (char*));
2249 prepend_specs[prepend_count++] = optarg;
2250 break;
2252 case OPT_FRIEND:
2253 if (friend_count == 0)
2254 friend_specs = (char**) ALLOC (argc * sizeof (char*));
2255 friend_specs[friend_count++] = optarg;
2256 break;
2258 case OPT_ADD:
2259 if (add_count == 0)
2260 add_specs = (char**) ALLOC (argc * sizeof (char*));
2261 add_specs[add_count++] = optarg;
2262 break;
2264 case OPT_APPEND:
2265 if (append_count == 0)
2266 append_specs = (char**) ALLOC (argc * sizeof (char*));
2267 append_specs[append_count++] = optarg;
2268 break;
2270 case OPT_M:
2271 emit_dependencies = 1;
2272 suppress_output = 1;
2273 jcf_dependency_init (1);
2274 break;
2276 case OPT_MM:
2277 emit_dependencies = 1;
2278 suppress_output = 1;
2279 jcf_dependency_init (0);
2280 break;
2282 case OPT_MG:
2283 fprintf (stderr, "gcjh: `-MG' option is unimplemented\n");
2284 exit (1);
2286 case OPT_MD:
2287 emit_dependencies = 1;
2288 jcf_dependency_init (1);
2289 break;
2291 case OPT_MMD:
2292 emit_dependencies = 1;
2293 jcf_dependency_init (0);
2294 break;
2296 default:
2297 usage ();
2298 break;
2302 if (optind == argc)
2304 fprintf (stderr, "gcjh: no classes specified\n");
2305 usage ();
2308 jcf_path_seal (verbose);
2310 if (output_file && emit_dependencies)
2312 fprintf (stderr, "gcjh: can't specify both -o and -MD\n");
2313 exit (1);
2316 for (argi = optind; argi < argc; argi++)
2318 char *classname = argv[argi];
2319 char *current_output_file;
2320 const char *classfile_name;
2322 if (verbose)
2323 fprintf (stderr, "Processing %s\n", classname);
2324 if (! output_file)
2325 jcf_dependency_reset ();
2326 classfile_name = find_class (classname, strlen (classname), &jcf, 0);
2327 if (classfile_name == NULL)
2329 fprintf (stderr, "%s: no such class\n", classname);
2330 exit (1);
2332 if (verbose)
2333 fprintf (stderr, "Found in %s\n", classfile_name);
2334 if (output_file)
2336 if (strcmp (output_file, "-") == 0)
2337 out = stdout;
2338 else if (out == NULL)
2340 out = fopen (output_file, "w");
2342 if (out == NULL)
2344 perror (output_file);
2345 exit (1);
2347 current_output_file = output_file;
2349 else
2351 int dir_len = strlen (output_directory);
2352 int i, classname_length = strlen (classname);
2353 current_output_file = (char*) ALLOC (dir_len + classname_length + 5);
2354 strcpy (current_output_file, output_directory);
2355 if (dir_len > 0 && output_directory[dir_len-1] != '/')
2356 current_output_file[dir_len++] = '/';
2357 for (i = 0; classname[i] != '\0'; i++)
2359 char ch = classname[i];
2360 if (ch == '.')
2361 ch = '/';
2362 if (flag_jni && ch == '/')
2363 ch = '_';
2364 current_output_file[dir_len++] = ch;
2366 if (emit_dependencies)
2368 if (suppress_output)
2370 jcf_dependency_set_dep_file ("-");
2371 out = NULL;
2373 else
2375 /* We use `.hd' and not `.d' to avoid clashes with
2376 dependency tracking from straight compilation. */
2377 strcpy (current_output_file + dir_len, ".hd");
2378 jcf_dependency_set_dep_file (current_output_file);
2381 strcpy (current_output_file + dir_len,
2382 stubs ? (flag_jni ? ".c" : ".cc") : ".h");
2383 jcf_dependency_set_target (current_output_file);
2384 if (! suppress_output)
2386 out = fopen (current_output_file, "w");
2387 if (out == NULL)
2389 perror (current_output_file);
2390 exit (1);
2394 process_file (&jcf, out);
2395 JCF_FINISH (&jcf);
2396 if (current_output_file != output_file)
2397 free (current_output_file);
2398 jcf_dependency_write ();
2401 if (out != NULL && out != stdout)
2402 fclose (out);
2404 return found_error;