summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>1997-10-16 07:20:46 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>1997-10-16 07:20:46 +0000
commit006f94cdee02752dccc1322e7ce13fcff95b6936 (patch)
tree57f6c60612e19f552c7ec3548903b470205eeb74
parent822c8a6c892188b5201f5d7600e33fdd5042570d (diff)
downloadgcc-006f94cdee02752dccc1322e7ce13fcff95b6936.tar.gz
* method.c (build_overload_value): Handle TEMPLATE_CONST_PARMs here.
(build_overload_int): Not here. Wed Oct 15 00:35:28 1997 Mike Stump <mrs@wrs.com> * class.c (build_type_pathname): Remove. (prepare_fresh_vtable): Fix problem with complex MI vtable names. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@15928 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/class.c147
-rw-r--r--gcc/cp/method.c18
-rw-r--r--gcc/cp/typeck2.c2
4 files changed, 93 insertions, 84 deletions
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 <jason@yorick.cygnus.com>
+
+ * method.c (build_overload_value): Handle TEMPLATE_CONST_PARMs here.
+ (build_overload_int): Not here.
+
+Wed Oct 15 00:35:28 1997 Mike Stump <mrs@wrs.com>
+
+ * class.c (build_type_pathname): Remove.
+ (prepare_fresh_vtable): Fix problem with complex MI vtable names.
+
1997-10-14 Brendan Kehoe <brendan@lisa.cygnus.com>
* 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<int>, 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;