mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-08 13:57:15 +08:00
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>
|
||||
|
||||
* 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 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);
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user