re PR libgcj/21692 (unexpected java.lang.NoClassDefFoundError)
PR libgcj/21692 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. From-SVN: r100171
This commit is contained in:
parent
81fc305201
commit
6de33afa78
|
@ -1,3 +1,12 @@
|
|||
2005-05-25 Richard Henderson <rth@redhat.com>
|
||||
|
||||
PR libgcj/21692
|
||||
* 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.
|
||||
|
||||
2005-05-25 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
|
||||
|
||||
PR c++/21686
|
||||
|
@ -248,8 +257,8 @@
|
|||
|
||||
2005-05-02 Paolo Bonzini <bonzini@gnu.org>
|
||||
|
||||
* semantics.c (finish_call_expr): Call resolve_overloaded_builtin
|
||||
for BUILT_IN_MD built-ins.
|
||||
* semantics.c (finish_call_expr): Call resolve_overloaded_builtin
|
||||
for BUILT_IN_MD built-ins.
|
||||
|
||||
2005-05-02 Michael Matz <matz@suse.de>
|
||||
|
||||
|
@ -310,7 +319,7 @@
|
|||
2005-04-22 Per Bothner <per@bothner.com>
|
||||
|
||||
* decl.c (make_rtl_for_nonlocal_decl): Don't try get_fileinfo if
|
||||
input_filename is NULL, as it is for (say) __PRETTY_FUNCTION__.
|
||||
input_filename is NULL, as it is for (say) __PRETTY_FUNCTION__.
|
||||
|
||||
2005-04-22 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -2731,6 +2731,50 @@ cxx_callgraph_analyze_expr (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
|
|||
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 (("_ZGA", 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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,33 @@
|
|||
2005-05-25 Richard Henderson <rth@redhat.com>
|
||||
|
||||
PR libgcj/21692
|
||||
* 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.
|
||||
|
||||
2005-05-25 DJ Delorie <dj@redhat.com>
|
||||
|
||||
* class.c (set_constant_value): Move warning control from if() to
|
||||
|
|
|
@ -340,7 +340,7 @@ java/lang.o: java/lang.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h input.h \
|
|||
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) \
|
||||
|
|
|
@ -970,10 +970,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
|
||||
|
@ -1969,7 +1972,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
|
||||
|
@ -2017,8 +2020,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
|
||||
|
@ -2092,7 +2099,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))
|
||||
|
@ -2140,18 +2146,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
|
||||
|
@ -2319,11 +2313,6 @@ layout_class_method (tree this_class, tree super_class,
|
|||
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)));
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -35,11 +35,14 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
|
|||
#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 ();
|
||||
}
|
||||
|
||||
tree
|
||||
java_mangle_class_field (struct obstack *obstack, 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)
|
||||
{
|
||||
init_mangling (obstack);
|
||||
MANGLE_RAW_STRING ("TV");
|
||||
mangle_record_type (type, /* for_pointer = */ 0);
|
||||
obstack_1grow (mangle_obstack, 'E');
|
||||
return finish_mangling ();
|
||||
else
|
||||
lhd_set_decl_assembler_name (decl);
|
||||
}
|
||||
|
||||
/* Beginning of the helper functions */
|
||||
|
||||
static void
|
||||
mangle_class_field (tree type)
|
||||
{
|
||||
mangle_record_type (type, /* for_pointer = */ 0);
|
||||
MANGLE_RAW_STRING ("6class$");
|
||||
obstack_1grow (mangle_obstack, 'E');
|
||||
}
|
||||
|
||||
static void
|
||||
mangle_vtable (tree type)
|
||||
{
|
||||
MANGLE_RAW_STRING ("TV");
|
||||
mangle_record_type (type, /* for_pointer = */ 0);
|
||||
obstack_1grow (mangle_obstack, 'E');
|
||||
}
|
||||
|
||||
/* 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 ("GA");
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue