diff options
author | apbianco <apbianco@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-01-15 08:01:22 +0000 |
---|---|---|
committer | apbianco <apbianco@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-01-15 08:01:22 +0000 |
commit | 6599bf3a0c329e6b77955d670683bf672f1c19df (patch) | |
tree | 978174af2eae55529af123d6d167212203a572ad /gcc/java/mangle.c | |
parent | 24d2f3a30a1afe944917c6374f035c14cb0abd47 (diff) | |
download | gcc-6599bf3a0c329e6b77955d670683bf672f1c19df.tar.gz |
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)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@39031 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/java/mangle.c')
-rw-r--r-- | gcc/java/mangle.c | 682 |
1 files changed, 645 insertions, 37 deletions
diff --git a/gcc/java/mangle.c b/gcc/java/mangle.c index e54df393989..080d4553350 100644 --- a/gcc/java/mangle.c +++ b/gcc/java/mangle.c @@ -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; +{ + 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 (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; { - const char *ptr; - int qualifications = 0; + int i, match; + tree current, saved_current; - for (ptr = class_name; *ptr != '\0'; ptr++) + /* 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)) { - if (*ptr == '.') - qualifications++; + 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; + } + } + + 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, ¤t); + 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); } - if (qualifications) + while (current) { - 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)); + /* 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; } - for (ptr = class_name; ; ptr++) + + /* 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 { - if (ptr[0] == '.' || ptr[0] == '\0') + /* 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) { - append_gpp_mangled_name (obstack, class_name, ptr - class_name); - if (ptr[0] == '\0') - break; - class_name = ptr + 1; + 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; } |