OSDN Git Service

2007-07-09 Geoffrey Keating <geoffk@apple.com>
[pf3gnuchains/gcc-fork.git] / gcc / java / class.c
index 85cdeb4..bbfe4f2 100644 (file)
@@ -428,8 +428,7 @@ push_class (tree class_type, tree class_name)
   tree decl, signature;
   location_t saved_loc = input_location;
 #ifndef USE_MAPPED_LOCATION
-  tree source_name = identifier_subst (class_name, "", '.', '/', ".java");
-  input_filename = IDENTIFIER_POINTER (source_name);
+  input_filename = "<unknown>";
   input_line = 0;
 #endif
   CLASS_P (class_type) = 1;
@@ -691,6 +690,13 @@ build_java_method_type (tree fntype, tree this_class, int access_flags)
   return fntype;
 }
 
+static void
+hide (tree decl)
+{
+  DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+  DECL_VISIBILITY_SPECIFIED (decl) = 1;
+}
+
 tree
 add_method_1 (tree this_class, int access_flags, tree name, tree function_type)
 {
@@ -719,6 +725,14 @@ add_method_1 (tree this_class, int access_flags, tree name, tree function_type)
   TREE_CHAIN (fndecl) = TYPE_METHODS (this_class);
   TYPE_METHODS (this_class) = fndecl;
 
+  /* If pointers to member functions use the least significant bit to
+     indicate whether a function is virtual, ensure a pointer
+     to this function will have that bit clear.  */
+  if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
+      && !(access_flags & ACC_STATIC)
+      && DECL_ALIGN (fndecl) < 2 * BITS_PER_UNIT)
+    DECL_ALIGN (fndecl) = 2 * BITS_PER_UNIT;
+
   /* Notice that this is a finalizer and update the class type
      accordingly. This is used to optimize instance allocation. */
   if (name == finalize_identifier_node
@@ -801,6 +815,10 @@ add_field (tree class, tree name, tree field_type, int flags)
       /* Always make field externally visible.  This is required so
         that native methods can always access the field.  */
       TREE_PUBLIC (field) = 1;
+      /* Hide everything that shouldn't be visible outside a DSO.  */
+      if (flag_indirect_classes
+         || (FIELD_PRIVATE (field)))
+       hide (field);
       /* Considered external unless we are compiling it into this
         object file.  */
       DECL_EXTERNAL (field) = (is_compiled_class (class) != 2);
@@ -958,7 +976,11 @@ build_static_class_ref (tree type)
       decl = build_decl (VAR_DECL, decl_name, class_type_node);
       TREE_STATIC (decl) = 1;
       if (! flag_indirect_classes)
-       TREE_PUBLIC (decl) = 1;
+       {
+         TREE_PUBLIC (decl) = 1;
+         if (CLASS_PRIVATE (TYPE_NAME (type)))
+           hide (decl);
+       }
       DECL_IGNORED_P (decl) = 1;
       DECL_ARTIFICIAL (decl) = 1;
       if (is_compiled_class (type) == 1)
@@ -997,6 +1019,7 @@ build_classdollar_field (tree type)
       TREE_CONSTANT (decl) = 1;
       TREE_READONLY (decl) = 1;
       TREE_PUBLIC (decl) = 1;
+      hide (decl);
       DECL_IGNORED_P (decl) = 1;
       DECL_ARTIFICIAL (decl) = 1;
       MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
@@ -1008,7 +1031,7 @@ build_classdollar_field (tree type)
   return decl;
 }
 
-/* Create a local variable that holds the the current class$.  */
+/* Create a local variable that holds the current class$.  */
 
 void
 cache_this_class_ref (tree fndecl)
@@ -1654,8 +1677,7 @@ make_class_data (tree type)
   tree id_class = get_identifier("java.lang.Class");
   /** Offset from start of virtual function table declaration
       to where objects actually point at, following new g++ ABI. */
-  tree dtable_start_offset = build_int_cst (NULL_TREE,
-                                           2 * POINTER_SIZE / BITS_PER_UNIT);
+  tree dtable_start_offset = size_int (2 * POINTER_SIZE / BITS_PER_UNIT);
   VEC(int, heap) *field_indexes;
   tree first_real_field;
 
@@ -1684,6 +1706,10 @@ make_class_data (tree type)
 
       TREE_PUBLIC (dtable_decl) = 1;
       DECL_INITIAL (dtable_decl) = dtable;
+      /* The only dispatch table exported from a DSO is the dispatch
+        table for java.lang.Class.  */
+      if (DECL_NAME (type_decl) != id_class)
+       hide (dtable_decl);
       if (! flag_indirect_classes)
        rest_of_decl_compilation (dtable_decl, 1, 0);
       /* Maybe we're compiling Class as the first class.  If so, set
@@ -1938,7 +1964,7 @@ make_class_data (tree type)
   PUSH_FIELD_VALUE (temp, "vtable",
                    (flag_indirect_classes 
                     ? null_pointer_node
-                    : build2 (PLUS_EXPR, dtable_ptr_type,
+                    : build2 (POINTER_PLUS_EXPR, dtable_ptr_type,
                               build1 (ADDR_EXPR, dtable_ptr_type,
                                       class_dtable_decl),
                               dtable_start_offset)));
@@ -1986,7 +2012,7 @@ make_class_data (tree type)
   else
     PUSH_FIELD_VALUE (cons, "vtable",
                      dtable_decl == NULL_TREE ? null_pointer_node
-                     : build2 (PLUS_EXPR, dtable_ptr_type,
+                     : build2 (POINTER_PLUS_EXPR, dtable_ptr_type,
                                build1 (ADDR_EXPR, dtable_ptr_type,
                                        dtable_decl),
                                dtable_start_offset));
@@ -2553,6 +2579,12 @@ layout_class_method (tree this_class, tree super_class,
 
   TREE_PUBLIC (method_decl) = 1;
 
+  if (flag_indirect_classes
+      || (METHOD_PRIVATE (method_decl) && METHOD_STATIC (method_decl)
+         && ! METHOD_NATIVE (method_decl)
+         && ! special_method_p (method_decl)))
+    hide (method_decl);
+
   /* Considered external unless it is being compiled into this object
      file, or it was already flagged as external.  */
   if (!DECL_EXTERNAL (method_decl))
@@ -2782,7 +2814,8 @@ build_symbol_entry (tree decl, tree special)
      system that this is a "special" symbol, i.e. one that should
      bypass access controls.  */
   if (special != NULL_TREE)
-    signature = build2 (PLUS_EXPR, TREE_TYPE (signature), signature, special);
+    signature = build2 (POINTER_PLUS_EXPR, TREE_TYPE (signature), signature,
+                       fold_convert (sizetype, special));
       
   START_RECORD_CONSTRUCTOR (sym, symbol_type);
   PUSH_FIELD_VALUE (sym, "clname", clname);