From 8145f0828c5c795620174ffd6deba9a5a6eb63f6 Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Fri, 30 Dec 1994 21:03:40 +0000 Subject: [PATCH] 52th Cygnus<->FSF merge From-SVN: r8714 --- gcc/cp/ChangeLog | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ gcc/cp/class.c | 16 +++++++------ gcc/cp/cvt.c | 3 --- gcc/cp/decl.c | 16 ++++++++++++- gcc/cp/decl2.c | 33 +++++++++++++++++++++------ gcc/cp/method.c | 13 +++++++++++ gcc/cp/parse.y | 2 +- gcc/cp/pt.c | 31 ++++++++++++++++++++++++++ gcc/cp/typeck.c | 35 +++++++++++++---------------- 9 files changed, 169 insertions(+), 38 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 44511fcdaeb9..5fa2f83f2d7b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,61 @@ +Fri Dec 30 12:22:29 1994 Mike Stump + + * 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 + + * pt.c (tsubst): Fix problem with defining constructors in templated + classes with virtual bases. + +Wed Dec 28 08:31:00 1994 Mike Stump + + * 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 + + * 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 + + * method.c (build_overload_value): Handle pointer to members as + template arguments. + +Thu Dec 22 13:09:07 1994 Mike Stump + + * 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 + + * 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 + + * 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 + + * 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 * decl2.c (check_classfn): Don't use decls_match yet, as it modifies diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 9731ac1cb84e..b0e0cf8ff973 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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) diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index b472c83538be..01d0a3d6386b 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -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 ()) { diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 5d3c2f2c2648..f57399421e9b 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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)); } } diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index af7d7d712c81..df2b11968368 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -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; } diff --git a/gcc/cp/method.c b/gcc/cp/method.c index da2a7824852c..92610ff07254 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -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: diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index 9fb1b37d6cd8..49dc8329b6f9 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -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: diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index eab4e109f931..e10acbe1c29a 100644 --- a/gcc/cp/pt.c +++ b/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), diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 90ea075a2354..ae9f1935f90d 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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); } } -- 2.43.5