OSDN Git Service

* gjavah.c (print_stub): New function.
authorgreen <green@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 25 Jul 1999 10:12:49 +0000 (10:12 +0000)
committergreen <green@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 25 Jul 1999 10:12:49 +0000 (10:12 +0000)
        (METHOD_IS_NATIVE): New macro.
        (print_mangled_classname): Make static.
        (HANDLE_END_FIELD): Don't emit fields during stub generation.
        (process_file): Perform stub generation.
        (HANDLE_METHOD): Don't emit class decls during stub
        generation.
        (HANDLE_END_METHOD): Take into account stub generation.
        (print_method_info): Handle stub generation.
        (print_stub): New function.
        (print_cxx_classname): Make signature consistant with others.
        (help): Describe -stubs option.
        (main): Create stub file.
        (version): Use version.c.
        (print_full_cxx_name): New function.
        (print_c_decl): Use print_full_cxx_name.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@28236 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/java/ChangeLog
gcc/java/gjavah.c

index 6d3d690..cc4ce98 100644 (file)
@@ -1,3 +1,22 @@
+1999-07-25  Anthony Green  <green@cygnus.com>
+
+       * gjavah.c (print_stub): New function.
+       (METHOD_IS_NATIVE): New macro.
+       (print_mangled_classname): Make static.
+       (HANDLE_END_FIELD): Don't emit fields during stub generation.
+       (process_file): Perform stub generation.
+       (HANDLE_METHOD): Don't emit class decls during stub
+       generation.
+       (HANDLE_END_METHOD): Take into account stub generation.
+       (print_method_info): Handle stub generation.
+       (print_stub): New function.
+       (print_cxx_classname): Make signature consistant with others.
+       (help): Describe -stubs option.
+       (main): Create stub file.
+       (version): Use version.c.
+       (print_full_cxx_name): New function.
+       (print_c_decl): Use print_full_cxx_name.
+
 Thu Jul 22 12:41:12 1999  Alexandre Petit-Bianco  <apbianco@cygnus.com>
 
        * check-init.c (check_init): Handle MAX_EXPR.
index f99ad5b..500aa2c 100644 (file)
@@ -33,6 +33,8 @@ The Free Software Foundation is independent of Sun Microsystems, Inc.  */
 #include "java-tree.h"
 #include "java-opcodes.h"
 
+#include "version.c"
+
 /* The output file.  */
 FILE *out = NULL;
 
@@ -88,6 +90,11 @@ static JCF_u2 last_access;
 #define METHOD_IS_FINAL(Class, Method) \
    (((Class) & ACC_FINAL) || ((Method) & (ACC_FINAL | ACC_PRIVATE)))
 
+/* Pass this macro the flags for a method.  It will return true if the
+   method is native.  */
+#define METHOD_IS_NATIVE(Method) \
+   ((Method) & ACC_NATIVE)
+
 /* We keep a linked list of all method names we have seen.  This lets
    us determine if a method name and a field name are in conflict.  */
 struct method_name
@@ -100,11 +107,15 @@ struct method_name
 /* List of method names we've seen.  */
 static struct method_name *method_name_list;
 
-static void print_field_info PROTO ((FILE *, JCF*, int, int, JCF_u2));
-static void print_method_info PROTO ((FILE *, JCF*, int, int, JCF_u2));
+static void print_field_info PROTO ((FILE*, JCF*, int, int, JCF_u2));
+static void print_mangled_classname PROTO ((FILE*, JCF*, const char*, int));
+static int  print_cxx_classname PROTO ((FILE*, const char*, JCF*, int));
+static void print_method_info PROTO ((FILE*, JCF*, int, int, JCF_u2));
 static void print_c_decl PROTO ((FILE*, JCF*, int, int, int, const char *));
-static void decompile_method PROTO ((FILE *, JCF *, int));
-static void add_class_decl PROTO ((FILE *, JCF *, JCF_u2));
+static void print_stub PROTO ((FILE*, JCF*, int, int, int, const char *));
+static void print_full_cxx_name PROTO ((FILE*, JCF*, int, int, int, const char *));
+static void decompile_method PROTO ((FILE*, JCF*, int));
+static void add_class_decl PROTO ((FILE*, JCF*, JCF_u2));
 
 static int java_float_finite PROTO ((jfloat));
 static int java_double_finite PROTO ((jdouble));
@@ -130,13 +141,13 @@ static int method_pass;
 #define HANDLE_END_FIELD()                                                   \
   if (field_pass)                                                            \
     {                                                                        \
-      if (out)                                                               \
+      if (out && ! stubs)                                                    \
        print_field_info (out, jcf, current_field_name,                       \
                          current_field_signature,                            \
                          current_field_flags);                               \
     }                                                                        \
   else                                                                       \
-    add_class_decl (out, jcf, current_field_signature);
+    if (! stubs) add_class_decl (out, jcf, current_field_signature);
 
 #define HANDLE_CONSTANTVALUE(VALUEINDEX) current_field_value = (VALUEINDEX)
 
@@ -151,14 +162,14 @@ static int method_printed = 0;
         print_method_info (out, jcf, NAME, SIGNATURE, ACCESS_FLAGS);         \
     }                                                                        \
   else                                                                       \
-    add_class_decl (out, jcf, SIGNATURE);
+    if (! stubs) add_class_decl (out, jcf, SIGNATURE);
 
 #define HANDLE_CODE_ATTRIBUTE(MAX_STACK, MAX_LOCALS, CODE_LENGTH) \
   if (out && method_declared) decompile_method (out, jcf, CODE_LENGTH);
 
 static int decompiled = 0;
 #define HANDLE_END_METHOD() \
-  if (out && method_printed) fputs (decompiled ? "\n" : ";\n", out);
+  if (out && method_printed) fputs (decompiled || stubs ? "\n" : ";\n", out);
 
 #include "jcf-reader.c"
 
@@ -562,24 +573,36 @@ DEFUN(print_method_info, (stream, jcf, name_index, sig_index, flags),
        return;
     }
 
-  method_printed = 1;
-  generate_access (stream, flags);
-
-  fputs ("  ", out);
-  if ((flags & ACC_STATIC))
-    fputs ("static ", out);
-  else if (! METHOD_IS_FINAL (jcf->access_flags, flags))
+  if (! stubs)
     {
-      /* Don't print `virtual' if we have a constructor.  */
-      if (! is_init)
-       fputs ("virtual ", out);
-    }
-  print_c_decl (out, jcf, name_index, sig_index, is_init, override);
+      method_printed = 1;
 
-  if ((flags & ACC_ABSTRACT))
-    fputs (" = 0", out);
+      generate_access (stream, flags);
+      
+      fputs ("  ", out);
+      if ((flags & ACC_STATIC))
+       fputs ("static ", out);
+      else if (! METHOD_IS_FINAL (jcf->access_flags, flags))
+       {
+         /* Don't print `virtual' if we have a constructor.  */
+         if (! is_init)
+           fputs ("virtual ", out);
+       }
+      print_c_decl (out, jcf, name_index, sig_index, is_init, override);
+      
+      if ((flags & ACC_ABSTRACT))
+       fputs (" = 0", out);
+      else
+       method_declared = 1;
+    }
   else
-    method_declared = 1;
+    {
+      if (METHOD_IS_NATIVE(flags)) 
+       {
+         method_printed = 1;
+         print_stub (out, jcf, name_index, sig_index, is_init, override);
+       }
+    }
 }
 
 /* Try to decompile a method body.  Right now we just try to handle a
@@ -791,40 +814,121 @@ DEFUN(print_c_decl, (stream, jcf, name_index, signature_index, is_init,
       /* Now print the name of the thing.  */
       if (need_space)
        fputs (" ", stream);
-      if (name_override)
-       fputs (name_override, stream);
-      else if (name_index)
+      print_full_cxx_name (stream, jcf, name_index, 
+                          signature_index, is_init, name_override);
+    }
+}
+
+// Print the unqualified method name followed by the signature.
+static void
+DEFUN(print_full_cxx_name, (stream, jcf, name_index, signature_index, is_init, name_override),
+      FILE* stream AND JCF* jcf
+      AND int name_index AND int signature_index AND int is_init 
+      AND const char *name_override)
+{
+  int length = JPOOL_UTF_LENGTH (jcf, signature_index);
+  unsigned char *str0 = JPOOL_UTF_DATA (jcf, signature_index);
+  register  unsigned char *str = str0;
+  unsigned char *limit = str + length;
+  int need_space = 0;
+  int is_method = str[0] == '(';
+  unsigned char *next;
+
+  if (name_override)
+    fputs (name_override, stream);
+  else if (name_index)
+    {
+      /* Declare constructors specially.  */
+      if (is_init)
+       print_base_classname (stream, jcf, jcf->this_class);
+      else
+       print_name (stream, jcf, name_index);
+    }
+  
+  if (is_method)
+    {
+      /* Have a method or a constructor.  Print signature pieces
+        until done.  */
+      fputs (" (", stream);
+      str = str0 + 1;
+      while (str < limit && *str != ')')
        {
-         /* Declare constructors specially.  */
-         if (is_init)
-           print_base_classname (stream, jcf, jcf->this_class);
-         else
-           print_name (stream, jcf, name_index);
+         next = decode_signature_piece (stream, str, limit, &need_space);
+         if (! next)
+           {
+             fprintf (stderr, "unparseable signature: `%s'\n", str0);
+             found_error = 1;
+             return;
+           }
+         
+         if (next < limit && *next != ')')
+           fputs (", ", stream);
+         str = next;
        }
+      
+      fputs (")", stream);
+    }
+}
+      
+static void
+DEFUN(print_stub, (stream, jcf, name_index, signature_index, is_init,
+                    name_override),
+      FILE* stream AND JCF* jcf
+      AND int name_index AND int signature_index
+      AND int is_init AND const char *name_override)
+{
+  if (JPOOL_TAG (jcf, signature_index) != CONSTANT_Utf8)
+    {
+      fprintf (stream, "<not a UTF8 constant>");
+      found_error = 1;
+    }
+  else
+    {
+      int length = JPOOL_UTF_LENGTH (jcf, signature_index);
+      unsigned char *str0 = JPOOL_UTF_DATA (jcf, signature_index);
+      register  unsigned char *str = str0;
+      unsigned char *limit = str + length;
+      int need_space = 0;
+      int is_method = str[0] == '(';
+      unsigned char *next;
 
-      if (is_method)
+      /* If printing a method, skip to the return signature and print
+        that first.  However, there is no return value if this is a
+        constructor.  */
+      if (is_method && ! is_init)
        {
-         /* Have a method or a constructor.  Print signature pieces
-            until done.  */
-         fputs (" (", stream);
-         str = str0 + 1;
-         while (str < limit && *str != ')')
+         while (str < limit)
            {
-             next = decode_signature_piece (stream, str, limit, &need_space);
-             if (! next)
-               {
-                 fprintf (stderr, "unparseable signature: `%s'\n", str0);
-                 found_error = 1;
-                 return;
-               }
-
-             if (next < limit && *next != ')')
-               fputs (", ", stream);
-             str = next;
+             int ch = *str++;
+             if (ch == ')')
+               break;
            }
+       }
 
-         fputs (")", stream);
+      /* If printing a field or an ordinary method, then print the
+        "return value" now.  */
+      if (! is_method || ! is_init)
+       {
+         next = decode_signature_piece (stream, str, limit, &need_space);
+         if (! next)
+           {
+             fprintf (stderr, "unparseable signature: `%s'\n", str0);
+             found_error = 1;
+             return;
+           }
        }
+
+      /* Now print the name of the thing.  */
+      print_cxx_classname (stream, "\n", jcf, jcf->this_class);
+      fputs ("::", stream);
+      print_full_cxx_name (stream, jcf, name_index, 
+                          signature_index, is_init, name_override);
+      fputs ("\n{\n  JvFail (\"", stream);
+      print_cxx_classname (stream, "", jcf, jcf->this_class);
+      fputs ("::", stream);
+      print_full_cxx_name (stream, jcf, name_index, 
+                          signature_index, is_init, name_override);
+      fputs (" not implemented\");\n}\n\n", stream);
     }
 }
 
@@ -846,7 +950,7 @@ DEFUN(print_mangled_classname, (stream, jcf, prefix, index),
 static int
 print_cxx_classname (stream, prefix, jcf, index)
      FILE *stream;
-     char *prefix;
+     const char *prefix;
      JCF *jcf;
      int index;
 {
@@ -1204,30 +1308,49 @@ DEFUN(process_file, (jcf, out),
   jcf_parse_class (jcf);
 
   if (written_class_count++ == 0 && out)
-    fputs ("// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-\n\n",
-          out);
+    if (! stubs)
+      fputs ("// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-\n\n",
+            out);
+    else
+      {
+       fputs ("// This file was created by `gcjh -stubs'.  It is -*- c++ -*-.
+//
+// This file is intended to give you a head start on implementing native 
+// methods using CNI.  
+// Be aware: running `gcjh -stubs' once more for this class may overwrite any 
+// edits you have made to this file.\n\n", out);
+      }
 
   if (out)
     {
-      print_mangled_classname (out, jcf, "#ifndef __", jcf->this_class);
-      fprintf (out, "__\n");
-
-      print_mangled_classname (out, jcf, "#define __", jcf->this_class);
-      fprintf (out, "__\n\n");
-
-      /* We do this to ensure that inline methods won't be `outlined'
-        by g++.  This works as long as method and fields are not
-        added by the user.  */
-      fprintf (out, "#pragma interface\n");
-    }
-
-  if (jcf->super_class && out)
-    {
-      int super_length;
-      unsigned char *supername = super_class_name (jcf, &super_length);
-
-      fputs ("\n", out);
-      print_include (out, supername, super_length);
+      if (! stubs)
+       {
+         print_mangled_classname (out, jcf, "#ifndef __", jcf->this_class);
+         fprintf (out, "__\n");
+         
+         print_mangled_classname (out, jcf, "#define __", jcf->this_class);
+         fprintf (out, "__\n\n");
+         
+         /* We do this to ensure that inline methods won't be `outlined'
+            by g++.  This works as long as method and fields are not
+            added by the user.  */
+         fprintf (out, "#pragma interface\n");
+         
+         if (jcf->super_class)
+           {
+             int super_length;
+             unsigned char *supername = super_class_name (jcf, &super_length);
+             
+             fputs ("\n", out);
+             print_include (out, supername, super_length);
+           }
+       }
+      else
+       {
+         /* Strip off the ".class" portion of the name when printing
+            the include file name.  */
+         print_include (out, jcf->classname, strlen (jcf->classname) - 6);
+       }
     }
 
   /* We want to parse the methods first.  But we need to find where
@@ -1246,31 +1369,37 @@ DEFUN(process_file, (jcf, out),
   if (out)
     {
       fputs ("\n", out);
-      print_class_decls (out, jcf, jcf->this_class);
+
+      if (! stubs)
+       print_class_decls (out, jcf, jcf->this_class);
 
       for (i = 0; i < prepend_count; ++i)
        fprintf (out, "%s\n", prepend_specs[i]);
       if (prepend_count > 0)
        fputc ('\n', out);
-    }
-
-  if (out && ! print_cxx_classname (out, "class ", jcf, jcf->this_class))
-    {
-      fprintf (stderr, "class is of array type\n");
-      found_error = 1;
-      return;
-    }
-  if (out && jcf->super_class)
-    {
-      if (! print_cxx_classname (out, " : public ", jcf, jcf->super_class))
+      
+      if (! stubs)
        {
-         fprintf (stderr, "base class is of array type\n");
-         found_error = 1;
-         return;
+         if (! print_cxx_classname (out, "class ", jcf, jcf->this_class))
+           {
+             fprintf (stderr, "class is of array type\n");
+             found_error = 1;
+             return;
+           }
+         if (jcf->super_class)
+           {
+             if (! print_cxx_classname (out, " : public ", 
+                                        jcf, jcf->super_class))
+               {
+                 fprintf (stderr, "base class is of array type\n");
+                 found_error = 1;
+                 return;
+               }
+           }
+
+         fputs ("\n{\n", out);
        }
     }
-  if (out)
-    fputs ("\n{\n", out);
 
   /* Now go back for second pass over methods and fields.  */
   JCF_SEEK (jcf, method_start);
@@ -1297,15 +1426,20 @@ DEFUN(process_file, (jcf, out),
       for (i = 0; i < add_count; ++i)
        fprintf (out, "  %s\n", add_specs[i]);
 
-      fputs ("};\n", out);
+      if (! stubs)
+       fputs ("};\n", out);
 
       if (append_count > 0)
        fputc ('\n', out);
       for (i = 0; i < append_count; ++i)
        fprintf (out, "%s\n", append_specs[i]);
 
-      print_mangled_classname (out, jcf, "\n#endif /* __", jcf->this_class);
-      fprintf (out, "__ */\n");
+      if (!stubs)
+       {
+         print_mangled_classname (out, jcf, 
+                                  "\n#endif /* __", jcf->this_class);
+         fprintf (out, "__ */\n");
+       }
     }
 }
 
@@ -1327,6 +1461,7 @@ help ()
   printf ("  -d DIRECTORY            Set output directory name\n");
   printf ("  --help                  Print this help, then exit\n");
   printf ("  -o FILE                 Set output file name\n");
+  printf ("  -stubs                  Generate a C++ implementation stub file\n");
   printf ("  -td DIRECTORY           Set temporary directory name\n");
   printf ("  -v, --verbose           Print extra information while running\n");
   printf ("  --version               Print version number, then exit\n");
@@ -1346,8 +1481,8 @@ static void
 version ()
 {
   /* FIXME: use version.c?  */
-  printf ("gcjh (GNU gcc) 0.0\n\n");
-  printf ("Copyright (C) 1998 Free Software Foundation, Inc.\n");
+  printf ("gcjh (%s)\n\n", version_string);
+  printf ("Copyright (C) 1998, 1999 Free Software Foundation, Inc.\n");
   printf ("This is free software; see the source for copying conditions.  There is NO\n");
   printf ("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
   exit (0);
@@ -1548,7 +1683,7 @@ DEFUN(main, (argc, argv),
        {
          int dir_len = strlen (output_directory);
          int i, classname_length = strlen (classname);
-         current_output_file = (char*) ALLOC (dir_len + classname_length + 4);
+         current_output_file = (char*) ALLOC (dir_len + classname_length + 5);
          strcpy (current_output_file, output_directory);
          if (dir_len > 0 && output_directory[dir_len-1] != '/')
            current_output_file[dir_len++] = '/';
@@ -1574,7 +1709,8 @@ DEFUN(main, (argc, argv),
                  jcf_dependency_set_dep_file (current_output_file);
                }
            }
-         strcpy (current_output_file + dir_len, ".h");
+         strcpy (current_output_file + dir_len, 
+                 stubs ? ".cc" : ".h");
          jcf_dependency_set_target (current_output_file);
          if (! suppress_output)
            {
@@ -1601,10 +1737,9 @@ DEFUN(main, (argc, argv),
 
 /* TODO:
 
- * Do whatever the javah -stubs flag does.
-
  * Emit "structure forward declarations" when needed.
 
  * Generate C headers, like javah
 
  */
+