method.c (build_overload_value): Handle TEMPLATE_CONST_PARMs here.
* 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. From-SVN: r15928
This commit is contained in:
parent
96b63cd7a2
commit
2636fde4ba
|
@ -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>
|
1997-10-14 Brendan Kehoe <brendan@lisa.cygnus.com>
|
||||||
|
|
||||||
* parse.y (unary_expr): Give a pedwarn if someone tries to use the
|
* parse.y (unary_expr): Give a pedwarn if someone tries to use the
|
||||||
|
|
147
gcc/cp/class.c
147
gcc/cp/class.c
|
@ -96,7 +96,6 @@ static tree get_derived_offset PROTO((tree, tree));
|
||||||
static tree get_basefndecls PROTO((tree, tree));
|
static tree get_basefndecls PROTO((tree, tree));
|
||||||
static void set_rtti_entry PROTO((tree, tree, tree));
|
static void set_rtti_entry PROTO((tree, tree, tree));
|
||||||
static tree build_vtable PROTO((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 prepare_fresh_vtable PROTO((tree, tree));
|
||||||
static void fixup_vtable_deltas1 PROTO((tree, tree));
|
static void fixup_vtable_deltas1 PROTO((tree, tree));
|
||||||
static void fixup_vtable_deltas PROTO((tree, int, tree));
|
static void fixup_vtable_deltas PROTO((tree, int, tree));
|
||||||
|
@ -588,8 +587,8 @@ get_vtable_name (type)
|
||||||
tree type;
|
tree type;
|
||||||
{
|
{
|
||||||
tree type_id = build_typename_overload (type);
|
tree type_id = build_typename_overload (type);
|
||||||
char *buf = (char *)alloca (strlen (VTABLE_NAME_FORMAT)
|
char *buf = (char *) alloca (strlen (VTABLE_NAME_FORMAT)
|
||||||
+ IDENTIFIER_LENGTH (type_id) + 2);
|
+ IDENTIFIER_LENGTH (type_id) + 2);
|
||||||
char *ptr = IDENTIFIER_POINTER (type_id);
|
char *ptr = IDENTIFIER_POINTER (type_id);
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; ptr[i] == OPERATOR_TYPENAME_FORMAT[i]; i++) ;
|
for (i = 0; ptr[i] == OPERATOR_TYPENAME_FORMAT[i]; i++) ;
|
||||||
|
@ -737,69 +736,6 @@ build_vtable (binfo, type)
|
||||||
return decl;
|
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;
|
extern tree signed_size_zero_node;
|
||||||
|
|
||||||
/* Give TYPE a new virtual function table which is initialized
|
/* 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
|
FOR_TYPE is the derived type which caused this table to
|
||||||
be needed.
|
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
|
static void
|
||||||
prepare_fresh_vtable (binfo, for_type)
|
prepare_fresh_vtable (binfo, for_type)
|
||||||
tree binfo, for_type;
|
tree binfo, for_type;
|
||||||
{
|
{
|
||||||
tree basetype = BINFO_TYPE (binfo);
|
tree basetype;
|
||||||
tree orig_decl = BINFO_VTABLE (binfo);
|
tree orig_decl = BINFO_VTABLE (binfo);
|
||||||
/* This name is too simplistic. We can have multiple basetypes for
|
tree name;
|
||||||
for_type, and we really want different names. (mrs) */
|
tree new_decl;
|
||||||
tree name = build_type_pathname (VTABLE_NAME_FORMAT, basetype, for_type);
|
|
||||||
tree new_decl = build_decl (VAR_DECL, name, TREE_TYPE (orig_decl));
|
|
||||||
tree offset;
|
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. */
|
/* Remember which class this vtable is really for. */
|
||||||
DECL_CONTEXT (new_decl) = for_type;
|
DECL_CONTEXT (new_decl) = for_type;
|
||||||
|
|
||||||
|
@ -5407,8 +5406,8 @@ get_vfield_name (type)
|
||||||
binfo = BINFO_BASETYPE (binfo, 0);
|
binfo = BINFO_BASETYPE (binfo, 0);
|
||||||
|
|
||||||
type = BINFO_TYPE (binfo);
|
type = BINFO_TYPE (binfo);
|
||||||
buf = (char *)alloca (sizeof (VFIELD_NAME_FORMAT)
|
buf = (char *) alloca (sizeof (VFIELD_NAME_FORMAT)
|
||||||
+ TYPE_NAME_LENGTH (type) + 2);
|
+ TYPE_NAME_LENGTH (type) + 2);
|
||||||
sprintf (buf, VFIELD_NAME_FORMAT, TYPE_NAME_STRING (type));
|
sprintf (buf, VFIELD_NAME_FORMAT, TYPE_NAME_STRING (type));
|
||||||
return get_identifier (buf);
|
return get_identifier (buf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -435,15 +435,7 @@ build_overload_int (value, in_template)
|
||||||
tree value;
|
tree value;
|
||||||
int in_template;
|
int in_template;
|
||||||
{
|
{
|
||||||
if (TREE_CODE (value) == TEMPLATE_CONST_PARM)
|
if (in_template && TREE_CODE (value) != INTEGER_CST)
|
||||||
{
|
|
||||||
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)
|
|
||||||
/* We don't ever want this output, but it's inconvenient not to
|
/* We don't ever want this output, but it's inconvenient not to
|
||||||
be able to build the string. This should cause assembler
|
be able to build the string. This should cause assembler
|
||||||
errors we'll notice. */
|
errors we'll notice. */
|
||||||
|
@ -487,6 +479,14 @@ build_overload_value (type, value, in_template)
|
||||||
numeric_output_need_bar = 0;
|
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
|
if (TREE_CODE (type) == POINTER_TYPE
|
||||||
&& TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE)
|
&& TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE)
|
||||||
{
|
{
|
||||||
|
|
|
@ -301,7 +301,7 @@ ack (s, v, v2)
|
||||||
silly. So instead, we just do the equivalent of a call to fatal in the
|
silly. So instead, we just do the equivalent of a call to fatal in the
|
||||||
same situation (call exit). */
|
same situation (call exit). */
|
||||||
|
|
||||||
/* First used: 0 (reserved), Last used: 367. Free: */
|
/* First used: 0 (reserved), Last used: 369. Free: */
|
||||||
|
|
||||||
static int abortcount = 0;
|
static int abortcount = 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue