parent
ad0ad21356
commit
8145f0828c
|
@ -1,3 +1,61 @@
|
|||
Fri Dec 30 12:22:29 1994 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* decl.c (n_incomplete): Bump n_incomplete up to int to match C
|
||||
front end.
|
||||
(pushdecl): Also count decls pushed that are of a type being defined
|
||||
as incomplete things.
|
||||
* class.c (finish_struct): Move hack_incomplete_structures up to
|
||||
just after we set it as not being defined, so that the decls we
|
||||
build for RTTI don't count as incomplete.
|
||||
|
||||
Thu Dec 29 18:20:57 1994 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* pt.c (tsubst): Fix problem with defining constructors in templated
|
||||
classes with virtual bases.
|
||||
|
||||
Wed Dec 28 08:31:00 1994 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* parse.y (TYPEID): Strip top-level cv-qualifiers on typeid
|
||||
expressions.
|
||||
* gc.c (build_typeid): Ditto.
|
||||
|
||||
Thu Dec 22 17:26:33 1994 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* cvt.c (build_up_reference): Fix breakage introduced on Nov 29,
|
||||
don't assert on complex AGGR inits.
|
||||
|
||||
Thu Dec 22 14:32:31 1994 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* method.c (build_overload_value): Handle pointer to members as
|
||||
template arguments.
|
||||
|
||||
Thu Dec 22 13:09:07 1994 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* typeck.c (unary_complex_lvalue): Don't call sorry if we know how
|
||||
to do take the address of a data member for a pointer to data
|
||||
member.
|
||||
|
||||
Thu Dec 22 10:04:19 1994 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* decl.c (grokdeclarator): Use the typedef name for linkage if the
|
||||
type doesn't otherwise have a name.
|
||||
|
||||
* decl2.c (grokfield): Ditto.
|
||||
|
||||
* class.c (finish_struct): Since we reuse the TYPE_DECL for the
|
||||
DECL_NAME of enums, structs and classes, we have to avoid trying to
|
||||
put it in the TYPE_FIELDS again.
|
||||
|
||||
Wed Dec 21 11:07:05 1994 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* decl2.c (check_classfn): Ignore this parameter on static functions
|
||||
when checking to see if we match.
|
||||
|
||||
Tue Dec 20 17:47:02 1994 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* typeck.c (unary_complex_lvalue): Handle address of non-left most
|
||||
pointers to members by calling get_delta_difference.
|
||||
|
||||
Mon Dec 19 22:40:53 1994 Mike Stump <mrs@cygnus.com>
|
||||
|
||||
* decl2.c (check_classfn): Don't use decls_match yet, as it modifies
|
||||
|
|
|
@ -3982,12 +3982,15 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
last_x = tree_last (TYPE_FIELDS (t));
|
||||
while (x)
|
||||
{
|
||||
#if 0 /* What's wrong with using the decl the type already has? */
|
||||
tree tag = build_decl (TYPE_DECL, TREE_PURPOSE (x), TREE_VALUE (x));
|
||||
DECL_CONTEXT (tag) = t;
|
||||
#else
|
||||
tree tag = TYPE_NAME (TREE_VALUE (x));
|
||||
#endif
|
||||
|
||||
/* Check to see if it is already there. This will be the case if
|
||||
was do enum { red; } color; */
|
||||
if (chain_member (tag, TYPE_FIELDS (t)))
|
||||
{
|
||||
x = TREE_CHAIN (x);
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef DWARF_DEBUGGING_INFO
|
||||
if (write_symbols == DWARF_DEBUG)
|
||||
|
@ -4077,6 +4080,7 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
the base types we marked. */
|
||||
finish_vtbls (TYPE_BINFO (t), 1, t);
|
||||
TYPE_BEING_DEFINED (t) = 0;
|
||||
hack_incomplete_structures (t);
|
||||
|
||||
if (flag_rtti && TYPE_VIRTUAL_P (t) && CLASSTYPE_VTABLE_NEEDS_WRITING (t))
|
||||
{
|
||||
|
@ -4128,8 +4132,6 @@ finish_struct (t, list_of_fieldlists, warn_anon)
|
|||
else
|
||||
error ("trying to finish struct, but kicked out due to previous parse errors.");
|
||||
|
||||
hack_incomplete_structures (t);
|
||||
|
||||
resume_momentary (old);
|
||||
|
||||
if (flag_cadillac)
|
||||
|
|
|
@ -556,9 +556,6 @@ build_up_reference (type, arg, flags, checkconst)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* We should never get here for class objects, because they are
|
||||
always in memory. */
|
||||
my_friendly_assert (! IS_AGGR_TYPE (argtype), 362);
|
||||
temp = get_temp_name (argtype, 0);
|
||||
if (global_bindings_p ())
|
||||
{
|
||||
|
|
|
@ -552,7 +552,7 @@ struct binding_level
|
|||
|
||||
/* Number of decls in `names' that have incomplete
|
||||
structure or union types. */
|
||||
unsigned short n_incomplete;
|
||||
unsigned int n_incomplete;
|
||||
|
||||
/* 1 for the level that holds the parameters of a function.
|
||||
2 for the level that holds a class declaration.
|
||||
|
@ -2979,6 +2979,16 @@ pushdecl (x)
|
|||
if (++b->n_incomplete == 0)
|
||||
error ("too many incomplete variables at this point");
|
||||
}
|
||||
|
||||
/* Keep count of variables in this level with incomplete type. */
|
||||
/* RTTI TD entries are created while defining the type_info. */
|
||||
if (TREE_CODE (x) == VAR_DECL
|
||||
&& TYPE_LANG_SPECIFIC (TREE_TYPE (x))
|
||||
&& TYPE_BEING_DEFINED (TREE_TYPE (x)))
|
||||
{
|
||||
if (++b->n_incomplete == 0)
|
||||
error ("too many incomplete variables at this point");
|
||||
}
|
||||
}
|
||||
|
||||
if (TREE_CODE (x) == TYPE_DECL && name != NULL_TREE)
|
||||
|
@ -8603,6 +8613,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
|
|||
declarator, type);
|
||||
else
|
||||
set_nested_typename (d, TYPE_NESTED_NAME (c), declarator, type);
|
||||
|
||||
DECL_ASSEMBLER_NAME (d) = DECL_NAME (d);
|
||||
DECL_ASSEMBLER_NAME (d)
|
||||
= get_identifier (build_overload_name (type, 1, 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1155,13 +1155,22 @@ check_classfn (ctype, cname, function)
|
|||
if (decls_match (function, fndecl))
|
||||
return;
|
||||
#else
|
||||
if (DECL_NAME (function) == DECL_NAME (fndecl)
|
||||
&& comptypes (TREE_TYPE (TREE_TYPE (function)),
|
||||
TREE_TYPE (TREE_TYPE (fndecl)), 1)
|
||||
&& compparms (TYPE_ARG_TYPES (TREE_TYPE (function)),
|
||||
TYPE_ARG_TYPES (TREE_TYPE (fndecl)),
|
||||
3))
|
||||
return;
|
||||
if (DECL_NAME (function) == DECL_NAME (fndecl))
|
||||
{
|
||||
tree p1 = TYPE_ARG_TYPES (TREE_TYPE (function));
|
||||
tree p2 = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
|
||||
|
||||
/* Get rid of the this parameter on functions that become
|
||||
static. */
|
||||
if (DECL_STATIC_FUNCTION_P (fndecl)
|
||||
&& TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE)
|
||||
p1 = TREE_CHAIN (p1);
|
||||
|
||||
if (comptypes (TREE_TYPE (TREE_TYPE (function)),
|
||||
TREE_TYPE (TREE_TYPE (fndecl)), 1)
|
||||
&& compparms (p1, p2, 3))
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
fndecl = DECL_CHAIN (fndecl);
|
||||
}
|
||||
|
@ -1253,6 +1262,16 @@ grokfield (declarator, declspecs, raises, init, asmspec_tree)
|
|||
DECL_CLASS_CONTEXT (value) = current_class_type;
|
||||
CLASSTYPE_LOCAL_TYPEDECLS (current_class_type) = 1;
|
||||
pushdecl_class_level (value);
|
||||
|
||||
/* If we declare a typedef name for something that has no name,
|
||||
the typedef name is used for linkage. See 7.1.3 p4 94/0158. */
|
||||
if (TYPE_NAME (TREE_TYPE (value))
|
||||
&& TREE_CODE (TYPE_NAME (TREE_TYPE (value))) == TYPE_DECL
|
||||
&& ANON_AGGRNAME_P (TYPE_IDENTIFIER (TREE_TYPE (value))))
|
||||
{
|
||||
TYPE_NAME (TREE_TYPE (value)) = value;
|
||||
TYPE_STUB_DECL (TREE_TYPE (value)) = value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
|
@ -362,6 +362,19 @@ build_overload_value (type, value)
|
|||
value = TREE_OPERAND (value, 0);
|
||||
my_friendly_assert (TREE_CODE (type) == PARM_DECL, 242);
|
||||
type = TREE_TYPE (type);
|
||||
if (TREE_CODE (type) == POINTER_TYPE
|
||||
&& TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE)
|
||||
{
|
||||
/* Handle a pointer to member as a template instantiation
|
||||
parameter, boy, what fun! */
|
||||
type = integer_type_node;
|
||||
if (TREE_CODE (value) != INTEGER_CST)
|
||||
{
|
||||
sorry ("unknown pointer to member constant");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (TREE_CODE (type))
|
||||
{
|
||||
case INTEGER_TYPE:
|
||||
|
|
|
@ -1484,7 +1484,7 @@ primary:
|
|||
{ $$ = build_typeid ($3); }
|
||||
| TYPEID '(' type_id ')'
|
||||
{ tree type = groktypename ($3);
|
||||
$$ = get_typeid (type); }
|
||||
$$ = get_typeid (TYPE_MAIN_VARIANT (type)); }
|
||||
| global_scope IDENTIFIER
|
||||
{
|
||||
do_scoped_id:
|
||||
|
|
31
gcc/cp/pt.c
31
gcc/cp/pt.c
|
@ -1239,6 +1239,37 @@ tsubst (t, args, nargs, in_decl)
|
|||
&& TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (t))) == 't'
|
||||
&& constructor_name (DECL_CONTEXT (t)) == DECL_NAME (t))
|
||||
name = constructor_name (ctx);
|
||||
|
||||
if (DECL_CONSTRUCTOR_P (t) && TYPE_USES_VIRTUAL_BASECLASSES (ctx))
|
||||
{
|
||||
/* Since we didn't know that this class had virtual bases until after
|
||||
we instantiated it, we have to recreate the arguments to this
|
||||
constructor, as otherwise it would miss the __in_chrg parameter. */
|
||||
tree newtype, parm;
|
||||
tree parms = TREE_CHAIN (TYPE_ARG_TYPES (type));
|
||||
parms = hash_tree_chain (integer_type_node, parms);
|
||||
newtype = build_cplus_method_type (ctx,
|
||||
TREE_TYPE (type),
|
||||
parms);
|
||||
newtype = build_type_variant (newtype,
|
||||
TYPE_READONLY (type),
|
||||
TYPE_VOLATILE (type));
|
||||
type = newtype;
|
||||
|
||||
fnargs = copy_node (DECL_ARGUMENTS (t));
|
||||
/* In this case we need "in-charge" flag saying whether
|
||||
this constructor is responsible for initialization
|
||||
of virtual baseclasses or not. */
|
||||
parm = build_decl (PARM_DECL, in_charge_identifier, integer_type_node);
|
||||
/* Mark the artificial `__in_chrg' parameter as "artificial". */
|
||||
SET_DECL_ARTIFICIAL (parm);
|
||||
DECL_ARG_TYPE (parm) = integer_type_node;
|
||||
DECL_REGISTER (parm) = 1;
|
||||
TREE_CHAIN (parm) = TREE_CHAIN (fnargs);
|
||||
TREE_CHAIN (fnargs) = parm;
|
||||
|
||||
fnargs = tsubst (fnargs, args, nargs, t);
|
||||
}
|
||||
#if 0
|
||||
fprintf (stderr, "\nfor function %s in class %s:\n",
|
||||
IDENTIFIER_POINTER (name),
|
||||
|
|
|
@ -47,6 +47,7 @@ static tree pointer_int_sum ();
|
|||
static tree pointer_diff ();
|
||||
static tree convert_sequence ();
|
||||
/* static */ tree unary_complex_lvalue ();
|
||||
static tree get_delta_difference PROTO((tree, tree, int));
|
||||
|
||||
extern rtx original_result_rtx;
|
||||
|
||||
|
@ -4290,29 +4291,25 @@ unary_complex_lvalue (code, arg)
|
|||
return build_unary_op (ADDR_EXPR, t, 0);
|
||||
else
|
||||
{
|
||||
/* Can't build a pointer to member if the member must
|
||||
go through virtual base classes. */
|
||||
if (virtual_member (DECL_FIELD_CONTEXT (t),
|
||||
CLASSTYPE_VBASECLASSES (TREE_TYPE (TREE_OPERAND (arg, 0)))))
|
||||
{
|
||||
sorry ("pointer to member via virtual baseclass");
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
if (TREE_OPERAND (arg, 0)
|
||||
&& (TREE_CODE (TREE_OPERAND (arg, 0)) != NOP_EXPR
|
||||
|| TREE_OPERAND (TREE_OPERAND (arg, 0), 0) != error_mark_node))
|
||||
{
|
||||
/* Don't know if this should return address to just
|
||||
_DECL, or actual address resolved in this expression. */
|
||||
sorry ("address of bound pointer-to-member expression");
|
||||
return error_mark_node;
|
||||
}
|
||||
if (TREE_CODE (t) != FIELD_DECL)
|
||||
{
|
||||
/* Don't know if this should return address to just
|
||||
_DECL, or actual address resolved in this expression. */
|
||||
sorry ("address of bound pointer-to-member expression");
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
return convert (build_pointer_type (TREE_TYPE (arg)),
|
||||
size_binop (EASY_DIV_EXPR,
|
||||
DECL_FIELD_BITPOS (t),
|
||||
size_int (BITS_PER_UNIT)));
|
||||
offset = get_delta_difference (DECL_FIELD_CONTEXT (t),
|
||||
TREE_TYPE (TREE_OPERAND (arg, 0)),
|
||||
0);
|
||||
offset = size_binop (PLUS_EXPR, offset,
|
||||
size_binop (EASY_DIV_EXPR,
|
||||
DECL_FIELD_BITPOS (t),
|
||||
size_int (BITS_PER_UNIT)));
|
||||
return convert (build_pointer_type (TREE_TYPE (arg)), offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue