All files with updated copyright when applicable.

2001-01-07  Alexandre Petit-Bianco  <apbianco@cygnus.com>

	All files with updated copyright when applicable.
	* Make-lang.in (JVGENMAIN_OBS): Removed java/mangle.o.
	* class.c (mangle_class_field): Function removed.
	(append_gpp_mangled_type, mangle_static_field, mangle_field): Likewise.
	(utf8_cmp, cxx_keyword_p): Moved to lex.c.
	(build_class_ref): Call `java_mangle_class_field' instead of
	`mangle_class_field.'
	(build_dtable_decl): Rewritten to call `java_mangle_vtable.'
	(layout_class): Call `java_mangle_decl' instead of
	`mangle_static_field.'
	(cxx_keywords): Initialized static array moved to `lex.c.'
	(layout_class_method): Changed leading comment. Simplified to
	call `java_mangle_decl.' Local `ptr' moved in for loop body.
	* decl.c (lang_mark_tree): Mark field `package_list.'
	* java-tree.h (TYPE_PACKAGE_LIST): New macro.
	(struct lang_type): New field `package_list.'
	(unicode_mangling_length): Prototype removed.
	(append_gpp_mangled_name, append_gpp_mangled_classtype,
	emit_unicode_mangled_name): Likewise.
	(cxx_keyword_p): New prototype.
	(java_mangle_decl, java_mangle_class_field,
	java_mangle_class_field_from_string, java_mangle_vtable): Likewise.
	* jcf-parse.c (jcf_parse_source): Constify `file' argument to
	`build_expr_wfl.'
	* jvgenmain.c (main_method_prefix): Global variable removed.
	(main_method_suffix): Likewise.
	(do_mangle_classname): New function.
	(main): Call it. Format changed to accomodate new mangling scheme.
	* lex.c: (utf8_cmp): Conditionally prototyped.
	(cxx_keywords): Moved from class.c, conditionally defined.
	(utf8_cmp, cxx_keyword_p): Likewise.
	* mangle.c (obstack.h, ggc.h): Included.
	(mangle_field_decl): New function.
	(mangle_method_decl, mangle_type, mangle_pointer_type,
	mangle_array_type, mangle_record_type,
	find_compression_pointer_match, find_compression_array_match,
	find_compression_record_match,
	find_compression_array_template_match, set_type_package_list,
	entry_match_pointer_p, emit_compression_string, init_mangling,
	finish_mangling, compression_table_add, mangle_member_name): Likewise.
	(mangle_obstack): New global.
	(MANGLE_RAW_STRING): New macro.
	(unicode_mangling_length): Turned static.
	(append_unicode_mangled_name): Renamed from
	`emit_unicode_mangled_name.'  Turned static. `mangle_obstack'
	replaces `obstack', removed from the parameter list.
	(append_gpp_mangled_name): Turned static. `mangle_obstack'
	replaces parameter `obstack', removed from the parameter list. Call
	`append_unicode_mangled_name' instead of `emit_unicode_mangled_name.
	(append_gpp_mangled_classtype): Removed.
	(compression_table, compression_next): New static variables.
	* parse.y (temporary_obstack): Extern declaration removed.

(This is the new C++ ABI compatibility patch:
  http://gcc.gnu.org/ml/gcc-patches/2001-01/msg01225.html)

From-SVN: r39031
This commit is contained in:
Alexandre Petit-Bianco 2001-01-15 08:01:22 +00:00 committed by Alexandre Petit-Bianco
parent b9333bff58
commit dc08e60389
10 changed files with 872 additions and 410 deletions

View File

@ -70,6 +70,61 @@
(not_accessible_p): Grant `private' access from within
enclosing contexts.
2001-01-07 Alexandre Petit-Bianco <apbianco@cygnus.com>
All files with updated copyright when applicable.
* Make-lang.in (JVGENMAIN_OBS): Removed java/mangle.o.
* class.c (mangle_class_field): Function removed.
(append_gpp_mangled_type, mangle_static_field, mangle_field): Likewise.
(utf8_cmp, cxx_keyword_p): Moved to lex.c.
(build_class_ref): Call `java_mangle_class_field' instead of
`mangle_class_field.'
(build_dtable_decl): Rewritten to call `java_mangle_vtable.'
(layout_class): Call `java_mangle_decl' instead of
`mangle_static_field.'
(cxx_keywords): Initialized static array moved to `lex.c.'
(layout_class_method): Changed leading comment. Simplified to
call `java_mangle_decl.' Local `ptr' moved in for loop body.
* decl.c (lang_mark_tree): Mark field `package_list.'
* java-tree.h (TYPE_PACKAGE_LIST): New macro.
(struct lang_type): New field `package_list.'
(unicode_mangling_length): Prototype removed.
(append_gpp_mangled_name, append_gpp_mangled_classtype,
emit_unicode_mangled_name): Likewise.
(cxx_keyword_p): New prototype.
(java_mangle_decl, java_mangle_class_field,
java_mangle_class_field_from_string, java_mangle_vtable): Likewise.
* jcf-parse.c (jcf_parse_source): Constify `file' argument to
`build_expr_wfl.'
* jvgenmain.c (main_method_prefix): Global variable removed.
(main_method_suffix): Likewise.
(do_mangle_classname): New function.
(main): Call it. Format changed to accomodate new mangling scheme.
* lex.c: (utf8_cmp): Conditionally prototyped.
(cxx_keywords): Moved from class.c, conditionally defined.
(utf8_cmp, cxx_keyword_p): Likewise.
* mangle.c (obstack.h, ggc.h): Included.
(mangle_field_decl): New function.
(mangle_method_decl, mangle_type, mangle_pointer_type,
mangle_array_type, mangle_record_type,
find_compression_pointer_match, find_compression_array_match,
find_compression_record_match,
find_compression_array_template_match, set_type_package_list,
entry_match_pointer_p, emit_compression_string, init_mangling,
finish_mangling, compression_table_add, mangle_member_name): Likewise.
(mangle_obstack): New global.
(MANGLE_RAW_STRING): New macro.
(unicode_mangling_length): Turned static.
(append_unicode_mangled_name): Renamed from
`emit_unicode_mangled_name.' Turned static. `mangle_obstack'
replaces `obstack', removed from the parameter list.
(append_gpp_mangled_name): Turned static. `mangle_obstack'
replaces parameter `obstack', removed from the parameter list. Call
`append_unicode_mangled_name' instead of `emit_unicode_mangled_name.
(append_gpp_mangled_classtype): Removed.
(compression_table, compression_next): New static variables.
* parse.y (temporary_obstack): Extern declaration removed.
2001-01-05 Alexandre Petit-Bianco <apbianco@cygnus.com>
* parse.y (patch_binop): Compute missing type in error situations.

View File

@ -1,6 +1,6 @@
# Top level makefile fragment for the GNU compiler for the Java(TM)
# language.
# Copyright (C) 1996, 1998, 1999, 2000 Free Software Foundation, Inc.
# Copyright (C) 1996, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
#This file is part of GNU CC.
@ -111,7 +111,7 @@ JVSCAN_OBJS = java/parse-scan.o java/jv-scan.o version.o
JCFDUMP_OBJS = java/jcf-dump.o java/jcf-io.o java/jcf-depend.o java/jcf-path.o \
java/zextract.o errors.o version.o mkdeps.o
JVGENMAIN_OBJS = java/jvgenmain.o java/mangle.o
JVGENMAIN_OBJS = java/jvgenmain.o
# Use loose warnings for this front end.
java-warn =

View File

@ -37,25 +37,18 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "parse.h"
#include "ggc.h"
static tree mangle_class_field PARAMS ((tree class));
static tree make_method_value PARAMS ((tree));
static tree build_java_method_type PARAMS ((tree, tree, int));
static int32 hashUtf8String PARAMS ((const char *, int));
static tree make_field_value PARAMS ((tree));
static tree get_dispatch_vector PARAMS ((tree));
static tree get_dispatch_table PARAMS ((tree, tree));
static void append_gpp_mangled_type PARAMS ((struct obstack *, tree));
static tree mangle_static_field PARAMS ((tree));
static void add_interface_do PARAMS ((tree, tree, int));
static tree maybe_layout_super_class PARAMS ((tree, tree));
static int assume_compiled PARAMS ((const char *));
static struct hash_entry *init_test_hash_newfunc PARAMS ((struct hash_entry *,
struct hash_table *,
hash_table_key));
static int utf8_cmp PARAMS ((const unsigned char *, int, const char *));
static int cxx_keyword_p PARAMS ((const char *, int));
static tree mangle_field PARAMS ((tree, tree));
static rtx registerClass_libfunc;
extern struct obstack permanent_obstack;
@ -890,7 +883,8 @@ build_class_ref (type)
TREE_PUBLIC (decl) = 1;
DECL_IGNORED_P (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
DECL_ASSEMBLER_NAME (decl) = mangle_class_field (type);
DECL_ASSEMBLER_NAME (decl) =
java_mangle_class_field (&temporary_obstack, type);
make_decl_rtl (decl, NULL);
pushdecl_top_level (decl);
if (is_compiled == 1)
@ -1545,147 +1539,13 @@ is_compiled_class (class)
return 0;
}
/* Append the mangled name of TYPE onto OBSTACK. */
static void
append_gpp_mangled_type (obstack, type)
struct obstack *obstack;
tree type;
{
switch (TREE_CODE (type))
{
char code;
case BOOLEAN_TYPE: code = 'b'; goto primitive;
case CHAR_TYPE: code = 'w'; goto primitive;
case VOID_TYPE: code = 'v'; goto primitive;
case INTEGER_TYPE:
/* Get the original type instead of the arguments promoted type.
Avoid symbol name clashes. Should call a function to do that.
FIXME. */
if (type == promoted_short_type_node)
type = short_type_node;
if (type == promoted_byte_type_node)
type = byte_type_node;
switch (TYPE_PRECISION (type))
{
case 8: code = 'c'; goto primitive;
case 16: code = 's'; goto primitive;
case 32: code = 'i'; goto primitive;
case 64: code = 'x'; goto primitive;
default: goto bad_type;
}
primitive:
obstack_1grow (obstack, code);
break;
case REAL_TYPE:
switch (TYPE_PRECISION (type))
{
case 32: code = 'f'; goto primitive;
case 64: code = 'd'; goto primitive;
default: goto bad_type;
}
case POINTER_TYPE:
type = TREE_TYPE (type);
obstack_1grow (obstack, 'P');
case RECORD_TYPE:
if (TYPE_ARRAY_P (type))
{
obstack_grow (obstack, "t6JArray1Z", sizeof("t6JArray1Z")-1);
append_gpp_mangled_type (obstack, TYPE_ARRAY_ELEMENT (type));
}
else
{
const char *class_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
append_gpp_mangled_classtype (obstack, class_name);
}
break;
bad_type:
default:
fatal ("internal error - trying to mangle unknown type");
}
}
/* Build the mangled name of a field, given the class name and the
field name. */
static tree
mangle_field (class, name)
tree class, name;
{
int encoded_len;
#if ! defined (NO_DOLLAR_IN_LABEL) || ! defined (NO_DOT_IN_LABEL)
obstack_1grow (&temporary_obstack, '_');
#else
obstack_grow (&temporary_obstack, "__static_", 9);
#endif
append_gpp_mangled_type (&temporary_obstack, class);
encoded_len = unicode_mangling_length (IDENTIFIER_POINTER (name),
IDENTIFIER_LENGTH (name));
if (encoded_len > 0)
{
obstack_1grow (&temporary_obstack, 'U');
}
#ifndef NO_DOLLAR_IN_LABEL
obstack_1grow (&temporary_obstack, '$');
#else /* NO_DOLLAR_IN_LABEL */
#ifndef NO_DOT_IN_LABEL
obstack_1grow (&temporary_obstack, '.');
#else /* NO_DOT_IN_LABEL */
obstack_1grow (&temporary_obstack, '_');
#endif /* NO_DOT_IN_LABEL */
#endif /* NO_DOLLAR_IN_LABEL */
if (encoded_len > 0)
{
emit_unicode_mangled_name (&temporary_obstack,
IDENTIFIER_POINTER (name),
IDENTIFIER_LENGTH (name));
}
else
{
obstack_grow (&temporary_obstack,
IDENTIFIER_POINTER (name),
IDENTIFIER_LENGTH (name));
}
/* Mangle C++ keywords by appending a `$'. */
/* FIXME: NO_DOLLAR_IN_LABEL */
if (cxx_keyword_p (IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name)))
obstack_grow (&temporary_obstack, "$", 1);
obstack_1grow (&temporary_obstack, '\0');
name = get_identifier (obstack_base (&temporary_obstack));
obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
return name;
}
/* Build the mangled name of the `class' field. */
static tree
mangle_class_field (class)
tree class;
{
/* We know that we can use `class$' to mangle the class object,
because `class' is a reserved word in Java and thus can't appear
as a field or method name. */
return mangle_field (class, get_identifier ("class$"));
}
/* Build the mangled (assembly-level) name of the static field FIELD. */
static tree
mangle_static_field (field)
tree field;
{
return mangle_field (DECL_CONTEXT (field), DECL_NAME (field));
}
/* Build a VAR_DECL for the dispatch table (vtable) for class TYPE. */
tree
build_dtable_decl (type)
tree type;
{
tree name, dtype;
tree dtype;
/* 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
@ -1706,12 +1566,8 @@ build_dtable_decl (type)
else
dtype = dtable_type;
obstack_grow (&temporary_obstack, "__vt_", 5);
append_gpp_mangled_type (&temporary_obstack, type);
obstack_1grow (&temporary_obstack, '\0');
name = get_identifier (obstack_base (&temporary_obstack));
obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
return build_decl (VAR_DECL, name, dtype);
return build_decl (VAR_DECL,
java_mangle_vtable (&temporary_obstack, type), dtype);
}
/* Pre-pend the TYPE_FIELDS of THIS_CLASS with a dummy FIELD_DECL for the
@ -1836,7 +1692,8 @@ layout_class (this_class)
if (FIELD_STATIC (field))
{
/* Set DECL_ASSEMBLER_NAME to something suitably mangled. */
DECL_ASSEMBLER_NAME (field) = mangle_static_field (field);
DECL_ASSEMBLER_NAME (field) =
java_mangle_decl (&temporary_obstack, field);
}
}
@ -1916,218 +1773,38 @@ layout_class_methods (this_class)
#endif
}
/* A sorted list of all C++ keywords. */
static const char *cxx_keywords[] =
{
"asm",
"auto",
"bool",
"const_cast",
"delete",
"dynamic_cast",
"enum",
"explicit",
"extern",
"friend",
"inline",
"mutable",
"namespace",
"overload",
"register",
"reinterpret_cast",
"signed",
"sizeof",
"static_cast",
"struct",
"template",
"typedef",
"typeid",
"typename",
"typenameopt",
"union",
"unsigned",
"using",
"virtual",
"volatile",
"wchar_t"
};
/* Return 0 if NAME is equal to STR, -1 if STR is "less" than NAME,
and 1 if STR is "greater" than NAME. */
static int
utf8_cmp (str, length, name)
const unsigned char *str;
int length;
const char *name;
{
const unsigned char *limit = str + length;
int i;
for (i = 0; name[i]; ++i)
{
int ch = UTF8_GET (str, limit);
if (ch != name[i])
return ch - name[i];
}
return str == limit ? 0 : 1;
}
/* Return true if NAME is a C++ keyword. */
static int
cxx_keyword_p (name, length)
const char *name;
int length;
{
int last = ARRAY_SIZE (cxx_keywords);
int first = 0;
int mid = (last + first) / 2;
int old = -1;
for (mid = (last + first) / 2;
mid != old;
old = mid, mid = (last + first) / 2)
{
int kwl = strlen (cxx_keywords[mid]);
int min_length = kwl > length ? length : kwl;
int r = utf8_cmp (name, min_length, cxx_keywords[mid]);
if (r == 0)
{
int i;
/* We've found a match if all the remaining characters are
`$'. */
for (i = min_length; i < length && name[i] == '$'; ++i)
;
if (i == length)
return 1;
r = 1;
}
if (r < 0)
last = mid;
else
first = mid;
}
return 0;
}
/* Lay METHOD_DECL out, returning a possibly new value of
DTABLE_COUNT. */
DTABLE_COUNT. Also mangle the method's name. */
tree
layout_class_method (this_class, super_class, method_decl, dtable_count)
tree this_class, super_class, method_decl, dtable_count;
{
const char *ptr;
char *asm_name;
tree arg, arglist, t;
int method_name_needs_escapes = 0;
tree method_name = DECL_NAME (method_decl);
int method_name_is_wfl =
(TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION);
if (method_name_is_wfl)
method_name = java_get_real_method_name (method_decl);
if (!ID_INIT_P (method_name) && !ID_FINIT_P (method_name))
{
int encoded_len
= unicode_mangling_length (IDENTIFIER_POINTER (method_name),
IDENTIFIER_LENGTH (method_name));
if (encoded_len > 0)
{
method_name_needs_escapes = 1;
emit_unicode_mangled_name (&temporary_obstack,
IDENTIFIER_POINTER (method_name),
IDENTIFIER_LENGTH (method_name));
}
else
{
obstack_grow (&temporary_obstack,
IDENTIFIER_POINTER (method_name),
IDENTIFIER_LENGTH (method_name));
}
/* Mangle C++ keywords by appending a `$'. */
/* FIXME: NO_DOLLAR_IN_LABEL */
if (cxx_keyword_p (IDENTIFIER_POINTER (method_name),
IDENTIFIER_LENGTH (method_name)))
obstack_grow (&temporary_obstack, "$", 1);
}
obstack_grow (&temporary_obstack, "__", 2);
if (ID_FINIT_P (method_name))
obstack_grow (&temporary_obstack, "finit", 5);
append_gpp_mangled_type (&temporary_obstack, this_class);
TREE_PUBLIC (method_decl) = 1;
t = TREE_TYPE (method_decl);
arglist = TYPE_ARG_TYPES (t);
if (TREE_CODE (t) == METHOD_TYPE)
arglist = TREE_CHAIN (arglist);
for (arg = arglist; arg != end_params_node; )
{
tree a = arglist;
tree argtype = TREE_VALUE (arg);
int tindex = 1;
if (TREE_CODE (argtype) == POINTER_TYPE)
{
/* This is O(N**2). Do we care? Cfr gcc/cp/method.c. */
while (a != arg && argtype != TREE_VALUE (a))
a = TREE_CHAIN (a), tindex++;
}
else
a = arg;
if (a != arg)
{
char buf[12];
int nrepeats = 0;
do
{
arg = TREE_CHAIN (arg); nrepeats++;
}
while (arg != end_params_node && argtype == TREE_VALUE (arg));
if (nrepeats > 1)
{
obstack_1grow (&temporary_obstack, 'N');
sprintf (buf, "%d", nrepeats);
obstack_grow (&temporary_obstack, buf, strlen (buf));
if (nrepeats > 9)
obstack_1grow (&temporary_obstack, '_');
}
else
obstack_1grow (&temporary_obstack, 'T');
sprintf (buf, "%d", tindex);
obstack_grow (&temporary_obstack, buf, strlen (buf));
if (tindex > 9)
obstack_1grow (&temporary_obstack, '_');
}
else
{
append_gpp_mangled_type (&temporary_obstack, argtype);
arg = TREE_CHAIN (arg);
}
}
if (method_name_needs_escapes)
obstack_1grow (&temporary_obstack, 'U');
obstack_1grow (&temporary_obstack, '\0');
asm_name = obstack_finish (&temporary_obstack);
DECL_ASSEMBLER_NAME (method_decl) = get_identifier (asm_name);
/* This is a good occasion to mangle the method's name */
DECL_ASSEMBLER_NAME (method_decl) =
java_mangle_decl (&temporary_obstack, method_decl);
/* We don't generate a RTL for the method if it's abstract, or if
it's an interface method that isn't clinit. */
if (! METHOD_ABSTRACT (method_decl)
|| (CLASS_INTERFACE (TYPE_NAME (this_class))
&& (DECL_CLINIT_P (method_decl))))
make_decl_rtl (method_decl, NULL);
obstack_free (&temporary_obstack, asm_name);
if (ID_INIT_P (method_name))
{
const char *p = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class)));
const char *ptr;
for (ptr = p; *ptr; )
{
if (*ptr++ == '.')
@ -2153,16 +1830,6 @@ layout_class_method (this_class, super_class, method_decl, dtable_count)
&& !CLASS_FROM_SOURCE_P (this_class))
error_with_decl (method_decl,
"non-static method '%s' overrides static method");
#if 0
else if (TREE_TYPE (TREE_TYPE (method_decl))
!= TREE_TYPE (TREE_TYPE (super_method)))
{
error_with_decl (method_decl,
"Method `%s' redefined with different return type");
error_with_decl (super_method,
"Overridden decl is here");
}
#endif
}
else if (! METHOD_FINAL (method_decl)
&& ! METHOD_PRIVATE (method_decl)

View File

@ -1939,6 +1939,7 @@ lang_mark_tree (t)
ggc_mark_tree (lt->clinit_stmt_list);
ggc_mark_tree (lt->ii_block);
ggc_mark_tree (lt->dot_class);
ggc_mark_tree (lt->package_list);
}
}
}

View File

@ -1,6 +1,6 @@
/* Definitions for parsing and type checking for the GNU compiler for
the Java(TM) language.
Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -892,6 +892,7 @@ struct lang_decl_var
/* The decl of the synthetic method `class$' used to handle `.class'
for non primitive types when compiling to bytecode. */
#define TYPE_DOT_CLASS(T) (TYPE_LANG_SPECIFIC(T)->dot_class)
#define TYPE_PACKAGE_LIST(T) (TYPE_LANG_SPECIFIC(T)->package_list)
#define TYPE_PRIVATE_INNER_CLASS(T) (TYPE_LANG_SPECIFIC(T)->pic)
#define TYPE_PROTECTED_INNER_CLASS(T) (TYPE_LANG_SPECIFIC(T)->poic)
#define TYPE_HAS_FINAL_VARIABLE(T) (TYPE_LANG_SPECIFIC(T)->afv)
@ -909,6 +910,7 @@ struct lang_type
needs to be invoked and generated when
compiling to bytecode to implement
<non_primitive_type>.class */
tree package_list; /* List of package names, progressive */
unsigned pic:1; /* Private Inner Class. */
unsigned poic:1; /* Protected Inner Class. */
unsigned afv:1; /* Has final variables */
@ -1042,7 +1044,6 @@ extern void check_for_initialization PARAMS ((tree));
extern tree pushdecl_top_level PARAMS ((tree));
extern int alloc_class_constant PARAMS ((tree));
extern int unicode_mangling_length PARAMS ((const char *, int));
extern void init_expr_processing PARAMS ((void));
extern void push_super_field PARAMS ((tree, tree));
extern void init_class_processing PARAMS ((void));
@ -1060,9 +1061,6 @@ extern int push_type_0 PARAMS ((tree));
extern void push_type PARAMS ((tree));
extern void load_type_state PARAMS ((tree));
extern void add_interface PARAMS ((tree, tree));
extern void append_gpp_mangled_name PARAMS ((struct obstack *, const char *, int));
extern void append_gpp_mangled_classtype PARAMS ((struct obstack *, const char *));
extern void emit_unicode_mangled_name PARAMS ((struct obstack *, const char *, int));
extern tree force_evaluation_order PARAMS ((tree));
extern int verify_constant_pool PARAMS ((struct JCF *));
extern void start_java_method PARAMS ((tree));
@ -1111,6 +1109,12 @@ extern boolean java_hash_compare_tree_node PARAMS ((hash_table_key,
hash_table_key));
extern void java_check_methods PARAMS ((tree));
extern void init_jcf_parse PARAMS((void));
extern int cxx_keyword_p PARAMS ((const char *, int));
extern tree java_mangle_decl PARAMS ((struct obstack *, tree));
extern tree java_mangle_class_field PARAMS ((struct obstack *, tree));
extern tree java_mangle_class_field_from_string PARAMS ((struct obstack *, char *));
extern tree java_mangle_vtable PARAMS ((struct obstack *, tree));
extern const char *lang_printable_name_wls PARAMS ((tree, int));
/* We use ARGS_SIZE_RTX to indicate that gcc/expr.h has been included

View File

@ -1,5 +1,5 @@
/* Parser for Java(TM) .class files.
Copyright (C) 1996, 1998, 1999, 2000 Free Software Foundation, Inc.
Copyright (C) 1996, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of GNU CC.

View File

@ -1,5 +1,5 @@
/* Program to generate "main" a Java(TM) class containing a main method.
Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -32,8 +32,8 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "tree.h"
#include "java-tree.h"
const char main_method_prefix[] = "main__";
const char main_method_suffix[] = "Pt6JArray1ZPQ34java4lang6String";
static char * do_mangle_classname PARAMS ((const char *string));
const char class_mangling_suffix[] = "class$";
struct obstack name_obstack;
@ -116,9 +116,7 @@ main (int argc, const char **argv)
classname = argv[i];
gcc_obstack_init (&name_obstack);
append_gpp_mangled_classtype (&name_obstack, classname);
obstack_1grow (&name_obstack, '\0');
mangled_classname = obstack_finish (&name_obstack);
mangled_classname = do_mangle_classname (classname);
if (i < argc - 1 && strcmp (argv[i + 1], "-") != 0)
{
@ -155,13 +153,8 @@ main (int argc, const char **argv)
}
fprintf (stream, " 0\n};\n\n");
#ifndef NO_DOLLAR_IN_LABEL
fprintf (stream, "extern int class __attribute__ ((alias (\"_%s$%s\")));\n",
mangled_classname, class_mangling_suffix);
#else
fprintf (stream, "extern int class __attribute__ ((alias (\"_%s.%s\")));\n",
mangled_classname, class_mangling_suffix);
#endif
fprintf (stream, "extern int class __attribute__ ((alias (\"%s\")));\n",
mangled_classname);
fprintf (stream, "int main (int argc, const char **argv)\n");
fprintf (stream, "{\n");
fprintf (stream, " _Jv_Compiler_Properties = props;\n");
@ -175,3 +168,36 @@ main (int argc, const char **argv)
}
return 0;
}
static char *
do_mangle_classname (string)
const char *string;
{
char *ptr;
int count = 0;
#define MANGLE_NAME() \
{ \
char buffer [128]; \
sprintf (buffer, "%d", count); \
obstack_grow (&name_obstack, buffer, strlen (buffer)); \
obstack_grow (&name_obstack, & ptr [-count], count); \
count = 0; \
}
obstack_grow (&name_obstack, "_ZN", 3);
for (ptr = (char *)string; *ptr; ptr++ )
{
if (ptr[0] == '.')
{
MANGLE_NAME ();
}
else
count++;
}
MANGLE_NAME ();
obstack_grow0 (&name_obstack, "6class$E", 8);
return obstack_finish (&name_obstack);
}

View File

@ -1,5 +1,5 @@
/* Language lexer for the GNU compiler for the Java(TM) language.
Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
This file is part of GNU CC.
@ -61,6 +61,10 @@ static int java_read_char PARAMS ((java_lexer *));
static void java_allocate_new_line PARAMS ((void));
static void java_unget_unicode PARAMS ((void));
static unicode_t java_sneak_unicode PARAMS ((void));
#ifndef JC1_LITE
static int utf8_cmp PARAMS ((const unsigned char *, int, const char *));
#endif
java_lexer *java_new_lexer PARAMS ((FILE *, const char *));
/* This is nonzero if we have initialized `need_byteswap'. */
@ -1763,3 +1767,101 @@ java_get_line_col (filename, line, col)
return obstack_finish (&temporary_obstack);
#endif
}
#ifndef JC1_LITE
static int
utf8_cmp (str, length, name)
const unsigned char *str;
int length;
const char *name;
{
const unsigned char *limit = str + length;
int i;
for (i = 0; name[i]; ++i)
{
int ch = UTF8_GET (str, limit);
if (ch != name[i])
return ch - name[i];
}
return str == limit ? 0 : 1;
}
/* A sorted list of all C++ keywords. */
static const char *cxx_keywords[] =
{
"asm",
"auto",
"bool",
"const_cast",
"delete",
"dynamic_cast",
"enum",
"explicit",
"extern",
"friend",
"inline",
"mutable",
"namespace",
"overload",
"register",
"reinterpret_cast",
"signed",
"sizeof",
"static_cast",
"struct",
"template",
"typedef",
"typeid",
"typename",
"typenameopt",
"union",
"unsigned",
"using",
"virtual",
"volatile",
"wchar_t"
};
/* Return true if NAME is a C++ keyword. */
int
cxx_keyword_p (name, length)
const char *name;
int length;
{
int last = ARRAY_SIZE (cxx_keywords);
int first = 0;
int mid = (last + first) / 2;
int old = -1;
for (mid = (last + first) / 2;
mid != old;
old = mid, mid = (last + first) / 2)
{
int kwl = strlen (cxx_keywords[mid]);
int min_length = kwl > length ? length : kwl;
int r = utf8_cmp (name, min_length, cxx_keywords[mid]);
if (r == 0)
{
int i;
/* We've found a match if all the remaining characters are
`$'. */
for (i = min_length; i < length && name[i] == '$'; ++i)
;
if (i == length)
return 1;
r = 1;
}
if (r < 0)
last = mid;
else
first = mid;
}
return 0;
}
#endif /* JC1_LITE */

View File

@ -1,6 +1,6 @@
/* Functions related to mangling class names for the GNU compiler
for the Java(TM) language.
Copyright (C) 1998, 1999 Free Software Foundation, Inc.
Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -32,12 +32,211 @@ 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"
static void mangle_field_decl PARAMS ((tree));
static void mangle_method_decl PARAMS ((tree));
static void mangle_type PARAMS ((tree));
static void mangle_pointer_type PARAMS ((tree));
static void mangle_array_type PARAMS ((tree));
static int mangle_record_type PARAMS ((tree, int));
static int find_compression_pointer_match PARAMS ((tree));
static int find_compression_array_match PARAMS ((tree));
static int find_compression_record_match PARAMS ((tree, tree *));
static int find_compression_array_template_match PARAMS ((tree));
static void set_type_package_list PARAMS ((tree));
static int entry_match_pointer_p PARAMS ((tree, int));
static void emit_compression_string PARAMS ((int));
static void init_mangling PARAMS ((struct obstack *));
static tree finish_mangling PARAMS ((void));
static void compression_table_add PARAMS ((tree));
static void append_unicode_mangled_name PARAMS ((const char *, int));
static void append_gpp_mangled_name PARAMS ((const char *, int));
static int unicode_mangling_length PARAMS ((const char *, int));
static int mangle_member_name PARAMS ((tree));
/* We use an incoming obstack, always to be provided to the interface
functions. */
struct obstack *mangle_obstack;
#define MANGLE_RAW_STRING(S) \
obstack_grow (mangle_obstack, (S), sizeof (S)-1)
/* This is the mangling interface: a decl, a class field (.class) and
the vtable. */
tree
java_mangle_decl (obstack, decl)
struct obstack *obstack;
tree decl;
{
init_mangling (obstack);
switch (TREE_CODE (decl))
{
case VAR_DECL:
mangle_field_decl (decl);
break;
case FUNCTION_DECL:
mangle_method_decl (decl);
break;
default:
fatal ("Can't mangle `%s\' -- java_mangle_decl",
tree_code_name [TREE_CODE (decl)]);
}
return finish_mangling ();
}
tree
java_mangle_class_field (obstack, type)
struct obstack *obstack;
tree type;
{
init_mangling (obstack);
mangle_record_type (type, /* from_pointer = */ 0);
MANGLE_RAW_STRING ("6class$");
obstack_1grow (mangle_obstack, 'E');
return finish_mangling ();
}
tree
java_mangle_vtable (obstack, type)
struct obstack *obstack;
tree type;
{
init_mangling (obstack);
MANGLE_RAW_STRING ("TV");
mangle_record_type (type, /* from_pointer = */ 0);
obstack_1grow (mangle_obstack, 'E');
return finish_mangling ();
}
/* Beginning of the helper functions */
/* This mangles a field decl */
static void
mangle_field_decl (decl)
tree decl;
{
tree name = DECL_NAME (decl);
int field_name_needs_escapes = 0;
/* Mangle the name of the this the field belongs to */
mangle_record_type (DECL_CONTEXT (decl), /* from_pointer = */ 0);
/* Mangle the name of the field */
field_name_needs_escapes = mangle_member_name (name);
/* Terminate the mangled name */
obstack_1grow (mangle_obstack, 'E');
if (field_name_needs_escapes)
obstack_1grow (mangle_obstack, 'U');
}
/* This mangles a method decl, first mangling its name and then all
its arguments. */
static void
mangle_method_decl (mdecl)
tree mdecl;
{
tree method_name = DECL_NAME (mdecl);
tree arglist;
int method_name_needs_escapes = 0;
/* Mangle the name of the type that contains mdecl */
mangle_record_type (DECL_CONTEXT (mdecl), /* from_pointer = */ 0);
/* Before working on the method name, get to it. It might be burried
in a WFL. */
if (TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION)
method_name = java_get_real_method_name (mdecl);
/* Mangle the function name. There three cases
- mdecl is java.lang.Object.Object(), use `C2' for its name
(denotes a base object constructor.)
- mdecl is a constructor, use `C1' for its name, (denotes a
complete object constructor.)
- mdecl is not a constructor, standard mangling is performed.
We terminate the mangled function name with a `E'. */
if (ID_INIT_P (method_name))
{
if (DECL_CONTEXT (mdecl) == object_type_node)
obstack_grow (mangle_obstack, "C2", 2);
else
obstack_grow (mangle_obstack, "C1", 2);
}
else
method_name_needs_escapes = mangle_member_name (method_name);
obstack_1grow (mangle_obstack, 'E');
/* We mangled type.methodName. Now onto the arguments. */
arglist = TYPE_ARG_TYPES (TREE_TYPE (mdecl));
if (TREE_CODE (TREE_TYPE (mdecl)) == METHOD_TYPE)
arglist = TREE_CHAIN (arglist);
/* No arguments is easy. We shortcut it. */
if (arglist == end_params_node)
obstack_1grow (mangle_obstack, 'v');
else
{
tree arg;
for (arg = arglist; arg != end_params_node; arg = TREE_CHAIN (arg))
mangle_type (TREE_VALUE (arg));
}
/* Terminate the mangled name */
if (method_name_needs_escapes)
obstack_1grow (mangle_obstack, 'U');
}
/* This mangles a member name, like a function name or a field
name. Handle cases were `name' is a C++ keyword. Return a non zero
value if unicode encoding was required. */
static int
mangle_member_name (name)
tree name;
{
const char * name_string = IDENTIFIER_POINTER (name);
int len = IDENTIFIER_LENGTH (name);
int to_return = 0;
if (unicode_mangling_length (name_string, len) > 0)
{
append_unicode_mangled_name (name_string, len);
to_return = 1;
}
else
append_gpp_mangled_name (name_string, len);
/* If NAME happens to be a C++ keyword, add `$' or `.' or `_'. */
if (cxx_keyword_p (IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name)))
{
#ifndef NO_DOLLAR_IN_LABEL
obstack_1grow (mangle_obstack, '$');
#else /* NO_DOLLAR_IN_LABEL */
#ifndef NO_DOT_IN_LABEL
obstack_1grow (mangle_obstack, '.');
#else /* NO_DOT_IN_LABEL */
obstack_1grow (mangle_obstack, '_');
#endif /* NO_DOT_IN_LABEL */
#endif /* NO_DOLLAR_IN_LABEL */
}
return to_return;
}
/* Assuming (NAME, LEN) is a Utf8-encoding string, calculate
the length of the string as mangled (a la g++) including Unicode escapes.
If no escapes are needed, return 0. */
int
static int
unicode_mangling_length (name, len)
const char *name;
int len;
@ -69,9 +268,8 @@ unicode_mangling_length (name, len)
/* Assuming (NAME, LEN) is a Utf8-encoding string, emit the string
appropriately mangled (with Unicode escapes) to OBSTACK. */
void
emit_unicode_mangled_name (obstack, name, len)
struct obstack *obstack;
static void
append_unicode_mangled_name (name, len)
const char *name;
int len;
{
@ -94,11 +292,11 @@ emit_unicode_mangled_name (obstack, name, len)
{
char buf[6];
sprintf (buf, "_%04x", ch);
obstack_grow (obstack, buf, 5);
obstack_grow (mangle_obstack, buf, 5);
}
else
{
obstack_1grow (obstack, ch);
obstack_1grow (mangle_obstack, ch);
}
}
}
@ -106,9 +304,8 @@ emit_unicode_mangled_name (obstack, name, len)
/* Assuming (NAME, LEN) is a Utf8-encoding string, emit the string
appropriately mangled (with Unicode escapes if needed) to OBSTACK. */
void
append_gpp_mangled_name (obstack, name, len)
struct obstack *obstack;
static void
append_gpp_mangled_name (name, len)
const char *name;
int len;
{
@ -118,49 +315,460 @@ append_gpp_mangled_name (obstack, name, len)
if (needs_escapes)
{
sprintf (buf, "U%d", encoded_len);
obstack_grow (obstack, buf, strlen(buf));
emit_unicode_mangled_name (obstack, name, len);
obstack_grow (mangle_obstack, buf, strlen(buf));
append_unicode_mangled_name (name, len);
}
else
{
sprintf (buf, "%d", len);
obstack_grow (obstack, buf, strlen(buf));
obstack_grow (obstack, name, len);
obstack_grow (mangle_obstack, buf, strlen(buf));
obstack_grow (mangle_obstack, name, len);
}
}
/* Append the mangled name of a class named CLASSNAME onto OBSTACK. */
/* Append the mangled name of TYPE onto OBSTACK. */
void
append_gpp_mangled_classtype (obstack, class_name)
struct obstack *obstack;
const char *class_name;
static void
mangle_type (type)
tree type;
{
const char *ptr;
int qualifications = 0;
for (ptr = class_name; *ptr != '\0'; ptr++)
switch (TREE_CODE (type))
{
if (*ptr == '.')
qualifications++;
}
if (qualifications)
{
char buf[8];
if (qualifications >= 9)
sprintf (buf, "Q_%d_", qualifications + 1);
else
sprintf (buf, "Q%d", qualifications + 1);
obstack_grow (obstack, buf, strlen (buf));
}
for (ptr = class_name; ; ptr++)
{
if (ptr[0] == '.' || ptr[0] == '\0')
char code;
case BOOLEAN_TYPE: code = 'b'; goto primitive;
case CHAR_TYPE: code = 'w'; goto primitive;
case VOID_TYPE: code = 'v'; goto primitive;
case INTEGER_TYPE:
/* Get the original type instead of the arguments promoted type.
Avoid symbol name clashes. Should call a function to do that.
FIXME. */
if (type == promoted_short_type_node)
type = short_type_node;
if (type == promoted_byte_type_node)
type = byte_type_node;
switch (TYPE_PRECISION (type))
{
append_gpp_mangled_name (obstack, class_name, ptr - class_name);
if (ptr[0] == '\0')
case 8: code = 'c'; goto primitive;
case 16: code = 's'; goto primitive;
case 32: code = 'i'; goto primitive;
case 64: code = 'x'; goto primitive;
default: goto bad_type;
}
primitive:
obstack_1grow (mangle_obstack, code);
break;
case REAL_TYPE:
switch (TYPE_PRECISION (type))
{
case 32: code = 'f'; goto primitive;
case 64: code = 'd'; goto primitive;
default: goto bad_type;
}
case POINTER_TYPE:
if (TYPE_ARRAY_P (TREE_TYPE (type)))
mangle_array_type (type);
else
mangle_pointer_type (type);
break;
bad_type:
default:
fatal ("internal error - trying to mangle unknown type");
}
}
/* The compression table is a vector that keeps track of things we've
already seen, so they can be reused. For example, java.lang.Object
Would generate three entries: two package names and a type. If
java.lang.String is presented next, the java.lang will be matched
against the first two entries (and kept for compression as S_0), and
type String would be added to the table. See mangle_record_type.
COMPRESSION_NEXT is the index to the location of the next insertion
of an element. */
static tree compression_table;
static int compression_next;
/* Find a POINTER_TYPE in the compression table. Use a special
function to match pointer entries and start from the end */
static int
find_compression_pointer_match (type)
tree type;
{
int i;
for (i = compression_next-1; i >= 0; i--)
if (entry_match_pointer_p (type, i))
return i;
return -1;
}
/* Already recorder arrays are handled like pointer as they're always
associated with it. */
static int
find_compression_array_match (type)
tree type;
{
return find_compression_pointer_match (type);
}
/* Match the table of type against STRING. */
static int
find_compression_array_template_match (string)
tree string;
{
int i;
for (i = 0; i < compression_next; i++)
if (TREE_VEC_ELT (compression_table, i) == string)
return i;
return -1;
}
/* We go through the compression table and try to find a complete or
partial match. The function returns the compression table entry
that (evenutally partially) matches TYPE. *NEXT_CURRENT can be set
to the rest of TYPE to be mangled. */
static int
find_compression_record_match (type, next_current)
tree type;
tree *next_current;
{
int i, match;
tree current, saved_current;
/* Search from the beginning for something that matches TYPE, even
partially. */
for (current = TYPE_PACKAGE_LIST (type), i = 0, match = -1; current;
current = TREE_CHAIN (current))
{
int j;
for (j = i; j < compression_next; j++)
if (TREE_VEC_ELT (compression_table, j) == TREE_PURPOSE (current))
{
match = i = j;
saved_current = current;
break;
class_name = ptr + 1;
}
}
if (!next_current)
return match;
/* If we have a match, set next_current to the item next to the last
matched value. */
if (match >= 0)
*next_current = TREE_CHAIN (saved_current);
/* We had no match: we'll have to start from the beginning. */
if (match < 0)
*next_current = TYPE_PACKAGE_LIST (type);
return match;
}
/* Mangle a record type. If a non zero value is returned, it means
that a 'N' was emitted (so that a matching 'E' can be emitted if
necessary.) */
static int
mangle_record_type (type, from_pointer)
tree type;
int from_pointer;
{
tree current;
int match;
int nadded_p = 0;
#define ADD_N() \
do { obstack_1grow (mangle_obstack, 'N'); nadded_p = 1; } while (0)
if (TREE_CODE (type) != RECORD_TYPE)
fatal ("Non RECORD_TYPE argument -- mangle_record_type");
if (!TYPE_PACKAGE_LIST (type))
set_type_package_list (type);
match = find_compression_record_match (type, &current);
if (match >= 0)
{
/* If we had a pointer, and there's more, we need to emit
'N' after 'P' (from pointer tells us we already emitted it.) */
if (from_pointer && current)
ADD_N();
emit_compression_string (match);
}
while (current)
{
/* Add the new type to the table */
compression_table_add (TREE_PURPOSE (current));
/* Add 'N' if we never got a chance to. */
if (!nadded_p)
ADD_N();
/* Use the bare type name for the mangle. */
append_gpp_mangled_name (IDENTIFIER_POINTER (TREE_VALUE (current)),
IDENTIFIER_LENGTH (TREE_VALUE (current)));
current = TREE_CHAIN (current);
}
return nadded_p;
#undef ADD_N
}
/* Mangle a pointer type. There are two cases: the pointer is already
in the compression table: the compression is emited sans 'P'
indicator. Otherwise, a 'P' is emitted and, depending on the type,
a partial compression or/plus the rest of the mangling. */
static void
mangle_pointer_type (type)
tree type;
{
int match;
tree pointer_type;
/* Search for the type already in the compression table */
if ((match = find_compression_pointer_match (type)) >= 0)
{
emit_compression_string (match);
return;
}
/* This didn't work. We start by mangling the pointed-to type */
pointer_type = type;
type = TREE_TYPE (type);
if (TREE_CODE (type) != RECORD_TYPE)
fatal ("Double indirection found -- mangle_pointer_type");
obstack_1grow (mangle_obstack, 'P');
if (mangle_record_type (type, /* for_pointer = */ 1))
obstack_1grow (mangle_obstack, 'E');
/* Don't forget to insert the pointer type in the table */
compression_table_add (pointer_type);
}
/* Mangle an array type. Search for an easy solution first, then go
through the process of finding out whether the bare array type or even
the template indicator where already used an compress appropriately.
It handles pointers. */
static void
mangle_array_type (p_type)
tree p_type;
{
/* atms: array template mangled string. */
static tree atms = NULL_TREE;
tree type, elt_type;
int match;
type = TREE_TYPE (p_type);
if (!type)
fatal ("Non pointer array type -- mangle_array_type");
elt_type = TYPE_ARRAY_ELEMENT (type);
/* We cache a bit of the Jarray <> mangle. */
if (!atms)
{
atms = get_identifier ("6JArray");
ggc_add_tree_root (&atms, 1);
}
/* Maybe we have what we're looking in the compression table. */
if ((match = find_compression_array_match (p_type)) >= 0)
{
emit_compression_string (match);
return;
}
/* We know for a fact that all arrays are pointers */
obstack_1grow (mangle_obstack, 'P');
/* Maybe we already have a Jarray<t> somewhere. PSx_ will be enough. */
if ((match = find_compression_record_match (type, NULL)) > 0)
{
emit_compression_string (match);
return;
}
/* Maybe we already have just JArray somewhere */
if ((match = find_compression_array_template_match (atms)) > 0)
emit_compression_string (match);
else
{
/* Start the template mangled name */
obstack_grow (mangle_obstack,
IDENTIFIER_POINTER (atms), IDENTIFIER_LENGTH (atms));
/* Insert in the compression table */
compression_table_add (atms);
}
/* Mangle Jarray <elt_type> */
obstack_1grow (mangle_obstack, 'I');
mangle_type (elt_type);
obstack_1grow (mangle_obstack, 'E');
/* Add `Jarray <elt_type>' and `Jarray <elt_type> *' to the table */
compression_table_add (type);
compression_table_add (p_type);
}
/* Write a substition string for entry I. Substitution string starts a
-1 (encoded S_.) The base is 36, and the code shamlessly taken from
cp/mangle.c. */
static void
emit_compression_string (int i)
{
i -= 1; /* Adjust */
obstack_1grow (mangle_obstack, 'S');
if (i >= 0)
{
static const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
unsigned HOST_WIDE_INT n;
unsigned HOST_WIDE_INT m=1;
/* How many digits for I in base 36? */
for (n = i; n >= 36; n /= 36, m *=36);
/* Write the digits out */
while (m > 0)
{
int digit = i / m;
obstack_1grow (mangle_obstack, digits [digit]);
i -= digit * m;
m /= 36;
}
}
obstack_1grow (mangle_obstack, '_');
}
/* If search the compression table at index I for a pointer type
equivalent to TYPE (meaning that after all the indirection, which
might all be unique, we find the same RECORD_TYPE.) */
static int
entry_match_pointer_p (type, i)
tree type;
int i;
{
tree t = TREE_VEC_ELT (compression_table, i);
while (TREE_CODE (type) == POINTER_TYPE
&& TREE_CODE (t) == POINTER_TYPE)
{
t = TREE_TYPE (t);
type = TREE_TYPE (type);
}
return (TREE_CODE (type) == RECORD_TYPE
&& TREE_CODE (t) == RECORD_TYPE
&& t == type);
}
/* Go through all qualification of type and build a list of list node
elements containings as a purpose what should be used for a match and
inserted in the compression table; and as it value the raw name of the
part. The result is stored in TYPE_PACKAGE_LIST to be reused. */
static void
set_type_package_list (type)
tree type;
{
int i;
const char *type_string = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
char *ptr;
int qualifications;
tree list = NULL_TREE, elt;
for (ptr = (char *)type_string, qualifications = 0; *ptr; ptr++)
if (*ptr == '.')
qualifications += 1;
for (ptr = (char *)type_string, i = 0; i < qualifications; ptr++)
{
if (ptr [0] == '.')
{
char c;
tree identifier;
/* Can't use an obstack, we're already using it to
accumulate the mangling. */
c = ptr [0];
ptr [0] = '\0';
identifier = get_identifier (type_string);
ptr [0] = c;
elt = build_tree_list (identifier, identifier);
TREE_CHAIN (elt) = list;
list = elt;
type_string = ptr+1;
i += 1;
}
}
elt = build_tree_list (type, get_identifier (type_string));
TREE_CHAIN (elt) = list;
list = elt;
TYPE_PACKAGE_LIST (type) = nreverse (list);
}
/* Add TYPE as the last element of the compression table. Resize the
compression table if necessary. */
static void
compression_table_add (type)
tree type;
{
if (compression_next == TREE_VEC_LENGTH (compression_table))
{
tree new = make_tree_vec (2*compression_next);
int i;
for (i = 0; i < compression_next; i++)
TREE_VEC_ELT (new, i) = TREE_VEC_ELT (compression_table, i);
ggc_del_root (&compression_table);
compression_table = new;
ggc_add_tree_root (&compression_table, 1);
}
TREE_VEC_ELT (compression_table, compression_next++) = type;
}
/* Mangling initialization routine. */
static void
init_mangling (obstack)
struct obstack *obstack;
{
mangle_obstack = obstack;
if (!compression_table)
compression_table = make_tree_vec (10);
else
fatal ("Mangling already in progress -- init_mangling");
/* Mangled name are to be suffixed */
obstack_grow (mangle_obstack, "_Z", 2);
/* Register the compression table with the GC */
ggc_add_tree_root (&compression_table, 1);
}
/* Mangling finalization routine. The mangled name is returned as a
IDENTIFIER_NODE. */
static tree
finish_mangling ()
{
tree result;
if (!compression_table)
fatal ("Mangling already finished -- finish_mangling");
ggc_del_root (&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;
}

View File

@ -1,6 +1,6 @@
/* Source code parsing and tree node generation for the GNU compiler
for the Java(TM) language.
Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
This file is part of GNU CC.
@ -2973,7 +2973,6 @@ yyerror (msg)
int save_lineno;
char *remainder, *code_from_source;
extern struct obstack temporary_obstack;
if (!force_error && prev_lineno == lineno)
return;