diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a8218ba1f92..a278b09edc3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +Thu Oct 16 00:14:48 1997 Jason Merrill + + * method.c (build_overload_value): Handle TEMPLATE_CONST_PARMs here. + (build_overload_int): Not here. + +Wed Oct 15 00:35:28 1997 Mike Stump + + * class.c (build_type_pathname): Remove. + (prepare_fresh_vtable): Fix problem with complex MI vtable names. + 1997-10-14 Brendan Kehoe * parse.y (unary_expr): Give a pedwarn if someone tries to use the diff --git a/gcc/cp/class.c b/gcc/cp/class.c index da5fcd3b3ab..e24d6a230b9 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -96,7 +96,6 @@ static tree get_derived_offset PROTO((tree, tree)); static tree get_basefndecls PROTO((tree, tree)); static void set_rtti_entry PROTO((tree, tree, tree)); static tree build_vtable PROTO((tree, tree)); -static tree build_type_pathname PROTO((char *, tree, tree)); static void prepare_fresh_vtable PROTO((tree, tree)); static void fixup_vtable_deltas1 PROTO((tree, tree)); static void fixup_vtable_deltas PROTO((tree, int, tree)); @@ -588,8 +587,8 @@ get_vtable_name (type) tree type; { tree type_id = build_typename_overload (type); - char *buf = (char *)alloca (strlen (VTABLE_NAME_FORMAT) - + IDENTIFIER_LENGTH (type_id) + 2); + char *buf = (char *) alloca (strlen (VTABLE_NAME_FORMAT) + + IDENTIFIER_LENGTH (type_id) + 2); char *ptr = IDENTIFIER_POINTER (type_id); int i; for (i = 0; ptr[i] == OPERATOR_TYPENAME_FORMAT[i]; i++) ; @@ -737,69 +736,6 @@ build_vtable (binfo, type) return decl; } -/* Given a base type PARENT, and a derived type TYPE, build - a name which distinguishes exactly the PARENT member of TYPE's type. - - FORMAT is a string which controls how sprintf formats the name - we have generated. - - For example, given - - class A; class B; class C : A, B; - - it is possible to distinguish "A" from "C's A". And given - - class L; - class A : L; class B : L; class C : A, B; - - it is possible to distinguish "L" from "A's L", and also from - "C's L from A". - - Make sure to use the DECL_ASSEMBLER_NAME of the TYPE_NAME of the - type, as template have DECL_NAMEs like: X, whereas the - DECL_ASSEMBLER_NAME is set to be something the assembler can handle. */ - -static tree -build_type_pathname (format, parent, type) - char *format; - tree parent, type; -{ - extern struct obstack temporary_obstack; - char *first, *base, *name; - int i; - tree id; - - parent = TYPE_MAIN_VARIANT (parent); - - /* Remember where to cut the obstack to. */ - first = obstack_base (&temporary_obstack); - - /* Put on TYPE+PARENT. */ - obstack_grow (&temporary_obstack, - TYPE_ASSEMBLER_NAME_STRING (type), - TYPE_ASSEMBLER_NAME_LENGTH (type)); -#ifdef JOINER - obstack_1grow (&temporary_obstack, JOINER); -#else - obstack_1grow (&temporary_obstack, '_'); -#endif - obstack_grow0 (&temporary_obstack, - TYPE_ASSEMBLER_NAME_STRING (parent), - TYPE_ASSEMBLER_NAME_LENGTH (parent)); - i = obstack_object_size (&temporary_obstack); - base = obstack_base (&temporary_obstack); - obstack_finish (&temporary_obstack); - - /* Put on FORMAT+TYPE+PARENT. */ - obstack_blank (&temporary_obstack, strlen (format) + i + 1); - name = obstack_base (&temporary_obstack); - sprintf (name, format, base); - id = get_identifier (name); - obstack_free (&temporary_obstack, first); - - return id; -} - extern tree signed_size_zero_node; /* Give TYPE a new virtual function table which is initialized @@ -810,20 +746,83 @@ extern tree signed_size_zero_node; FOR_TYPE is the derived type which caused this table to be needed. - BINFO is the type association which provided TYPE for FOR_TYPE. */ + BINFO is the type association which provided TYPE for FOR_TYPE. + + The order in which vtables are built (by calling this function) for + an object must remain the same, otherwise a binary incompatibility + can result. */ static void prepare_fresh_vtable (binfo, for_type) tree binfo, for_type; { - tree basetype = BINFO_TYPE (binfo); + tree basetype; tree orig_decl = BINFO_VTABLE (binfo); - /* This name is too simplistic. We can have multiple basetypes for - for_type, and we really want different names. (mrs) */ - tree name = build_type_pathname (VTABLE_NAME_FORMAT, basetype, for_type); - tree new_decl = build_decl (VAR_DECL, name, TREE_TYPE (orig_decl)); + tree name; + tree new_decl; tree offset; + tree path = binfo; + char *buf, *buf2; + char joiner = '_'; + int i; +#ifdef JOINER + joiner = JOINER; +#endif + + basetype = TYPE_MAIN_VARIANT (BINFO_TYPE (binfo)); + + buf2 = TYPE_ASSEMBLER_NAME_STRING (basetype); + i = TYPE_ASSEMBLER_NAME_LENGTH (basetype) + 1; + + /* We know that the vtable that we are going to create doesn't exist + yet in the global namespace, and when we finish, it will be + pushed into the global namespace. In complex MI hierarchies, we + have to loop while the name we are thinking of adding is globally + defined, adding more name components to the vtable name as we + loop, until the name is unique. This is because in complex MI + cases, we might have the same base more than once. This means + that the order in which this function is called for vtables must + remain the same, otherwise binary compatibility can be + compromised. */ + + while (1) + { + char *buf1 = (char *) alloca (TYPE_ASSEMBLER_NAME_LENGTH (for_type) + 1 + i); + char *new_buf2; + + sprintf (buf1, "%s%c%s", TYPE_ASSEMBLER_NAME_STRING (for_type), joiner, + buf2); + buf = (char *) alloca (strlen (VTABLE_NAME_FORMAT) + strlen (buf1) + 1); + sprintf (buf, VTABLE_NAME_FORMAT, buf1); + name = get_identifier (buf); + + /* If this name doesn't clash, then we can use it, otherwise + we add more to the name until it is unique. */ + + if (! IDENTIFIER_GLOBAL_VALUE (name)) + break; + + /* Set values for next loop through, if the name isn't unique. */ + + path = BINFO_INHERITANCE_CHAIN (path); + + /* We better not run out of stuff to make it unique. */ + my_friendly_assert (path != NULL_TREE, 368); + + basetype = TYPE_MAIN_VARIANT (BINFO_TYPE (path)); + + /* We better not run out of stuff to make it unique. */ + my_friendly_assert (for_type != basetype, 369); + + i = TYPE_ASSEMBLER_NAME_LENGTH (basetype) + 1 + i; + new_buf2 = (char *) alloca (i); + sprintf (new_buf2, "%s%c%s", + TYPE_ASSEMBLER_NAME_STRING (basetype), joiner, buf2); + buf2 = new_buf2; + } + + new_decl = build_decl (VAR_DECL, name, TREE_TYPE (orig_decl)); /* Remember which class this vtable is really for. */ DECL_CONTEXT (new_decl) = for_type; @@ -5407,8 +5406,8 @@ get_vfield_name (type) binfo = BINFO_BASETYPE (binfo, 0); type = BINFO_TYPE (binfo); - buf = (char *)alloca (sizeof (VFIELD_NAME_FORMAT) - + TYPE_NAME_LENGTH (type) + 2); + buf = (char *) alloca (sizeof (VFIELD_NAME_FORMAT) + + TYPE_NAME_LENGTH (type) + 2); sprintf (buf, VFIELD_NAME_FORMAT, TYPE_NAME_STRING (type)); return get_identifier (buf); } diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 38004f8c482..15f444bf8fd 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -435,15 +435,7 @@ build_overload_int (value, in_template) tree value; int in_template; { - if (TREE_CODE (value) == TEMPLATE_CONST_PARM) - { - OB_PUTC ('Y'); - build_underscore_int (TEMPLATE_CONST_IDX (value)); - build_underscore_int (TEMPLATE_CONST_LEVEL (value)); - return; - } - else if (in_template - && TREE_CODE (value) != INTEGER_CST) + if (in_template && TREE_CODE (value) != INTEGER_CST) /* We don't ever want this output, but it's inconvenient not to be able to build the string. This should cause assembler errors we'll notice. */ @@ -487,6 +479,14 @@ build_overload_value (type, value, in_template) numeric_output_need_bar = 0; } + if (TREE_CODE (value) == TEMPLATE_CONST_PARM) + { + OB_PUTC ('Y'); + build_underscore_int (TEMPLATE_CONST_IDX (value)); + build_underscore_int (TEMPLATE_CONST_LEVEL (value)); + return; + } + if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE) { diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 93c77dd035a..d876e76806f 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -301,7 +301,7 @@ ack (s, v, v2) silly. So instead, we just do the equivalent of a call to fatal in the same situation (call exit). */ -/* First used: 0 (reserved), Last used: 367. Free: */ +/* First used: 0 (reserved), Last used: 369. Free: */ static int abortcount = 0;