This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[java/c++/rfc] avoid plt references to cni methods


The idea is that CNI code will be in the same DSO as its corresponding
Java code.  Indeed, after this patch it MUST be in the same DSO.  We
arrange for the C++ front end to emit hidden aliases for all of the 
functions that we need, and we use those in the _Jv_Method table.

On the C++ side, I need to wait until we've resolved clones.  Since
this is done during cgraph_analyze_function, which makes it difficult
to do this except for a separate pass over the generated functions.

I've somewhat arbitrarily chosen to extend the mangling grammar:

  <special_name> := HA <encoding>

where "HA" stands for "hidden alias".  It's not inconcievable that
such aliases could be useful in other cases.  In any event, it seemed
safer to inject myself into a logical point in the grammar like this
than invent my own private prefix/suffix which could just as easily
conflict with other symbols.

On the Java side, I've rearranged things to use the name mangling 
langhook.  This reduces the number of places that need to touch
DECL_ASSEMBLER_NAME to the builtins and the mangler itself.  This
ensures that we don't set DECL_ASSEMBLER_NAME before it's absolutely
necessary, which in turn allows us time to call java_mark_class_local.
Which will in turn set bits that will in fact *change* the mangling
for CNI methods.

This fixes PR 21692 on Alpha.  It merely exposes a follow-on problem
for ia64 and ppc64.

Tested on alphaev6 and i686 linux.  Tested on ia64 linux too; it 
doesn't cause any new regressions, but it doesn't help either.

Ok?



r~



cp/
	* cp-tree.h (make_alias_for): Declare.
	* decl2.c (build_java_method_aliases): New.
	(cp_finish_file): Call it.
	* method.c (make_alias_for): Split out from ...
	(make_alias_for_thunk): ... here.

java/
	* Make-lang.in (java/mangle.o): Depend on LANGHOOKS_DEF_H.
	* class.c (build_class_ref): Set DECL_CLASS_FIELD_P and
	DECL_CONTEXT; avoid pushdecl_top_level.
	(build_dtable_decl): Set DECL_VTABLE_P and DECL_CONTEXT.
	(layout_class): Don't SET_DECL_ASSEMBLER_NAME.
	(layout_class_method): Likewise.
	* decl.c (java_mark_cni_decl_local): New.
	(java_mark_class_local): Use it.
	* java-tree.h (DECL_LOCAL_CNI_METHOD_P): New.
	(DECL_CLASS_FIELD_P, DECL_VTABLE_P): New.
	(struct lang_decl_func): Add local_cni;
	(struct lang_decl_var): Add class_field, vtable.
	(java_mangle_decl): Declare.
	* lang.c (LANG_HOOKS_SET_DECL_ASSEMBLER_NAME): New.
	* mangle.c: Remove dup obstack.h; include langhooks-def.h.
	(mangle_obstack_1): New.
	(java_mangle_decl): Remove obstack argument.  Call mangle_class_field,
	mangle_vtable, and mangle_local_cni_method_decl.  Fall back to 
	lhd_set_decl_assembler_name for things that don't need mangling.
	(mangle_class_field): Rename from java_mangle_class_field, make
	static, don't call init_mangling or finish_mangling.
	(mangle_vtable): Similarly.
	(mangle_local_cni_method_decl): New.
	(init_mangling): Remove obstack argument.  Use &mangle_obstack_1,
	gcc_assert, and MANGLE_RAW_STRING.
	(finish_mangling): Use gcc_assert, remove if 0 debugging code.

Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1137
diff -u -p -d -r1.1137 cp-tree.h
--- cp/cp-tree.h	17 May 2005 20:04:58 -0000	1.1137
+++ cp/cp-tree.h	24 May 2005 20:46:53 -0000
@@ -3923,6 +3923,7 @@ extern void synthesize_method (tree);
 extern tree implicitly_declare_fn (special_function_kind, tree, bool);
 extern tree lazily_declare_fn (special_function_kind, tree);
 extern tree skip_artificial_parms_for (tree, tree);
+extern tree make_alias_for (tree, tree);
 
 /* In optimize.c */
 extern bool maybe_clone_body (tree);
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.782
diff -u -p -d -r1.782 decl2.c
--- cp/decl2.c	17 May 2005 21:47:13 -0000	1.782
+++ cp/decl2.c	24 May 2005 20:46:54 -0000
@@ -2731,6 +2731,50 @@ cxx_callgraph_analyze_expr (tree *tp, in
   return NULL;
 }
 
+/* Java requires that we be able to reference a local address for a
+   method, and not be confused by PLT entries.  If hidden aliases are
+   supported, emit one for each java function that we've emitted.  */
+
+static void
+build_java_method_aliases (void)
+{
+  struct cgraph_node *node;
+
+#ifndef HAVE_GAS_HIDDEN
+  return;
+#endif
+
+  for (node = cgraph_nodes; node ; node = node->next)
+    {
+      tree fndecl = node->decl;
+
+      if (TREE_ASM_WRITTEN (fndecl)
+	  && DECL_CONTEXT (fndecl)
+	  && TYPE_P (DECL_CONTEXT (fndecl))
+	  && TYPE_FOR_JAVA (DECL_CONTEXT (fndecl))
+	  && TARGET_USE_LOCAL_THUNK_ALIAS_P (fndecl))
+	{
+	  /* Mangle the name in a predictable way; we need to reference
+	     this from a java compiled object file.  */
+	  tree oid, nid, alias;
+	  const char *oname;
+	  char *nname;
+
+	  oid = DECL_ASSEMBLER_NAME (fndecl);
+	  oname = IDENTIFIER_POINTER (oid);
+	  gcc_assert (oname[0] == '_' && oname[1] == 'Z');
+	  nname = ACONCAT (("_ZHA", oname+2, NULL));
+	  nid = get_identifier (nname);
+
+	  alias = make_alias_for (fndecl, nid);
+	  TREE_PUBLIC (alias) = 1;
+	  DECL_VISIBILITY (alias) = VISIBILITY_HIDDEN;
+
+	  assemble_alias (alias, oid);
+	}
+    }
+}
+
 /* This routine is called from the last rule in yyparse ().
    Its job is to create all the code needed to initialize and
    destroy the global aggregates.  We do the destruction
@@ -3062,6 +3106,9 @@ cp_finish_file (void)
     check_global_declarations (VEC_address (tree, pending_statics),
 			       VEC_length (tree, pending_statics));
 
+  /* Generate hidden aliases for Java.  */
+  build_java_method_aliases ();
+
   finish_repo ();
 
   /* The entire file is now complete.  If requested, dump everything
Index: cp/method.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/method.c,v
retrieving revision 1.328
diff -u -p -d -r1.328 method.c
--- cp/method.c	17 May 2005 16:56:29 -0000	1.328
+++ cp/method.c	24 May 2005 20:46:54 -0000
@@ -258,16 +258,10 @@ static GTY (()) int thunk_labelno;
 
 /* Create a static alias to function.  */
 
-static tree
-make_alias_for_thunk (tree function)
+tree
+make_alias_for (tree function, tree newid)
 {
-  tree alias;
-  char buf[256];
-
-  ASM_GENERATE_INTERNAL_LABEL (buf, "LTHUNK", thunk_labelno);
-  thunk_labelno++;
-  alias = build_decl (FUNCTION_DECL, get_identifier (buf),
-		      TREE_TYPE (function));
+  tree alias = build_decl (FUNCTION_DECL, newid, TREE_TYPE (function));
   DECL_LANG_SPECIFIC (alias) = DECL_LANG_SPECIFIC (function);
   cxx_dup_lang_specific_decl (alias);
   DECL_CONTEXT (alias) = NULL;
@@ -296,8 +290,23 @@ make_alias_for_thunk (tree function)
   TREE_USED (alias) = 1;
   SET_DECL_ASSEMBLER_NAME (alias, DECL_NAME (alias));
   TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (alias)) = 1;
+  return alias;
+}
+
+static tree
+make_alias_for_thunk (tree function)
+{
+  tree alias;
+  char buf[256];
+
+  ASM_GENERATE_INTERNAL_LABEL (buf, "LTHUNK", thunk_labelno);
+  thunk_labelno++;
+
+  alias = make_alias_for (function, get_identifier (buf));
+
   if (!flag_syntax_only)
     assemble_alias (alias, DECL_ASSEMBLER_NAME (function));
+
   return alias;
 }
 
Index: java/Make-lang.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Make-lang.in,v
retrieving revision 1.158
diff -u -p -d -r1.158 Make-lang.in
--- java/Make-lang.in	4 May 2005 01:46:40 -0000	1.158
+++ java/Make-lang.in	24 May 2005 20:46:54 -0000
@@ -340,7 +340,7 @@ java/lang.o: java/lang.c $(CONFIG_H) $(J
   toplev.h $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(EXPR_H) diagnostic.h \
   langhooks.h $(LANGHOOKS_DEF_H) gt-java-lang.h opts.h options.h
 java/mangle.o: java/mangle.c $(CONFIG_H) java/jcf.h $(JAVA_TREE_H) $(SYSTEM_H) \
-  coretypes.h $(TM_H) toplev.h $(GGC_H) gt-java-mangle.h
+  coretypes.h $(TM_H) toplev.h $(GGC_H) gt-java-mangle.h $(LANGHOOKS_DEF_H)
 java/mangle_name.o: java/mangle_name.c $(CONFIG_H) java/jcf.h $(JAVA_TREE_H) \
   $(SYSTEM_H) coretypes.h $(TM_H) toplev.h $(GGC_H)
 java/resource.o: java/resource.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
Index: java/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/class.c,v
retrieving revision 1.228
diff -u -p -d -r1.228 class.c
--- java/class.c	24 May 2005 19:21:56 -0000	1.228
+++ java/class.c	24 May 2005 20:46:55 -0000
@@ -968,10 +968,13 @@ build_class_ref (tree type)
 	      DECL_ARTIFICIAL (decl) = 1;
 	      if (is_compiled == 1)
 		DECL_EXTERNAL (decl) = 1;
-	      SET_DECL_ASSEMBLER_NAME (decl, 
-				       java_mangle_class_field
-				       (&temporary_obstack, type));
-	      pushdecl_top_level (decl);
+	      MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
+	      DECL_CLASS_FIELD_P (decl) = 1;
+	      DECL_CONTEXT (decl) = type;
+
+	      /* ??? We want to preserve the DECL_CONTEXT we set just above,
+		 that that means not calling pushdecl_top_level.  */
+	      IDENTIFIER_GLOBAL_VALUE (decl_name) = decl;
 	    }
 	}
       else
@@ -1967,7 +1970,7 @@ is_compiled_class (tree class)
 tree
 build_dtable_decl (tree type)
 {
-  tree dtype;
+  tree dtype, decl;
 
   /* We need to build a new dtable type so that its size is uniquely
      computed when we're dealing with the class for real and not just
@@ -2015,8 +2018,12 @@ build_dtable_decl (tree type)
   else
     dtype = dtable_type;
 
-  return build_decl (VAR_DECL, 
-		     java_mangle_vtable (&temporary_obstack, type), dtype);
+  decl = build_decl (VAR_DECL, get_identifier ("vt$"), dtype);
+  DECL_CONTEXT (decl) = type;
+  MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
+  DECL_VTABLE_P (decl) = 1;
+
+  return decl;
 }
 
 /* Pre-pend the TYPE_FIELDS of THIS_CLASS with a dummy FIELD_DECL for the
@@ -2090,7 +2097,6 @@ void
 layout_class (tree this_class)
 {
   tree super_class = CLASSTYPE_SUPER (this_class);
-  tree field;
 
   class_list = tree_cons (this_class, NULL_TREE, class_list);
   if (CLASS_BEING_LAIDOUT (this_class))
@@ -2138,18 +2144,6 @@ layout_class (tree this_class)
 	push_super_field (this_class, maybe_super_class);
     }
 
-  for (field = TYPE_FIELDS (this_class);
-       field != NULL_TREE;  field = TREE_CHAIN (field))
-    {
-      if (FIELD_STATIC (field))
-	{
-	  /* Set DECL_ASSEMBLER_NAME to something suitably mangled. */
-	  SET_DECL_ASSEMBLER_NAME (field,
-				   java_mangle_decl
-				   (&temporary_obstack, field));
-	}
-    }
-
   layout_type (this_class);
 
   /* Also recursively load/layout any superinterfaces, but only if
@@ -2317,11 +2311,6 @@ layout_class_method (tree this_class, tr
      compiled into this object file.  */
   DECL_EXTERNAL (method_decl) = 1;
 
-  /* This is a good occasion to mangle the method's name */
-  SET_DECL_ASSEMBLER_NAME (method_decl,
-			   java_mangle_decl (&temporary_obstack, 
-					     method_decl));
-
   if (ID_INIT_P (method_name))
     {
       const char *p = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class)));
Index: java/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/decl.c,v
retrieving revision 1.221
diff -u -p -d -r1.221 decl.c
--- java/decl.c	24 May 2005 19:21:59 -0000	1.221
+++ java/decl.c	24 May 2005 20:46:55 -0000
@@ -2133,6 +2133,30 @@ java_mark_decl_local (tree decl)
     make_decl_rtl (decl);
 }
 
+/* Given appropriate target support, G++ will emit hidden aliases for native
+   methods.  Using this hidden name is required for proper operation of
+   _Jv_Method::ncode, but it doesn't hurt to use it everywhere.  Look for
+   proper target support, then mark the method for aliasing.  */
+
+static void
+java_mark_cni_decl_local (tree decl)
+{
+  /* Setting DECL_LOCAL_CNI_METHOD_P changes the behaviour of the mangler.
+     We expect that we should not yet have referenced this decl in a 
+     context that requires it.  Check this invariant even if we don't have
+     support for hidden aliases.  */
+  gcc_assert (!DECL_ASSEMBLER_NAME_SET_P (decl));
+
+#if !defined(HAVE_GAS_HIDDEN) || !defined(ASM_OUTPUT_DEF)
+  return;
+#endif
+
+  DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+  DECL_LOCAL_CNI_METHOD_P (decl) = 1;
+}
+
+/* Use the preceeding two functions and mark all members of the class.  */
+
 void
 java_mark_class_local (tree class)
 {
@@ -2143,8 +2167,13 @@ java_mark_class_local (tree class)
       java_mark_decl_local (t);
 
   for (t = TYPE_METHODS (class); t ; t = TREE_CHAIN (t))
-    if (!METHOD_ABSTRACT (t) && (!METHOD_NATIVE (t) || flag_jni))
-      java_mark_decl_local (t);
+    if (!METHOD_ABSTRACT (t))
+      {
+	if (METHOD_NATIVE (t) && !flag_jni)
+	  java_mark_cni_decl_local (t);
+        else
+	  java_mark_decl_local (t);
+      }
 }
 
 /* Add a statement to a compound_expr.  */
Index: java/java-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/java-tree.h,v
retrieving revision 1.231
diff -u -p -d -r1.231 java-tree.h
--- java/java-tree.h	24 May 2005 19:18:51 -0000	1.231
+++ java/java-tree.h	24 May 2005 20:46:56 -0000
@@ -818,6 +818,9 @@ union lang_tree_node 
 #define DECL_FIXED_CONSTRUCTOR_P(DECL) \
   (DECL_LANG_SPECIFIC(DECL)->u.f.fixed_ctor)
 
+#define DECL_LOCAL_CNI_METHOD_P(NODE) \
+    (DECL_LANG_SPECIFIC (NODE)->u.f.local_cni)
+
 /* A constructor that calls this. */
 #define DECL_INIT_CALLS_THIS(DECL) \
   (DECL_LANG_SPECIFIC(DECL)->u.f.init_calls_this)
@@ -931,6 +934,12 @@ union lang_tree_node 
     (DECL_LANG_SPECIFIC (NODE)->u.v.freed)
 #define LOCAL_SLOT_P(NODE) \
     (DECL_LANG_SPECIFIC (NODE)->u.v.local_slot)
+
+#define DECL_CLASS_FIELD_P(NODE) \
+    (DECL_LANG_SPECIFIC (NODE)->u.v.class_field)
+#define DECL_VTABLE_P(NODE) \
+    (DECL_LANG_SPECIFIC (NODE)->u.v.vtable)
+
 /* Create a DECL_LANG_SPECIFIC if necessary. */
 #define MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC(T)			\
   if (DECL_LANG_SPECIFIC (T) == NULL)				\
@@ -993,7 +1002,8 @@ struct lang_decl_func GTY(())
   unsigned int invisible : 1;	/* Set for methods we generate
 				   internally but which shouldn't be
 				   written to the .class file.  */
-  unsigned int dummy:1;		
+  unsigned int dummy : 1;
+  unsigned int local_cni : 1;	/* Decl needs mangle_local_cni_method.  */
 };
 
 struct treetreehash_entry GTY(())
@@ -1037,6 +1047,8 @@ struct lang_decl_var GTY(())
   unsigned int cif : 1;		/* True: decl is a class initialization flag */
   unsigned int freed : 1;		/* Decl is no longer in scope.  */
   unsigned int local_slot : 1;	/* Decl is a temporary in the stack frame.  */
+  unsigned int class_field : 1; /* Decl needs mangle_class_field.  */
+  unsigned int vtable : 1;	/* Decl needs mangle_vtable.  */
 };
 
 /* This is what 'lang_decl' really points to.  */
@@ -1367,7 +1379,7 @@ extern void init_jcf_parse (void);
 extern void init_src_parse (void);
 
 extern int cxx_keyword_p (const char *, int);
-extern tree java_mangle_decl (struct obstack *, tree);
+extern void java_mangle_decl (tree);
 extern tree java_mangle_class_field (struct obstack *, tree);
 extern tree java_mangle_vtable (struct obstack *, tree);
 extern void append_gpp_mangled_name (const char *, int);
Index: java/lang.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/lang.c,v
retrieving revision 1.171
diff -u -p -d -r1.171 lang.c
--- java/lang.c	4 Apr 2005 15:29:52 -0000	1.171
+++ java/lang.c	24 May 2005 20:46:57 -0000
@@ -213,6 +213,9 @@ struct language_function GTY(())
 #undef LANG_HOOKS_CLEAR_BINDING_STACK
 #define LANG_HOOKS_CLEAR_BINDING_STACK java_clear_binding_stack
 
+#undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME
+#define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME java_mangle_decl
+
 /* Each front end provides its own.  */
 const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
 
Index: java/mangle.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/mangle.c,v
retrieving revision 1.32
diff -u -p -d -r1.32 mangle.c
--- java/mangle.c	22 Oct 2003 18:00:06 -0000	1.32
+++ java/mangle.c	24 May 2005 20:46:57 -0000
@@ -35,11 +35,14 @@ The Free Software Foundation is independ
 #include "java-tree.h"
 #include "obstack.h"
 #include "toplev.h"
-#include "obstack.h"
 #include "ggc.h"
+#include "langhooks-def.h"
 
+static void mangle_class_field (tree);
+static void mangle_vtable (tree);
 static void mangle_field_decl (tree);
 static void mangle_method_decl (tree);
+static void mangle_local_cni_method_decl (tree);
 
 static void mangle_type (tree);
 static void mangle_pointer_type (tree);
@@ -55,15 +58,15 @@ static void set_type_package_list (tree)
 static int  entry_match_pointer_p (tree, int);
 static void emit_compression_string (int);
 
-static void init_mangling (struct obstack *);
+static void init_mangling (void);
 static tree finish_mangling (void);
 static void compression_table_add (tree);
 
 static void mangle_member_name (tree);
 
-/* We use an incoming obstack, always to be provided to the interface
-   functions. */
+static struct obstack mangle_obstack_1;
 struct obstack *mangle_obstack;
+
 #define MANGLE_RAW_STRING(S) \
   obstack_grow (mangle_obstack, (S), sizeof (S)-1)
 
@@ -73,46 +76,75 @@ static GTY(()) tree atms;
 /* This is the mangling interface: a decl, a class field (.class) and
    the vtable. */
 
-tree
-java_mangle_decl (struct obstack *obstack, tree decl)
+void
+java_mangle_decl (tree decl)
 {
-  init_mangling (obstack);
-  switch (TREE_CODE (decl))
+  /* A copy of the check from the beginning of lhd_set_decl_assembler_name.
+     Only FUNCTION_DECLs and VAR_DECLs for variables with static storage
+     duration need a real DECL_ASSEMBLER_NAME.  */
+  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
+	      || (TREE_CODE (decl) == VAR_DECL
+		  && (TREE_STATIC (decl)
+		      || DECL_EXTERNAL (decl)
+		      || TREE_PUBLIC (decl))));
+  
+  /* Mangling only applies to class members.  */
+  if (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
     {
-    case VAR_DECL:
-      mangle_field_decl (decl);
-      break;
-    case FUNCTION_DECL:
-      mangle_method_decl (decl);
-      break;
-    default:
-      internal_error ("can't mangle %s", tree_code_name [TREE_CODE (decl)]);
+      init_mangling ();
+      switch (TREE_CODE (decl))
+	{
+	case VAR_DECL:
+	  if (DECL_LANG_SPECIFIC (decl))
+	    {
+	      if (DECL_CLASS_FIELD_P (decl))
+		{
+		  mangle_class_field (DECL_CONTEXT (decl));
+		  break;
+		}
+	      else if (DECL_VTABLE_P (decl))
+		{
+		  mangle_vtable (DECL_CONTEXT (decl));
+		  break;
+		}
+	    }
+	  mangle_field_decl (decl);
+	  break;
+
+	case FUNCTION_DECL:
+	  if (DECL_LANG_SPECIFIC (decl) && DECL_LOCAL_CNI_METHOD_P (decl))
+	    mangle_local_cni_method_decl (decl);
+	  else
+	    mangle_method_decl (decl);
+	  break;
+
+	default:
+	  gcc_unreachable ();
+	}
+      SET_DECL_ASSEMBLER_NAME (decl, finish_mangling ());
     }
-  return finish_mangling ();
+  else
+    lhd_set_decl_assembler_name (decl);
 }
 
-tree 
-java_mangle_class_field (struct obstack *obstack, tree type)
+/* Beginning of the helper functions */
+
+static void
+mangle_class_field (tree type)
 {
-  init_mangling (obstack);
   mangle_record_type (type, /* for_pointer = */ 0);
   MANGLE_RAW_STRING ("6class$");
   obstack_1grow (mangle_obstack, 'E');
-  return finish_mangling ();
 }
 
-tree
-java_mangle_vtable (struct obstack *obstack, tree type)
+static void
+mangle_vtable (tree type)
 {
-  init_mangling (obstack);
   MANGLE_RAW_STRING ("TV");
   mangle_record_type (type, /* for_pointer = */ 0);
   obstack_1grow (mangle_obstack, 'E');
-  return finish_mangling ();
 }
 
-/* Beginning of the helper functions */
-
 /* This mangles a field decl */
 
 static void
@@ -167,6 +199,18 @@ mangle_method_decl (tree mdecl)
     }
 }
 
+/* This mangles a CNI method for a local class.  If the target supports
+   hidden aliases, then G++ will have generated one for us.  It is the
+   responsibility of java_mark_class_local to check target support, since
+   we need to set DECL_VISIBILITY (or not) much earlier.  */
+
+static void
+mangle_local_cni_method_decl (tree decl)
+{
+  MANGLE_RAW_STRING ("HA");
+  mangle_method_decl (decl);
+}
+
 /* This mangles a member name, like a function name or a field
    name. Handle cases were `name' is a C++ keyword.  Return a nonzero
    value if unicode encoding was required.  */
@@ -585,17 +629,19 @@ compression_table_add (tree type)
 /* Mangling initialization routine.  */
 
 static void
-init_mangling (struct obstack *obstack)
+init_mangling (void)
 {
-  mangle_obstack = obstack;
-  if (!compression_table)
-    compression_table = make_tree_vec (10);
-  else
-    /* Mangling already in progress.  */
-    abort ();
+  if (!mangle_obstack)
+    {
+      mangle_obstack = &mangle_obstack_1;
+      gcc_obstack_init (mangle_obstack);
+    }
+
+  gcc_assert (compression_table == NULL);
+  compression_table = make_tree_vec (10);
 
   /* Mangled name are to be suffixed */
-  obstack_grow (mangle_obstack, "_Z", 2);
+  MANGLE_RAW_STRING ("_Z");
 }
 
 /* Mangling finalization routine. The mangled name is returned as a
@@ -606,18 +652,14 @@ finish_mangling (void)
 {
   tree result;
 
-  if (!compression_table)
-    /* Mangling already finished.  */
-    abort ();
+  gcc_assert (compression_table);
 
   compression_table = NULL_TREE;
   compression_next = 0;
   obstack_1grow (mangle_obstack, '\0');
   result = get_identifier (obstack_base (mangle_obstack));
   obstack_free (mangle_obstack, obstack_base (mangle_obstack));
-#if 0
-  printf ("// %s\n", IDENTIFIER_POINTER (result));
-#endif
+
   return result;
 }
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]