912fdb1
2007-03-29  Andrew Haley  <aph@redhat.com>
1b4610d
1b4610d
	* jvgenmain.c (main): Change main to use class$, not class$$.
1b4610d
	(do_mangle_classname): Likewise.
1b4610d
	* class.c (hide): New function.
1b4610d
	(add_field): Hide everything that shouldn't be visible outside a
1b4610d
	DSO.
1b4610d
	(build_static_class_ref): Likewise.
1b4610d
	(build_classdollar_field): Likewise.
1b4610d
	(make_class_data): Likewise.
1b4610d
	(layout_class_method): Likewise.
912fdb1
	* expr.c (special_method_p): New function.
912fdb1
912fdb1
--- gcc/java/class.c	(revision 122746)
1b4610d
+++ gcc/java/class.c	(working copy)
912fdb1
@@ -689,6 +688,13 @@
1b4610d
   return fntype;
1b4610d
 }
1b4610d
 
1b4610d
+static void
1b4610d
+hide (tree decl)
1b4610d
+{
1b4610d
+  DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
1b4610d
+  DECL_VISIBILITY_SPECIFIED (decl) = 1;
1b4610d
+}
1b4610d
+
1b4610d
 tree
1b4610d
 add_method_1 (tree this_class, int access_flags, tree name, tree function_type)
1b4610d
 {
912fdb1
@@ -799,6 +805,10 @@
1b4610d
       /* Always make field externally visible.  This is required so
1b4610d
 	 that native methods can always access the field.  */
1b4610d
       TREE_PUBLIC (field) = 1;
1b4610d
+      /* Hide everything that shouldn't be visible outside a DSO.  */
1b4610d
+      if (flag_indirect_classes
1b4610d
+	  || (FIELD_PRIVATE (field)))
1b4610d
+	hide (field);
1b4610d
       /* Considered external unless we are compiling it into this
1b4610d
 	 object file.  */
1b4610d
       DECL_EXTERNAL (field) = (is_compiled_class (class) != 2);
912fdb1
@@ -956,7 +966,11 @@
1b4610d
       decl = build_decl (VAR_DECL, decl_name, class_type_node);
1b4610d
       TREE_STATIC (decl) = 1;
1b4610d
       if (! flag_indirect_classes)
1b4610d
-	TREE_PUBLIC (decl) = 1;
1b4610d
+	{
1b4610d
+	  TREE_PUBLIC (decl) = 1;
1b4610d
+	  if (CLASS_PRIVATE (TYPE_NAME (type)))
1b4610d
+	    hide (decl);
1b4610d
+	}
1b4610d
       DECL_IGNORED_P (decl) = 1;
1b4610d
       DECL_ARTIFICIAL (decl) = 1;
1b4610d
       if (is_compiled_class (type) == 1)
912fdb1
@@ -995,6 +1009,7 @@
1b4610d
       TREE_CONSTANT (decl) = 1;
1b4610d
       TREE_READONLY (decl) = 1;
1b4610d
       TREE_PUBLIC (decl) = 1;
1b4610d
+      hide (decl);
1b4610d
       DECL_IGNORED_P (decl) = 1;
1b4610d
       DECL_ARTIFICIAL (decl) = 1;
1b4610d
       MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
912fdb1
@@ -1640,6 +1655,10 @@
1b4610d
 
1b4610d
       TREE_PUBLIC (dtable_decl) = 1;
1b4610d
       DECL_INITIAL (dtable_decl) = dtable;
1b4610d
+      /* The only dispatch table exported from a DSO is the dispatch
1b4610d
+	 table for java.lang.Class.  */
1b4610d
+      if (DECL_NAME (type_decl) != id_class)
1b4610d
+	hide (dtable_decl);
1b4610d
       if (! flag_indirect_classes)
1b4610d
 	rest_of_decl_compilation (dtable_decl, 1, 0);
1b4610d
       /* Maybe we're compiling Class as the first class.  If so, set
912fdb1
@@ -2509,6 +2528,12 @@
1b4610d
 
1b4610d
   TREE_PUBLIC (method_decl) = 1;
1b4610d
 
1b4610d
+  if (flag_indirect_classes
912fdb1
+      || (METHOD_PRIVATE (method_decl) && METHOD_STATIC (method_decl)
912fdb1
+	  && ! METHOD_NATIVE (method_decl)
912fdb1
+	  && ! special_method_p (method_decl)))
1b4610d
+    hide (method_decl);
1b4610d
+
1b4610d
   /* Considered external unless it is being compiled into this object
1b4610d
      file, or it was already flagged as external.  */
1b4610d
   if (!DECL_EXTERNAL (method_decl))
912fdb1
--- gcc/java/jvgenmain.c	(revision 122746)
1b4610d
+++ gcc/java/jvgenmain.c	(working copy)
1b4610d
@@ -143,8 +143,8 @@
1b4610d
     fprintf (stream, "   JvRunMainName (\"%s\", argc, argv);\n", classname);
1b4610d
   else
1b4610d
     {
1b4610d
-      fprintf (stream, "   extern void *%s;\n", mangled_classname);
1b4610d
-      fprintf (stream, "   JvRunMain (%s, argc, argv);\n", mangled_classname);
1b4610d
+      fprintf (stream, "   extern char %s;\n", mangled_classname);
1b4610d
+      fprintf (stream, "   JvRunMain (&%s, argc, argv);\n", mangled_classname);
1b4610d
     }
1b4610d
   fprintf (stream, "}\n");
1b4610d
   if (stream != stdout && fclose (stream) != 0)
1b4610d
@@ -176,7 +176,7 @@
1b4610d
 	count++;
1b4610d
     }
1b4610d
   append_gpp_mangled_name (&ptr [-count], count);
1b4610d
-  obstack_grow (mangle_obstack, "7class$$E", strlen ("7class$$E"));
1b4610d
+  obstack_grow (mangle_obstack, "6class$E", strlen ("6class$E"));
1b4610d
   obstack_1grow (mangle_obstack, '\0');
1b4610d
   return obstack_finish (mangle_obstack);
1b4610d
 }
912fdb1
--- gcc/java/expr.c	(revision 122746)
912fdb1
+++ gcc/java/expr.c	(working copy)
912fdb1
@@ -2121,6 +2121,25 @@
912fdb1
 
912fdb1
    {NULL, NULL, NULL, NULL, 0, NULL}};
912fdb1
 
912fdb1
+/* True if this method is special, i.e. it's a private method that
912fdb1
+   should be exported fro a DSO.  */
912fdb1
+
912fdb1
+bool
912fdb1
+special_method_p (tree candidate_method)
912fdb1
+{
912fdb1
+  tree context = DECL_NAME (TYPE_NAME (DECL_CONTEXT (candidate_method)));
912fdb1
+  tree method = DECL_NAME (candidate_method);
912fdb1
+  rewrite_rule *p;
912fdb1
+
912fdb1
+  for (p = rules; p->classname; p++)
912fdb1
+    {
912fdb1
+      if (get_identifier (p->classname) == context
912fdb1
+	  && get_identifier (p->method) == method)
912fdb1
+	return true;
912fdb1
+    }
912fdb1
+  return false;
912fdb1
+}
912fdb1
+
912fdb1
 /* Scan the rules list for replacements for *METHOD_P and replace the
912fdb1
    args accordingly.  If the rewrite results in an access to a private
912fdb1
    method, update SPECIAL.*/
912fdb1
--- gcc/java/java-tree.h	(revision 122746)
912fdb1
+++ gcc/java/java-tree.h	(working copy)
912fdb1
@@ -1171,6 +1171,7 @@
912fdb1
 extern void initialize_builtins (void);
912fdb1
 
912fdb1
 extern tree lookup_name (tree);
912fdb1
+extern bool special_method_p (tree);
912fdb1
 extern void maybe_rewrite_invocation (tree *, tree *, tree *, tree *);
912fdb1
 extern tree build_known_method_ref (tree, tree, tree, tree, tree, tree);
912fdb1
 extern tree build_class_init (tree, tree);