+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
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)
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))
{
else
error ("trying to finish struct, but kicked out due to previous parse errors.");
- hack_incomplete_structures (t);
-
resume_momentary (old);
if (flag_cadillac)
}
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 ())
{
/* 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.
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)
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));
}
}
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);
}
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;
}
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:
{ $$ = 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:
&& 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),
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;
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);
}
}