|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T g
Length: 69500 (0x10f7c) Types: TextFile Names: »g++-patches«
└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89 └─⟦this⟧ »./g++-patches«
diff -rc2H /usr/gnu/ftp/pub/g++-1.35.0-/HINTS src-g++/HINTS *** /usr/gnu/ftp/pub/g++-1.35.0-/HINTS Wed Apr 5 07:55:27 1989 --- src-g++/HINTS Wed May 10 00:24:02 1989 *************** *** 35,36 **** --- 35,60 ---- Michael Tiemann tiemann@lurch.stanford.edu + + ---------------------------------------------------------------- + The 2.0 C++ language specification provides many new features which + can trip up the novice user. All of these features are being + implemented in GNU C++, and most of them work right now. However, + this does not mean that they are all that easily used. Perhaps on of + the toughest new features to take advantage of right now is extern "C". + What makes this hard is that up until now, C and C++ really looked + like they had about the same langauge linkage. Member functions had + their names mangled, but non-overloaded global functions did not. + In 2.0, all functions declared in C++ scope are automatically + overloaded, and all such functions all get mangled names. So if you + declare, e.g., `int printf (const char *, ...)' in C++ language scope, + and you get printf from libc.a, you will lose, since the compiler will + assume that you are looking for e.g., "_printf_PQI", when you are + really looking for "_printf". To get around this problem, you can use + extern "C" to tell the compiler which names should be mangled and how. + There is a macro called NO_EXTERN_C, which if defined, will provide + the standard cfront 1.2 and old GNU C++ behavior. If not defined, it + provides the cfront 2.0 behavior. One should move from the old to the + new carefully, and if you get lots of new undefined symbols from the + linker where such did not exist before, the first question you should + ask yourself is `how is extern "C" or extern "C++" doing me in?' + diff -rc2H /usr/gnu/ftp/pub/g++-1.35.0-/Makefile src-g++/Makefile *** /usr/gnu/ftp/pub/g++-1.35.0-/Makefile Sun May 7 00:51:02 1989 --- src-g++/Makefile Tue May 9 23:25:04 1989 *************** *** 53,57 **** # Variables that exist for you to override. ! CFLAGS = -g -DSOS -DESKIT -O # CFLAGS = -g -O CC = gcc --- 53,57 ---- # Variables that exist for you to override. ! CFLAGS = -g -DSOS -DESKIT # CFLAGS = -g -O CC = gcc diff -rc2H /usr/gnu/ftp/pub/g++-1.35.0-/README src-g++/README *** /usr/gnu/ftp/pub/g++-1.35.0-/README Thu Mar 30 02:06:58 1989 --- src-g++/README Wed May 10 00:14:25 1989 *************** *** 1,3 **** ! This is the file README. It documents release 1.34.2 of the GNU C++ compiler system, still in test release status. All bugs reported for previous test releases have been fixed. Some bugs surely remain. --- 1,3 ---- ! This is the file README. It documents release 1.35.0 of the GNU C++ compiler system, still in test release status. All bugs reported for previous test releases have been fixed. Some bugs surely remain. *************** *** 25,28 **** --- 25,31 ---- if (fdefines) + See the file HINTS for special clues relating to GNU C++ configuration + and troubleshooting. + Introduction. *************** *** 44,48 **** only the files that are not shared with GNU CC are currently being distributed. If you do not have GNU CC yet, or your version is older ! than 1.34, you should take care of getting that first. GNU CC is available to sites which have anonymous ftp capability to prep.ai.mit.edu. Contact the Free Software Foundation for more --- 47,51 ---- only the files that are not shared with GNU CC are currently being distributed. If you do not have GNU CC yet, or your version is older ! than 1.35, you should take care of getting that first. GNU CC is available to sites which have anonymous ftp capability to prep.ai.mit.edu. Contact the Free Software Foundation for more *************** *** 93,98 **** In this directory, you should have the subdirectories ! gcc-1.34/ ! gcc/ linked to -> gcc-1.34 gcc-test/ --- 96,101 ---- In this directory, you should have the subdirectories ! gcc-1.35/ ! gcc/ linked to -> gcc-1.35 gcc-test/ *************** *** 117,122 **** If you got this tar file electronically instead of by tape, you ! TARFILE will be g++-1.43.2.tar, and it will unpack as src-g++. ! Other tar files will provide libg++ and gdb+. The GNU C++ library contains header files such as `stdio.h', --- 120,125 ---- If you got this tar file electronically instead of by tape, you ! TARFILE will be g++-1.35.0.tar, and it will unpack as src-g++. ! Other tar files will provide libg++ and gdb. The GNU C++ library contains header files such as `stdio.h', *************** *** 198,202 **** Michael Tiemann ! 3/30/89 For more information. --- 201,205 ---- Michael Tiemann ! 5/10/89 For more information. diff -rc2H /usr/gnu/ftp/pub/g++-1.35.0-/cplus-class.c src-g++/cplus-class.c *** /usr/gnu/ftp/pub/g++-1.35.0-/cplus-class.c Sun May 7 00:22:04 1989 --- src-g++/cplus-class.c Tue May 9 23:29:31 1989 *************** *** 875,878 **** --- 875,879 ---- int ref_sans_init = 0; tree friend_list = 0; + int nonprivate_method = 0; if (TREE_CODE (name) == TYPE_DECL) *************** *** 1035,1039 **** but do queue them if they have inline functions to worry about. */ ! if (DECL_IS_FRIEND_P (x)) { if (DECL_PENDING_INLINE_INFO (x)) --- 1036,1042 ---- but do queue them if they have inline functions to worry about. */ ! nonprivate_method |= ! TREE_PRIVATE (x); ! ! if (DECL_FRIEND_P (x)) { if (DECL_PENDING_INLINE_INFO (x)) *************** *** 1056,1060 **** Save this in auxilliary field for later overloading. */ if (DECL_VIRTUAL_P (x) ! || (all_virtual == 1 && ! DECL_IS_CONSTRUCTOR (x))) pending_virtuals = add_virtual_function (pending_virtuals, &has_virtual, x, --- 1059,1063 ---- Save this in auxilliary field for later overloading. */ if (DECL_VIRTUAL_P (x) ! || (all_virtual == 1 && ! DECL_CONSTRUCTOR_P (x))) pending_virtuals = add_virtual_function (pending_virtuals, &has_virtual, x, *************** *** 1350,1353 **** --- 1353,1361 ---- head = NULL_TREE; tail = NULL_TREE; + if (fn_fields + && nonprivate_method == 0 + && DECL_FRIEND_CLASSES (TYPE_NAME (t)) == NULL_TREE + && DECL_FRIENDLIST (TYPE_NAME (t)) == NULL_TREE) + warning ("all class member functions are private"); while (fn_fields) { *************** *** 2328,2332 **** cp->function = function; ! cp->arg = TREE_VALUE (tta); cp->u.bad_arg = 0; /* optimistic! */ --- 2336,2340 ---- cp->function = function; ! cp->arg = tta ? TREE_VALUE (tta) : NULL_TREE; cp->u.bad_arg = 0; /* optimistic! */ *************** *** 2554,2559 **** i -= 1; ! for (ttf = TYPE_ARG_TYPES (TREE_TYPE (cp[i].function)), ! tta = parms, index = 0; index < len; tta = TREE_CHAIN (tta), ttf = TREE_CHAIN (ttf), index++) --- 2562,2569 ---- i -= 1; ! tta = parms; ! if (DECL_STATIC_FUNCTION_P (cp[i].function)) ! tta = TREE_CHAIN (tta); ! for (ttf = TYPE_ARG_TYPES (TREE_TYPE (cp[i].function)), index = 0; index < len; tta = TREE_CHAIN (tta), ttf = TREE_CHAIN (ttf), index++) *************** *** 2594,2598 **** { int exact_conversions = cp[best].user; ! for (tta = parms, ttf = TYPE_ARG_TYPES (TREE_TYPE (cp[best].function)), index = 0; exact_conversions > 0; tta = TREE_CHAIN (tta), ttf = TREE_CHAIN (ttf), index++) --- 2604,2611 ---- { int exact_conversions = cp[best].user; ! tta = parms; ! if (DECL_STATIC_FUNCTION_P (cp[best].function)) ! tta = TREE_CHAIN (parms); ! for (ttf = TYPE_ARG_TYPES (TREE_TYPE (cp[best].function)), index = 0; exact_conversions > 0; tta = TREE_CHAIN (tta), ttf = TREE_CHAIN (ttf), index++) *************** *** 3381,3385 **** /* Not looking for friends here. */ ! if (TREE_CODE (TREE_TYPE (field)) == FUNCTION_TYPE) { field = TREE_CHAIN (field); --- 3394,3399 ---- /* Not looking for friends here. */ ! if (TREE_CODE (TREE_TYPE (field)) == FUNCTION_TYPE ! && ! DECL_STATIC_FUNCTION_P (field)) { field = TREE_CHAIN (field); *************** *** 3393,3397 **** visibility = compute_visibility (basetypes, field); ! if (instance_ptr) { instance_ptr = save_expr (convert_to_nonzero_pointer (TYPE_POINTER_TO (DECL_VCONTEXT (field)), instance_ptr)); --- 3407,3411 ---- visibility = compute_visibility (basetypes, field); ! if (instance_ptr && ! DECL_STATIC_FUNCTION_P (field)) { instance_ptr = save_expr (convert_to_nonzero_pointer (TYPE_POINTER_TO (DECL_VCONTEXT (field)), instance_ptr)); *************** *** 3411,3416 **** goto found; } ! else if (pass != 0) { n_inner_fields_searched++; function = field; --- 3425,3432 ---- goto found; } ! if (pass != 0) { + tree these_parms = parms; + n_inner_fields_searched++; function = field; *************** *** 3417,3421 **** cp->harshness = (unsigned short *)alloca ((len+1) * sizeof (short)); ! compute_conversion_costs (function, parms, cp, len); cp->b_or_d += b_or_d; if (cp->evil == 0) --- 3433,3439 ---- cp->harshness = (unsigned short *)alloca ((len+1) * sizeof (short)); ! if (DECL_STATIC_FUNCTION_P (field)) ! these_parms = TREE_CHAIN (these_parms); ! compute_conversion_costs (function, these_parms, cp, len); cp->b_or_d += b_or_d; if (cp->evil == 0) *************** *** 3449,3453 **** && cp->easy <= 1) { ! TREE_VALUE (parms) = cp->arg; goto found_and_ok; } --- 3467,3472 ---- && cp->easy <= 1) { ! if (! DECL_STATIC_FUNCTION_P (function)) ! TREE_VALUE (parms) = cp->arg; goto found_and_ok; } *************** *** 3534,3539 **** basetype = TREE_TYPE (TREE_TYPE (cp->arg)); - TREE_VALUE (parms) = cp->arg; function = cp->function; goto found_and_ok; } --- 3553,3559 ---- basetype = TREE_TYPE (TREE_TYPE (cp->arg)); function = cp->function; + if (! DECL_STATIC_FUNCTION_P (function)) + TREE_VALUE (parms) = cp->arg; goto found_and_ok; } *************** *** 3543,3550 **** char *tag_name, *buf; if (ever_seen) { if (saw_protected == 0 && saw_private == 0) ! report_type_mismatch (cp, parms, name_kind, err_name); else { --- 3563,3580 ---- char *tag_name, *buf; + if (DECL_STATIC_FUNCTION_P (cp->function)) + parms = TREE_CHAIN (parms); if (ever_seen) { if (saw_protected == 0 && saw_private == 0) ! { ! if (TREE_CODE (instance_ptr) == NOP_EXPR ! && TREE_OPERAND (instance_ptr, 0) == error_mark_node) ! error ("object missing in call to `%s::%s'", ! TYPE_NAME_STRING (TREE_TYPE (TREE_TYPE (instance_ptr))), ! IDENTIFIER_POINTER (name)); ! else ! report_type_mismatch (cp, parms, name_kind, err_name); ! } else { *************** *** 3629,3633 **** /* We do not pass FUNCTION into `actualparameterlist', because by now everything should be ok. If not, then we have a serious error. */ ! parms = tree_cons (NULL_TREE, convert_to_nonzero_pointer (TYPE_POINTER_TO (DECL_VCONTEXT (function)), TREE_VALUE (parms)), actualparameterlist (NULL_TREE, TREE_CHAIN (TYPE_ARG_TYPES (fntype)), TREE_CHAIN (parms), NULL_TREE)); /* See if there is a wrapper for this thing. */ --- 3659,3667 ---- /* We do not pass FUNCTION into `actualparameterlist', because by now everything should be ok. If not, then we have a serious error. */ ! if (DECL_STATIC_FUNCTION_P (function)) ! parms = actualparameterlist (NULL_TREE, TYPE_ARG_TYPES (fntype), ! TREE_CHAIN (parms), NULL_TREE); ! else ! parms = tree_cons (NULL_TREE, convert_to_nonzero_pointer (TYPE_POINTER_TO (DECL_VCONTEXT (function)), TREE_VALUE (parms)), actualparameterlist (NULL_TREE, TREE_CHAIN (TYPE_ARG_TYPES (fntype)), TREE_CHAIN (parms), NULL_TREE)); /* See if there is a wrapper for this thing. */ diff -rc2H /usr/gnu/ftp/pub/g++-1.35.0-/cplus-decl.c src-g++/cplus-decl.c *** /usr/gnu/ftp/pub/g++-1.35.0-/cplus-decl.c Sun May 7 01:02:25 1989 --- src-g++/cplus-decl.c Wed May 10 00:24:44 1989 *************** *** 1471,1475 **** Farm that case out here. */ if (TREE_CODE (newdecl) == FUNCTION_DECL ! && DECL_IS_CONSTRUCTOR (newdecl)) { tree type = TREE_TYPE (newdecl); --- 1471,1475 ---- Farm that case out here. */ if (TREE_CODE (newdecl) == FUNCTION_DECL ! && DECL_CONSTRUCTOR_P (newdecl)) { tree type = TREE_TYPE (newdecl); *************** *** 3394,3397 **** --- 3394,3403 ---- *argp = parmtypes; fndecl = build_decl (FUNCTION_DECL, fnname, type); + TREE_EXTERNAL (fndecl) = TREE_EXTERNAL (decl); + TREE_PUBLIC (fndecl) = TREE_PUBLIC (decl); + TREE_INLINE (fndecl) = TREE_INLINE (decl); + /* Keep G++ from thinking this function is unused. + It is only used to speed up search in name space. */ + TREE_USED (fndecl) = 1; DECL_LANG_SPECIFIC (fndecl) = DECL_LANG_SPECIFIC (decl); fndecl = pushdecl (fndecl); *************** *** 3440,3474 **** expand_decl_init (decl); ! if (IS_AGGR_TYPE (type) ! && TYPE_USES_VIRTUAL_BASECLASSES (type)) ! { ! tree result = init_vbase_pointers (type, build_unary_op (ADDR_EXPR, decl, 0)); ! tree tmp, basetype; ! ! if (result) ! expand_expr_stmt (build_compound_expr (result)); ! ! for (tmp = result; tmp; tmp = TREE_CHAIN (tmp)) ! { ! basetype = TREE_TYPE (TREE_TYPE (TREE_VALUE (tmp))); ! if (TYPE_NEEDS_CONSTRUCTING (basetype) ! && CLASSTYPE_MARKED3 (basetype) == 0) ! { ! tree addr = TREE_OPERAND (TREE_VALUE (tmp), 0); ! tree ref = build_indirect_ref (addr, 0); ! ! CLASSTYPE_MARKED3 (basetype) = 1; ! do_aggr_init (TREE_TYPE (ref), ref, NULL_TREE, 0); ! } ! } ! for (tmp = result; tmp; tmp = TREE_CHAIN (tmp)) ! { ! basetype = TREE_TYPE (TREE_TYPE (TREE_VALUE (tmp))); ! CLASSTYPE_MARKED3 (basetype) = 0; ! } ! #ifdef sparc ! expand_asm_operands (build_string (30, "! end of vbase initialization"), 0, 0, 0, 0, 0, 0); ! #endif ! } if (init0) --- 3446,3451 ---- expand_decl_init (decl); ! if (IS_AGGR_TYPE (type) && TYPE_USES_VIRTUAL_BASECLASSES (type)) ! do_aggr_vbase_init (type, build_unary_op (ADDR_EXPR, decl, 0)); if (init0) *************** *** 4157,4160 **** --- 4134,4142 ---- warning ("duplicate `volatile'"); virtualp = specbits & (1 << (int) RID_VIRTUAL); + if (virtualp && (specbits & (1 << (int) RID_STATIC))) + { + error ("member function cannot be declared both virtual and static"); + specbits &= ~ (1 << (int) RID_STATIC); + } friendp = specbits & (1 << (int) RID_FRIEND); specbits &= ~ ((1 << (int) RID_VIRTUAL) | (1 << (int) RID_FRIEND)); *************** *** 4383,4386 **** --- 4365,4373 ---- if (flags == DTOR_FLAG) { + if (specbits & (1 << RID_STATIC)) + { + error ("destructor cannot be static member function"); + specbits &= ~(1 << RID_STATIC); + } if (type != void_type_node) { *************** *** 4406,4409 **** --- 4393,4401 ---- else if (flags == WRAPPER_FLAG || flags == ANTI_WRAPPER_FLAG) { + if (specbits & (1 << RID_STATIC)) + { + error ("wrapper cannot be static member function"); + specbits &= ~(1 << RID_STATIC); + } if (decl_context == FIELD) { *************** *** 4416,4419 **** --- 4408,4416 ---- else if (flags == WRAPPER_PRED_FLAG) { + if (specbits & (1 << RID_STATIC)) + { + error ("wrapper predicate cannot be static member function"); + specbits &= ~(1 << RID_STATIC); + } if (TREE_CODE (type) != INTEGER_TYPE) { *************** *** 4431,4434 **** --- 4428,4436 ---- else /* its a constructor. */ { + if (specbits & (1 << RID_STATIC)) + { + error ("constructor cannot be static member function"); + specbits &= ~(1 << RID_STATIC); + } if (TYPE_MAIN_VARIANT (type) != TYPE_POINTER_TO (ctor_return_type)) { *************** *** 4757,4760 **** --- 4759,4763 ---- will have been taken care of in the SCOPE_REF case. */ if (TREE_CODE (type) == FUNCTION_TYPE + && ((specbits & (1 << (int) RID_STATIC)) == 0) && (decl_context == FIELD && friendp == 0 || decl_context == NORMAL && ctype != 0)) *************** *** 4951,4957 **** if (ctype == NULL_TREE) ctype = current_class_type; ! type = build_method_type (ctype, type); } decl = build_lang_decl (FUNCTION_DECL, declarator, type); TREE_INLINE (decl) = inlinep; } --- 4954,4963 ---- if (ctype == NULL_TREE) ctype = current_class_type; ! if ((specbits & (1 << (int) RID_STATIC)) == 0) ! type = build_method_type (ctype, type); } decl = build_lang_decl (FUNCTION_DECL, declarator, type); + if (ctype != NULL_TREE && TREE_CODE (type) == FUNCTION_TYPE) + DECL_STATIC_FUNCTION_P (decl) = 1; TREE_INLINE (decl) = inlinep; } *************** *** 4964,4969 **** else if (TYPE_SIZE (type) == 0) { ! error ("field `%s' has incomplete type", ! IDENTIFIER_POINTER (declarator)); type = error_mark_node; decl = NULL_TREE; --- 4970,4978 ---- else if (TYPE_SIZE (type) == 0) { ! if (declarator) ! error ("field `%s' has incomplete type", ! IDENTIFIER_POINTER (declarator)); ! else ! error ("field has incomplete type"); type = error_mark_node; decl = NULL_TREE; *************** *** 5011,5015 **** case out. See comments below for what each of the following calls is supposed to do. */ ! DECL_IS_CONSTRUCTOR (decl) = 1; grokclassfn (current_class_name, decl, flags, 0); grok_ctor_properties (decl); --- 5020,5024 ---- case out. See comments below for what each of the following calls is supposed to do. */ ! DECL_CONSTRUCTOR_P (decl) = 1; grokclassfn (current_class_name, decl, flags, 0); grok_ctor_properties (decl); *************** *** 5116,5125 **** } ! if (specbits & (1 << (int) RID_STATIC)) ! if (TREE_CODE (decl) == FUNCTION_DECL) ! { ! sorry ("function declared static in class"); ! TREE_PUBLIC (type) = 0; ! } } else if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE) --- 5125,5131 ---- } ! if (specbits & (1 << (int) RID_STATIC) ! && TREE_CODE (decl) != FUNCTION_DECL) ! TREE_PUBLIC (type) = 0; } else if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE) *************** *** 5155,5161 **** #else current_lang_name == lang_name_cplusplus ! && (IDENTIFIER_LENGTH (original_name) != 4 ! || IDENTIFIER_POINTER (original_name)[0] != 'm' ! || strcmp (IDENTIFIER_POINTER (original_name), "main")) #endif ) --- 5161,5171 ---- #else current_lang_name == lang_name_cplusplus ! && ! (IDENTIFIER_LENGTH (original_name) == 4 ! && IDENTIFIER_POINTER (original_name)[0] == 'm' ! && strcmp (IDENTIFIER_POINTER (original_name), "main") == 0) ! && ! (IDENTIFIER_LENGTH (original_name) > 10 ! && IDENTIFIER_POINTER (original_name)[0] == '_' ! && IDENTIFIER_POINTER (original_name)[1] == '_' ! && strncmp (IDENTIFIER_POINTER (original_name)+2, "builtin_", 8) == 0) #endif ) *************** *** 5166,5174 **** } } ! else if (TREE_CODE (type) == FUNCTION_TYPE) type = build_method_type (ctype, type); decl = build_lang_decl (FUNCTION_DECL, declarator, type); ! TREE_EXTERNAL (decl) = 1; /* Record presence of `static'. In C++, `inline' is like `static'. */ --- 5176,5187 ---- } } ! else if (TREE_CODE (type) == FUNCTION_TYPE ! && ((specbits & (1 << (int) RID_STATIC)) == 0)) type = build_method_type (ctype, type); decl = build_lang_decl (FUNCTION_DECL, declarator, type); ! if (TREE_CODE (type) == FUNCTION_TYPE ! && ((specbits & (1 << (int) RID_STATIC)) != 0)) ! DECL_STATIC_FUNCTION_P (decl) = 1; TREE_EXTERNAL (decl) = 1; /* Record presence of `static'. In C++, `inline' is like `static'. */ *************** *** 5204,5208 **** && flags == NO_SPECIAL) { ! DECL_IS_CONSTRUCTOR (decl) = 1; grok_ctor_properties (decl); } --- 5217,5221 ---- && flags == NO_SPECIAL) { ! DECL_CONSTRUCTOR_P (decl) = 1; grok_ctor_properties (decl); } *************** *** 5340,5355 **** } ! /* Must add the class instance variable up front. */ ! /* Right now we just make this a pointer. But later ! we may wish to make it special. */ ! type = TYPE_POINTER_TO (ctype); ! ! parm = build_decl (PARM_DECL, get_identifier (THIS_NAME), type); ! DECL_ARG_TYPE (parm) = type; ! /* We can make this a register, so long as we don't ! accidently complain if someone tries to take its address. */ ! TREE_REGDECL (parm) = 1; ! TREE_CHAIN (parm) = last_function_parms; ! last_function_parms = parm; if (flags == DTOR_FLAG) --- 5353,5371 ---- } ! if (TREE_CODE (fntype) == METHOD_TYPE) ! { ! /* Must add the class instance variable up front. */ ! /* Right now we just make this a pointer. But later ! we may wish to make it special. */ ! type = TYPE_POINTER_TO (ctype); ! ! parm = build_decl (PARM_DECL, get_identifier (THIS_NAME), type); ! DECL_ARG_TYPE (parm) = type; ! /* We can make this a register, so long as we don't ! accidently complain if someone tries to take its address. */ ! TREE_REGDECL (parm) = 1; ! TREE_CHAIN (parm) = last_function_parms; ! last_function_parms = parm; ! } if (flags == DTOR_FLAG) *************** *** 5396,5400 **** } #ifdef SOS ! else if (TYPE_DYNAMIC (ctype) && DECL_IS_CONSTRUCTOR (function)) { arg_types = tree_cons (NULL_TREE, build_pointer_type (ptr_type_node), --- 5412,5416 ---- } #ifdef SOS ! else if (TYPE_DYNAMIC (ctype) && DECL_CONSTRUCTOR_P (function)) { arg_types = tree_cons (NULL_TREE, build_pointer_type (ptr_type_node), *************** *** 5416,5421 **** else { DECL_NAME (function) = build_decl_overload (IDENTIFIER_POINTER (fn_name), ! arg_types); if (flags == TYPENAME_FLAG) TREE_TYPE (DECL_NAME (function)) = TREE_TYPE (fn_name); --- 5432,5441 ---- else { + tree these_arg_types = arg_types; + if (TREE_CODE (fntype) == FUNCTION_TYPE) + these_arg_types = tree_cons (NULL_TREE, TYPE_POINTER_TO (ctype), + arg_types); DECL_NAME (function) = build_decl_overload (IDENTIFIER_POINTER (fn_name), ! these_arg_types); if (flags == TYPENAME_FLAG) TREE_TYPE (DECL_NAME (function)) = TREE_TYPE (fn_name); *************** *** 5608,5612 **** int report_ambiguous; { ! tree parmtypes; int seen_classtype_parm = (type != NULL_TREE && TREE_CODE (type) == METHOD_TYPE); --- 5628,5632 ---- int report_ambiguous; { ! tree name, parmtypes; int seen_classtype_parm = (type != NULL_TREE && TREE_CODE (type) == METHOD_TYPE); *************** *** 5616,5620 **** /* Now we know the number of parameters, so build the real operator fnname. */ ! declarator = build_operator_fnname (declarator, TYPE_ARG_TYPES (type), 0); } else --- 5636,5640 ---- /* Now we know the number of parameters, so build the real operator fnname. */ ! name = build_operator_fnname (declarator, TYPE_ARG_TYPES (type), 0); } else *************** *** 5635,5639 **** error ("operator '%s' ambiguous, (default binary)", opname_tab[(int)TREE_CODE (TREE_VALUE (declarator))]); ! declarator = build_operator_fnname (declarator, NULL_TREE, 2); } else --- 5655,5659 ---- error ("operator '%s' ambiguous, (default binary)", opname_tab[(int)TREE_CODE (TREE_VALUE (declarator))]); ! name = build_operator_fnname (declarator, NULL_TREE, 2); } else *************** *** 5645,5653 **** break; default: ! declarator = build_operator_fnname (declarator, NULL_TREE, -1); break; } else if (TREE_CODE (TREE_PURPOSE (declarator)) == MODIFY_EXPR) ! declarator = build_operator_fnname (declarator, NULL_TREE, -1); else abort (); } --- 5665,5673 ---- break; default: ! name = build_operator_fnname (declarator, NULL_TREE, -1); break; } else if (TREE_CODE (TREE_PURPOSE (declarator)) == MODIFY_EXPR) ! name = build_operator_fnname (declarator, NULL_TREE, -1); else abort (); } *************** *** 5667,5674 **** if (is_decl && seen_classtype_parm == 0) ! error ("operator has no %s user-defined argument type", ! type == NULL_TREE ? "(default)" : ""); ! return declarator; } --- 5687,5700 ---- if (is_decl && seen_classtype_parm == 0) ! if (TREE_CODE (declarator) == OP_IDENTIFIER ! && (TREE_CODE (TREE_OPERAND (declarator, 0)) == NEW_EXPR ! || TREE_CODE (TREE_OPERAND (declarator, 0)) == DELETE_EXPR)) ! /* Global operators new and delete are not overloaded. */ ! TREE_OVERLOADED (name) = 0; ! else ! error ("operator has no %suser-defined argument type", ! type == NULL_TREE ? "(default) " : ""); ! return name; } *************** *** 5993,5996 **** --- 6019,6117 ---- } + /* When a function is declared with an initialializer, + do the right thing. Currently, there are two possibilities: + + class B + { + public: + // initialization possibility #1. + virtual void f () = 0; + int g (); + }; + + class D1 : B + { + public: + int d1; + // error, no f (); + }; + + class D2 : B + { + public: + int d2; + void f (); + }; + + class D3 : B + { + public: + int d3; + // initialization possibility #2 + void f () = B::f; + }; + + Returns the ASMSPEC that should be used for this function. + + */ + + static char * + grok_function_init (decl, init) + tree decl; + tree init; + { + /* An initializer for a function tells how this function should + be inherited. */ + tree type = TREE_TYPE (decl); + char *asmspec = 0; + + if (TREE_CODE (type) == FUNCTION_TYPE) + error_with_decl (decl, "initializer specified for non-member function `%s'"); + else if (! DECL_VIRTUAL_P (decl)) + error_with_decl (decl, "initializer specified for non-virtual method `%s'"); + else if (integer_zerop (init)) + { + CLASSTYPE_UNINHERITED_VIRTUALS (current_class_type) + = tree_cons (NULL_TREE, decl, CLASSTYPE_UNINHERITED_VIRTUALS (current_class_type)); + /* Mark this function as being "defined". */ + DECL_INITIAL (decl) = error_mark_node; + /* Give this node new rtl. */ + DECL_RTL (decl) = 0; + /* @@ Assume names have underscores. */ + asmspec = "_abort"; + } + else if (TREE_CODE (init) == MEMBER_REF + && TREE_OPERAND (init, 0) == NULL_TREE + && TREE_CODE (TREE_TYPE (init)) == METHOD_TYPE) + { + tree basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (init)); + tree basefn = TREE_OPERAND (init, 1); + if (TREE_CODE (basefn) != FUNCTION_DECL) + error_with_decl (decl, "non-method initializer invalid for method `%s'"); + else if (DECL_OFFSET (TYPE_NAME (basefn)) != 0) + sorry ("base member function from other than first base class"); + else + { + basetype = get_base_type (basetype, TYPE_METHOD_BASETYPE (type), 1); + if (basetype == error_mark_node) + ; + else if (basetype == 0) + error_with_aggr_type (basetype, + "type `%s' is not derived from type `%s'", + TYPE_NAME_STRING (TYPE_METHOD_BASETYPE (type))); + else + { + /* Mark this function as being defined, + and give it new rtl. */ + DECL_INITIAL (decl) = error_mark_node; + DECL_RTL (decl) = DECL_RTL (basefn); + } + } + } + else + error_with_decl (decl, "invalid initializer for virtual method `%s'"); + return asmspec; + } + /* Process the specs, declarator (NULL if omitted) and width (NULL if omitted) of a structure component, returning a FIELD_DECL node. *************** *** 6041,6053 **** else if (TREE_CODE (value) == FUNCTION_DECL) { ! /* An initializer for a function tells how this function should ! be inherited. */ ! if (integer_zerop (init)) ! { ! CLASSTYPE_UNINHERITED_VIRTUALS (current_class_type) ! = tree_cons (NULL_TREE, value, CLASSTYPE_UNINHERITED_VIRTUALS (current_class_type)); ! } ! else ! sorry ("initializer for member function"); } else --- 6162,6167 ---- else if (TREE_CODE (value) == FUNCTION_DECL) { ! asmspec = grok_function_init (value, init); ! init = NULL_TREE; } else *************** *** 7267,7271 **** /* Can't let this happen for constructors. */ ! if (DECL_IS_CONSTRUCTOR (current_function_decl)) { error ("can't redefine default return value for constructors"); --- 7381,7385 ---- /* Can't let this happen for constructors. */ ! if (DECL_CONSTRUCTOR_P (current_function_decl)) { error ("can't redefine default return value for constructors"); *************** *** 7435,7439 **** TREE_ANY_ASSIGNS_THIS (current_class_type) = 1; ! if (DECL_IS_CONSTRUCTOR (current_function_decl)) { if (call_poplevel) --- 7549,7553 ---- TREE_ANY_ASSIGNS_THIS (current_class_type) = 1; ! if (DECL_CONSTRUCTOR_P (current_function_decl)) { if (call_poplevel) *************** *** 7448,7452 **** current_function_just_assigned_this = 0; } ! else if (DECL_IS_CONSTRUCTOR (fndecl)) { tree cond, thenclause; --- 7562,7566 ---- current_function_just_assigned_this = 0; } ! else if (DECL_CONSTRUCTOR_P (fndecl)) { tree cond, thenclause; diff -rc2H /usr/gnu/ftp/pub/g++-1.35.0-/cplus-init.c src-g++/cplus-init.c *** /usr/gnu/ftp/pub/g++-1.35.0-/cplus-init.c Sat May 6 19:00:55 1989 --- src-g++/cplus-init.c Tue May 9 06:02:49 1989 *************** *** 43,48 **** void init_init_processing (); void finish_base_init (); ! void do_aggr_init (); void do_member_init (); tree build_virtual_init (); --- 43,49 ---- void init_init_processing (); void finish_base_init (); ! void do_aggr_vbase_init (); void do_member_init (); + void do_aggr_init (); tree build_virtual_init (); *************** *** 105,109 **** || ! current_function_just_assigned_this) return; ! if (DECL_IS_CONSTRUCTOR (current_function_decl)) { /* Constructors must wait until we are out of control --- 106,110 ---- || ! current_function_just_assigned_this) return; ! if (DECL_CONSTRUCTOR_P (current_function_decl)) { /* Constructors must wait until we are out of control *************** *** 141,145 **** /* We only care about constructors. */ ! assigns_this_p &= DECL_IS_CONSTRUCTOR (current_function_decl); /* First things to ever get initialized are the virtual base --- 142,146 ---- /* We only care about constructors. */ ! assigns_this_p &= DECL_CONSTRUCTOR_P (current_function_decl); /* First things to ever get initialized are the virtual base *************** *** 148,180 **** parts of this object, which are then initialized. */ if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) ! { ! tree result = init_vbase_pointers (current_class_type, current_class_decl); ! tree tmp; ! ! if (result) ! expand_expr_stmt (build_compound_expr (result)); ! ! for (tmp = result; tmp; tmp = TREE_CHAIN (tmp)) ! { ! basetype = TREE_TYPE (TREE_TYPE (TREE_VALUE (tmp))); ! if (TYPE_NEEDS_CONSTRUCTING (basetype) ! && CLASSTYPE_MARKED3 (basetype) == 0) ! { ! tree addr = TREE_OPERAND (TREE_VALUE (tmp), 0); ! tree ref = build_indirect_ref (addr, 0); ! ! CLASSTYPE_MARKED3 (basetype) = 1; ! do_aggr_init (current_class_type, ref, NULL_TREE, 0); ! } ! } ! for (tmp = result; tmp; tmp = TREE_CHAIN (tmp)) ! { ! basetype = TREE_TYPE (TREE_TYPE (TREE_VALUE (tmp))); ! CLASSTYPE_MARKED3 (basetype) = 0; ! } ! #ifdef sparc ! expand_asm_operands (build_string (30, "! end of vbase initialization"), 0, 0, 0, 0, 0, 0); ! #endif ! } for (; current_base_init_list; --- 149,153 ---- parts of this object, which are then initialized. */ if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) ! do_aggr_vbase_init (current_class_type, current_class_decl); for (; current_base_init_list; *************** *** 485,488 **** --- 458,501 ---- } + /* Initialize this object's virtual base class pointers. This is + not done by do_aggr_init, since it is only done at the top-level + of the object being constructed. */ + void + do_aggr_vbase_init (type, addr) + tree type; + tree addr; + { + if (TYPE_USES_VIRTUAL_BASECLASSES (type)) + { + tree result = init_vbase_pointers (type, addr); + tree basetype, tmp; + + if (result) + expand_expr_stmt (build_compound_expr (result)); + + for (tmp = result; tmp; tmp = TREE_CHAIN (tmp)) + { + basetype = TREE_TYPE (TREE_TYPE (TREE_VALUE (tmp))); + if (TYPE_NEEDS_CONSTRUCTING (basetype) + && CLASSTYPE_MARKED3 (basetype) == 0) + { + tree addr = TREE_OPERAND (TREE_VALUE (tmp), 0); + tree ref = build_indirect_ref (addr, 0); + + CLASSTYPE_MARKED3 (basetype) = 1; + do_aggr_init (TREE_TYPE (ref), ref, NULL_TREE, 0); + } + } + for (tmp = result; tmp; tmp = TREE_CHAIN (tmp)) + { + basetype = TREE_TYPE (TREE_TYPE (TREE_VALUE (tmp))); + CLASSTYPE_MARKED3 (basetype) = 0; + } + #ifdef sparc + expand_asm_operands (build_string (30, "! end of vbase initialization"), 0, 0, 0, 0, 0, 0); + #endif + } + } + /* If NAME is a viable field name for the aggregate DECL, and PARMS is a viable parameter list, then expand an _EXPR *************** *** 1137,1147 **** } - if (! current_class_decl) - { - error ("object missing for `%s::%s'", - IDENTIFIER_POINTER (cname), - IDENTIFIER_POINTER (name)); - return error_mark_node; - } if (TREE_CODE (name) == OP_IDENTIFIER) method_name = build_operator_fnname (name, parmlist, 1); --- 1150,1153 ---- *************** *** 1154,1158 **** base type is not aggregate. */ ! if (cname == current_class_name) decl = current_class_decl; else if (comptypes (type, current_class_type, 0)) --- 1160,1167 ---- base type is not aggregate. */ ! if (current_class_decl == NULL_TREE) ! decl = build (NOP_EXPR, TYPE_POINTER_TO (TREE_TYPE (TREE_TYPE (cname))), ! error_mark_node); ! else if (cname == current_class_name) decl = current_class_decl; else if (comptypes (type, current_class_type, 0)) *************** *** 1445,1457 **** tree basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (member)); tree addr = build_unary_op (ADDR_EXPR, base, 0); ! basetype = get_base_type (basetype, TREE_TYPE (base), 1); ! if (basetype == error_mark_node) ! return error_mark_node; ! if (basetype == 0) { ! error ("type `%s' is not derived from type `%s'", ! TYPE_NAME_STRING (basetype), ! TYPE_NAME_STRING (TREE_TYPE (base))); ! return error_mark_node; } addr = convert_to_nonzero_pointer (TYPE_POINTER_TO (basetype), addr); --- 1454,1469 ---- tree basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (member)); tree addr = build_unary_op (ADDR_EXPR, base, 0); ! if (basetype != TREE_TYPE (base)) { ! basetype = get_base_type (basetype, TREE_TYPE (base), 1); ! if (basetype == error_mark_node) ! return error_mark_node; ! if (basetype == 0) ! { ! error ("type `%s' is not derived from type `%s'", ! TYPE_NAME_STRING (basetype), ! TYPE_NAME_STRING (TREE_TYPE (base))); ! return error_mark_node; ! } } addr = convert_to_nonzero_pointer (TYPE_POINTER_TO (basetype), addr); *************** *** 1462,1474 **** tree basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (member)); tree addr = build_unary_op (ADDR_EXPR, base, 0); ! basetype = get_base_type (basetype, TREE_TYPE (base), 1); ! if (basetype == error_mark_node) ! return error_mark_node; ! if (basetype == 0) { ! error ("type `%s' is not derived from type `%s'", ! TYPE_NAME_STRING (basetype), ! TYPE_NAME_STRING (TREE_TYPE (base))); ! return error_mark_node; } addr = convert_to_nonzero_pointer (TYPE_POINTER_TO (basetype), addr); --- 1474,1490 ---- tree basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (member)); tree addr = build_unary_op (ADDR_EXPR, base, 0); ! if (basetype != TREE_TYPE (base)) { ! basetype = get_base_type (basetype, TREE_TYPE (base), 1); ! if (basetype == error_mark_node) ! return error_mark_node; ! if (basetype == 0) ! { ! basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (member)); ! error ("type `%s' is not derived from type `%s'", ! TYPE_NAME_STRING (basetype), ! TYPE_NAME_STRING (TREE_TYPE (base))); ! return error_mark_node; ! } } addr = convert_to_nonzero_pointer (TYPE_POINTER_TO (basetype), addr); *************** *** 1824,1828 **** else xref_friend (current_class_type, decl, ctype); ! DECL_IS_FRIEND_P (decl) = 1; } } --- 1840,1844 ---- else xref_friend (current_class_type, decl, ctype); ! DECL_FRIEND_P (decl) = 1; } } *************** *** 1854,1859 **** && IDENTIFIER_POINTER (declarator)[0] == 'm' && ! strcmp (IDENTIFIER_POINTER (declarator), "main")) ! /* raw "main" never gets overloaded. */ ! ; /* A global friend. @@ or possibly a friend from a base class ?!? */ --- 1870,1878 ---- && IDENTIFIER_POINTER (declarator)[0] == 'm' && ! strcmp (IDENTIFIER_POINTER (declarator), "main")) ! { ! /* raw "main" never gets overloaded, but it can become a friend. */ ! add_friend (current_class_type, decl); ! DECL_FRIEND_P (decl) = 1; ! } /* A global friend. @@ or possibly a friend from a base class ?!? */ *************** *** 1887,1891 **** "after declaration of non-overloaded `%s'"); } ! DECL_IS_FRIEND_P (decl) = 1; TREE_OVERLOADED (decl) = 1; TREE_OVERLOADED (declarator) = 1; --- 1906,1910 ---- "after declaration of non-overloaded `%s'"); } ! DECL_FRIEND_P (decl) = 1; TREE_OVERLOADED (decl) = 1; TREE_OVERLOADED (declarator) = 1; *************** *** 2237,2243 **** return rval; if (TYPE_NEEDS_CONSTRUCTING (type)) { - rval = save_expr (rval); if (has_array) rval = do_vec_init (decl, rval, --- 2256,2268 ---- return rval; + if (IS_AGGR_TYPE (type) + && (TYPE_USES_VIRTUAL_BASECLASSES (type) || TYPE_NEEDS_CONSTRUCTING (type))) + rval = save_expr (rval); + + if (IS_AGGR_TYPE (type) && TYPE_USES_VIRTUAL_BASECLASSES (type)) + do_aggr_vbase_init (type, rval); + if (TYPE_NEEDS_CONSTRUCTING (type)) { if (has_array) rval = do_vec_init (decl, rval, *************** *** 2937,2940 **** --- 2962,2967 ---- else if (TREE_CODE (exp) == OP_IDENTIFIER) error ("unresolved reference to user-defined operator"); + else if (TREE_CODE (exp) == COMPONENT_REF) + warning ("useless reference to a member function name, did you forget the ()?"); } else diff -rc2H /usr/gnu/ftp/pub/g++-1.35.0-/cplus-lex.c src-g++/cplus-lex.c *** /usr/gnu/ftp/pub/g++-1.35.0-/cplus-lex.c Sun May 7 01:02:22 1989 --- src-g++/cplus-lex.c Wed May 10 00:24:40 1989 *************** *** 2493,2497 **** } else if ((c == '-') && (c1 == '>')) ! { value = POINTSAT; goto done; } else if (c1 == '?') if (c == '<') --- 2493,2512 ---- } else if ((c == '-') && (c1 == '>')) ! { ! nextchar = skip_white_space (getc (finput)); ! if (nextchar == '(') ! { ! int next_c = skip_white_space (getc (finput)); ! if (next_c == ')') ! { ! nextchar = -1; ! value = POINTSAT_LEFT_RIGHT; ! goto done; ! } ! ungetc (next_c, finput); ! } ! value = POINTSAT; ! goto done; ! } else if (c1 == '?') if (c == '<') *************** *** 2613,2620 **** { DECL_LANGUAGE (t) = lang_cplusplus; ! if (code == FUNCTION_DECL) { TREE_OVERLOADED (name) = 1; } } else if (current_lang_name == lang_name_c) --- 2628,2644 ---- { DECL_LANGUAGE (t) = lang_cplusplus; ! #ifndef NO_EXTERN_C ! if (code == FUNCTION_DECL ! && ! (IDENTIFIER_LENGTH (name) == 4 ! && IDENTIFIER_POINTER (name)[0] == 'm' ! && strcmp (IDENTIFIER_POINTER (name), "main") == 0) ! && ! (IDENTIFIER_LENGTH (name) > 10 ! && IDENTIFIER_POINTER (name)[0] == '_' ! && IDENTIFIER_POINTER (name)[1] == '_' ! && strncmp (IDENTIFIER_POINTER (name)+2, "builtin_", 8) == 0)) { TREE_OVERLOADED (name) = 1; } + #endif } else if (current_lang_name == lang_name_c) diff -rc2H /usr/gnu/ftp/pub/g++-1.35.0-/cplus-method.c src-g++/cplus-method.c *** /usr/gnu/ftp/pub/g++-1.35.0-/cplus-method.c Sun May 7 01:02:21 1989 --- src-g++/cplus-method.c Wed May 10 00:24:42 1989 *************** *** 1045,1049 **** dump_type (TREE_TYPE (TREE_TYPE (fndecl)), &p); } ! else if (DECL_IS_CONSTRUCTOR (fndecl)) { #ifdef SOS --- 1045,1049 ---- dump_type (TREE_TYPE (TREE_TYPE (fndecl)), &p); } ! else if (DECL_CONSTRUCTOR_P (fndecl)) { #ifdef SOS diff -rc2H /usr/gnu/ftp/pub/g++-1.35.0-/cplus-parse.y src-g++/cplus-parse.y *** /usr/gnu/ftp/pub/g++-1.35.0-/cplus-parse.y Sun May 7 00:21:57 1989 --- src-g++/cplus-parse.y Tue May 9 06:02:47 1989 *************** *** 93,97 **** %token <ttype> AGGR %token DELETE NEW OVERLOAD PRIVATE PUBLIC PROTECTED THIS OPERATOR ! %token OPERATOR_PUSH OPERATOR_POP DYNAMIC PAREN_STAR_PAREN %token <itype> SCOPE --- 93,97 ---- %token <ttype> AGGR %token DELETE NEW OVERLOAD PRIVATE PUBLIC PROTECTED THIS OPERATOR ! %token OPERATOR_PUSH OPERATOR_POP DYNAMIC PAREN_STAR_PAREN POINTSAT_LEFT_RIGHT %token <itype> SCOPE *************** *** 420,424 **** if (current_class_name == NULL_TREE) errmsg = "base initializers not allowed here"; ! else if (! DECL_IS_CONSTRUCTOR (current_function_decl)) errmsg = "only constructors take base initializers"; --- 420,424 ---- if (current_class_name == NULL_TREE) errmsg = "base initializers not allowed here"; ! else if (! DECL_CONSTRUCTOR_P (current_function_decl)) errmsg = "only constructors take base initializers"; *************** *** 426,430 **** store_parm_decls (); ! if (DECL_IS_CONSTRUCTOR (current_function_decl)) { /* Make a contour for the initializer list. */ --- 426,430 ---- store_parm_decls (); ! if (DECL_CONSTRUCTOR_P (current_function_decl)) { /* Make a contour for the initializer list. */ *************** *** 482,487 **** basetype = get_base_type (TREE_TYPE (TREE_TYPE (scopes)), current_class_type, 1); ! if (basetype == 0 || basetype == error_mark_node) break; base = convert_to_nonzero_pointer (basetype, current_class_decl); --- 482,494 ---- basetype = get_base_type (TREE_TYPE (TREE_TYPE (scopes)), current_class_type, 1); ! if (basetype == error_mark_node) break; + if (basetype == 0) + { + error_with_aggr_type (TREE_TYPE (TREE_TYPE (scopes)), + "type `%s' is not derived from type `%s'", + TYPE_NAME_STRING (current_class_type)); + break; + } base = convert_to_nonzero_pointer (basetype, current_class_decl); *************** *** 820,826 **** else { ! error ("type `%s' is not derived from type `%s'", ! TYPE_NAME_STRING (TREE_TYPE ($1)), ! TYPE_NAME_STRING (basetype)); $$ = error_mark_node; } --- 827,833 ---- else { ! error_with_aggr_type (basetype, ! "type `%s' is not derived from type `%s'", ! TYPE_NAME_STRING (TREE_TYPE ($1))); $$ = error_mark_node; } *************** *** 843,846 **** --- 850,859 ---- $$ = current_class_decl; } + else if (current_function_decl + && DECL_STATIC_FUNCTION_P (current_function_decl)) + { + error ("`this' is unavailable for static member functions"); + $$ = error_mark_node; + } else { *************** *** 2517,2521 **** | OPERATOR POINTSAT %prec EMPTY { $$ = build_op_identifier (0, make_node (COMPONENT_REF)); } ! | OPERATOR POINTSAT '(' ')' { if (yychar == YYEMPTY) --- 2530,2534 ---- | OPERATOR POINTSAT %prec EMPTY { $$ = build_op_identifier (0, make_node (COMPONENT_REF)); } ! | OPERATOR POINTSAT_LEFT_RIGHT { if (yychar == YYEMPTY) diff -rc2H /usr/gnu/ftp/pub/g++-1.35.0-/cplus-search.c src-g++/cplus-search.c *** /usr/gnu/ftp/pub/g++-1.35.0-/cplus-search.c Sat May 6 18:39:30 1989 --- src-g++/cplus-search.c Mon May 8 22:35:25 1989 *************** *** 597,600 **** --- 597,601 ---- enum visibility_type visibility = visibility_public; tree types, type; + tree context = DECL_FIELD_CONTEXT (field); /* Virtual function tables are never private. *************** *** 604,616 **** /* Make these special cases fast. */ ! if (TREE_FIELD_PUBLIC (field)) ! return visibility_public; ! else if (TREE_FIELD_PROTECTED (field)) ! return visibility_protected; ! else if (TREE_FIELD_PRIVATE (field)) ! return visibility_private; /* Member function manipulating its own members. */ ! if (current_class_type == DECL_FIELD_CONTEXT (field)) PUBLIC_RETURN; --- 605,620 ---- /* Make these special cases fast. */ ! if (TREE_VALUE (basetypes) == current_class_type) ! { ! if (TREE_FIELD_PUBLIC (field)) ! return visibility_public; ! else if (TREE_FIELD_PROTECTED (field)) ! return visibility_protected; ! else if (TREE_FIELD_PRIVATE (field)) ! return visibility_private; ! } /* Member function manipulating its own members. */ ! if (current_class_type == context) PUBLIC_RETURN; *************** *** 623,627 **** /* Friend function manipulating members it gets (for being a friend). */ ! if (is_friend (DECL_FIELD_CONTEXT (field), current_function_decl)) PUBLIC_RETURN; --- 627,631 ---- /* Friend function manipulating members it gets (for being a friend). */ ! if (is_friend (context, current_function_decl)) PUBLIC_RETURN; *************** *** 628,633 **** /* Inner than that, without special visibility, ! protected members are ok if current_class_type is derived ! from the type of the object. private members are not ok. */ --- 632,639 ---- /* Inner than that, without special visibility, ! protected members are ok if type of object is current_class_type ! is derived therefrom. This means that if the type of the object ! is a base type for our current class type, we cannot access ! protected members. private members are not ok. */ *************** *** 639,644 **** if (TREE_PROTECTED (field)) { ! type = get_base_type (DECL_FIELD_CONTEXT (field), current_class_type, 0); ! if (type) PUBLIC_RETURN; else --- 645,650 ---- if (TREE_PROTECTED (field)) { ! if (context == current_class_type ! || (type = get_base_type (current_class_type, context, 0))) PUBLIC_RETURN; else *************** *** 650,654 **** { /* Friend function manipulating members it gets (for being a friend). */ ! if (is_friend (DECL_FIELD_CONTEXT (field), current_function_decl)) PUBLIC_RETURN; --- 656,660 ---- { /* Friend function manipulating members it gets (for being a friend). */ ! if (is_friend (context, current_function_decl)) PUBLIC_RETURN; *************** *** 673,677 **** || (visibility == visibility_protected && current_class_type ! && get_base_type (DECL_FIELD_CONTEXT (field), current_class_type, 0))) PUBLIC_RETURN; if (visibility == visibility_protected) --- 679,683 ---- || (visibility == visibility_protected && current_class_type ! && get_base_type (context, current_class_type, 0))) PUBLIC_RETURN; if (visibility == visibility_protected) *************** *** 688,692 **** PUBLIC_RETURN; if (TREE_PRIVATE (field)) ! if (type == DECL_FIELD_CONTEXT (field)) PUBLIC_RETURN; else --- 694,698 ---- PUBLIC_RETURN; if (TREE_PRIVATE (field)) ! if (type == context) PUBLIC_RETURN; else *************** *** 726,730 **** #if 0 if (current_class_type ! && get_base_type (DECL_FIELD_CONTEXT (field), current_class_type, 0)) #else if (current_class_type && value_member (current_class_type, basetypes)) --- 732,736 ---- #if 0 if (current_class_type ! && get_base_type (context, current_class_type, 0)) #else if (current_class_type && value_member (current_class_type, basetypes)) *************** *** 758,765 **** a private base class. */ - type = DECL_FIELD_CONTEXT (field); if (! TREE_PRIVATE (field)) for (i = 1; i <= n_baselinks; i++) ! if (CLASSTYPE_MAIN_VARIANT (CLASSTYPE_THIS_BASECLASS (current_class_type, i)) == type) PUBLIC_RETURN; } --- 764,770 ---- a private base class. */ if (! TREE_PRIVATE (field)) for (i = 1; i <= n_baselinks; i++) ! if (CLASSTYPE_MAIN_VARIANT (CLASSTYPE_THIS_BASECLASS (current_class_type, i)) == context) PUBLIC_RETURN; } *************** *** 1829,1832 **** --- 1834,1840 ---- } + /* Sometimes this needs to clear both 3 and 4. Other times, + just 4, but optimizer should make both equivalent + (though it does not currently). */ static void dfs_clear_vbase_slots (type) *************** *** 1834,1837 **** --- 1842,1846 ---- { CLASSTYPE_SEARCH_SLOT (type) = 0; + CLASSTYPE_MARKED3 (type) = 0; CLASSTYPE_MARKED4 (type) = 0; } *************** *** 2356,2360 **** else { ! if (old) warning ("shadowing member `%s' with member function", IDENTIFIER_POINTER (TREE_PURPOSE (fields))); --- 2365,2372 ---- else { ! /* Only complain if we shadow something we can access. */ ! if (old && (DECL_CONTEXT (old) == current_class_type ! || ! TREE_PRIVATE (old))) ! /* Should figure out visibility more accurately. */ warning ("shadowing member `%s' with member function", IDENTIFIER_POINTER (TREE_PURPOSE (fields))); diff -rc2H /usr/gnu/ftp/pub/g++-1.35.0-/cplus-tree.h src-g++/cplus-tree.h *** /usr/gnu/ftp/pub/g++-1.35.0-/cplus-tree.h Sat May 6 21:40:01 1989 --- src-g++/cplus-tree.h Tue May 9 06:00:26 1989 *************** *** 379,383 **** unsigned in_aggr_attr : 1; unsigned is_friend_attr : 1; ! unsigned dummy15 : 14; } decl_flags; tree original_name; --- 379,384 ---- unsigned in_aggr_attr : 1; unsigned is_friend_attr : 1; ! unsigned is_static_function_attr : 1; ! unsigned dummy13 : 13; } decl_flags; tree original_name; *************** *** 397,401 **** /* For FUNCTION_DECLs: nonzero means that this function is a constructor. */ ! #define DECL_IS_CONSTRUCTOR(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.is_constructor) /* For FUNCTION_DECLS: nonzero means that the constructor --- 398,402 ---- /* For FUNCTION_DECLs: nonzero means that this function is a constructor. */ ! #define DECL_CONSTRUCTOR_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.is_constructor) /* For FUNCTION_DECLS: nonzero means that the constructor *************** *** 417,421 **** friend declaration, and should not be added to the list of member functions for this class. */ ! #define DECL_IS_FRIEND_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.is_friend_attr) /* Nonzero for FIELD_DECL node means that this FIELD_DECL is --- 418,426 ---- friend declaration, and should not be added to the list of member functions for this class. */ ! #define DECL_FRIEND_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.is_friend_attr) ! ! /* Nonzero for FUNCTION_DECL means that this decl is a static ! member function. */ ! #define DECL_STATIC_FUNCTION_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.is_static_function_attr) /* Nonzero for FIELD_DECL node means that this FIELD_DECL is diff -rc2H /usr/gnu/ftp/pub/g++-1.35.0-/cplus-typeck.c src-g++/cplus-typeck.c *** /usr/gnu/ftp/pub/g++-1.35.0-/cplus-typeck.c Sun May 7 00:21:54 1989 --- src-g++/cplus-typeck.c Tue May 9 17:37:02 1989 *************** *** 96,104 **** /* Print an error message stemming from an invalid use of an ! aggregate type. */ void ! error_with_aggr_type (type, msg) tree type; char *msg; { tree name = TYPE_NAME (type); --- 96,109 ---- /* Print an error message stemming from an invalid use of an ! aggregate type. ! ! TYPE is the type which draws the error. ! MSG is the message to print. ! ARG is an optional argument which may provide more information. */ void ! error_with_aggr_type (type, msg, arg) tree type; char *msg; + int arg; { tree name = TYPE_NAME (type); *************** *** 105,109 **** if (TREE_CODE (name) == TYPE_DECL) name = DECL_NAME (name); ! error (msg, IDENTIFIER_POINTER (name)); } --- 110,114 ---- if (TREE_CODE (name) == TYPE_DECL) name = DECL_NAME (name); ! error (msg, IDENTIFIER_POINTER (name), arg); } *************** *** 144,148 **** } } ! else error ("since type `%s' has uninheritable virtual functions"); } --- 149,153 ---- } } ! else error ("since type `%s' has uninheritable virtual functions", typename); } *************** *** 206,215 **** } ! if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) ! error (errmsg, IDENTIFIER_POINTER (TYPE_NAME (type))); ! else ! /* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL. */ ! error ("invalid use of incomplete typedef `%s'", ! TYPE_NAME_STRING (type)); } } --- 211,215 ---- } ! error_with_aggr_type (type, errmsg); } } *************** *** 1136,1140 **** if (is_aggr_typedef_or_else (types)) { ! type = TREE_TYPE (TREE_TYPE (types)); switch (TREE_CODE (datum)) --- 1136,1151 ---- if (is_aggr_typedef_or_else (types)) { ! tree basetype = TREE_TYPE (TREE_TYPE (types)); ! if (basetype != type) ! { ! basetype = get_base_type (basetype, type, 1); ! if (basetype == error_mark_node) ! return error_mark_node; ! if (basetype == 0) ! { ! error_with_aggr_type (basetype, "type `%s' is not derived from type `%s'", TYPE_NAME_STRING (type)); ! return error_mark_node; ! } ! } switch (TREE_CODE (datum)) *************** *** 1261,1265 **** } ! /* Like `build_component_ref, but uses an already found field. */ tree build_component_ref_1 (datum, field, protect) --- 1272,1277 ---- } ! /* Like `build_component_ref, but uses an already found field. ! Must compute visibility for C_C_D. Otherwise, ok. */ tree build_component_ref_1 (datum, field, protect) *************** *** 1299,1308 **** return field; ! if (datum == C_C_D ! #if 0 ! || something for multiple inheritance ! #endif ! ) ! if (TREE_FIELD_PRIVATE (field)) { error_with_decl (field, "field `%s' is private"); --- 1311,1321 ---- return field; ! if (datum == C_C_D && ! TREE_FIELD_PUBLIC (field)) ! { ! enum visibility_type visibility ! = compute_visibility (build_tree_list (NULL_TREE, current_class_type), ! field); ! ! if (visibility == visibility_private) { error_with_decl (field, "field `%s' is private"); *************** *** 1309,1312 **** --- 1322,1331 ---- return error_mark_node; } + else if (visibility == visibility_protected) + { + error_with_decl (field, "field `%s' is protected"); + return error_mark_node; + } + } ref = build (COMPONENT_REF, TREE_TYPE (field), datum, field); *************** *** 1941,1947 **** be instantiated by the type given by TYPE. If TYPE is also NULL, the tree type of VAL is ERROR_MARK_NODE. */ ! if (TREE_TYPE (val) == unknown_type_node) ! if (TREE_CODE (val) == TREE_LIST ! && TREE_CHAIN (val) == NULL_TREE) { /* Instantiates automatically. */ --- 1960,1967 ---- be instantiated by the type given by TYPE. If TYPE is also NULL, the tree type of VAL is ERROR_MARK_NODE. */ ! if (TREE_TYPE (val) == unknown_type_node ! || (TREE_CODE (TREE_TYPE (val)) == OFFSET_TYPE ! && TREE_TYPE (TREE_TYPE (val)) == unknown_type_node)) ! if (TREE_CODE (val) == TREE_LIST && TREE_CHAIN (val) == NULL_TREE) { /* Instantiates automatically. */ *************** *** 3628,3632 **** && (TYPE_OVERLOADS_METHOD_CALL_EXPR (DECL_CONTEXT (t)) || TYPE_NEEDS_WRAPPER (DECL_CONTEXT (t))) ! && ! DECL_IS_CONSTRUCTOR (t))) { offset = copy_node (DECL_VINDEX (t)); --- 3648,3652 ---- && (TYPE_OVERLOADS_METHOD_CALL_EXPR (DECL_CONTEXT (t)) || TYPE_NEEDS_WRAPPER (DECL_CONTEXT (t))) ! && ! DECL_CONSTRUCTOR_P (t))) { offset = copy_node (DECL_VINDEX (t)); *************** *** 4226,4230 **** } ! if (TREE_TYPE (value) == unknown_type_node) { if (TREE_CODE (value) == OP_IDENTIFIER) --- 4246,4252 ---- } ! if (TREE_TYPE (value) == unknown_type_node ! || (TREE_CODE (TREE_TYPE (value)) == OFFSET_TYPE ! && TREE_TYPE (TREE_TYPE (value)) == unknown_type_node)) { if (TREE_CODE (value) == OP_IDENTIFIER) *************** *** 4452,4456 **** when the type of RHS is not yet known, i.e. its type is inherited from LHS. */ ! if (TREE_TYPE (rhs) == unknown_type_node) { if (TREE_CODE (rhs) == OP_IDENTIFIER) --- 4474,4480 ---- when the type of RHS is not yet known, i.e. its type is inherited from LHS. */ ! if (TREE_TYPE (rhs) == unknown_type_node ! || (TREE_CODE (TREE_TYPE (rhs)) == OFFSET_TYPE ! && TREE_TYPE (TREE_TYPE (rhs)) == unknown_type_node)) { if (TREE_CODE (rhs) == OP_IDENTIFIER) *************** *** 5150,5153 **** --- 5174,5184 ---- init = TREE_VALUE (init); } + else if (TREE_TYPE (init) != 0 + && TREE_CODE (TREE_TYPE (init)) == OFFSET_TYPE) + { + /* Use the type of our variable to instantiate + the type of our initializer. */ + init = instantiate_type (type, init, 1); + } else abort (); } *************** *** 5632,5636 **** if (retval == NULL_TREE) { ! if (DECL_IS_CONSTRUCTOR (current_function_decl)) retval = current_class_decl; else if (result != NULL_TREE) --- 5663,5667 ---- if (retval == NULL_TREE) { ! if (DECL_CONSTRUCTOR_P (current_function_decl)) retval = current_class_decl; else if (result != NULL_TREE) *************** *** 5675,5679 **** /* Watch out for constructors, which "return" aggregates via initialization, but which otherwise "return" a pointer. */ ! if (DECL_IS_CONSTRUCTOR (current_function_decl)) { if (retval != current_class_decl) --- 5706,5710 ---- /* Watch out for constructors, which "return" aggregates via initialization, but which otherwise "return" a pointer. */ ! if (DECL_CONSTRUCTOR_P (current_function_decl)) { if (retval != current_class_decl) diff -rc2H /usr/gnu/ftp/pub/g++-1.35.0-/expr.c src-g++/expr.c *** /usr/gnu/ftp/pub/g++-1.35.0-/expr.c Sun May 7 00:21:49 1989 --- src-g++/expr.c Tue May 9 06:02:45 1989 *************** *** 3078,3082 **** if (TREE_CODE (func) == ADDR_EXPR && TREE_CODE (TREE_OPERAND (func, 0)) == FUNCTION_DECL ! && DECL_IS_CONSTRUCTOR (TREE_OPERAND (func, 0))) { type = TYPE_POINTER_TO (type); --- 3078,3082 ---- if (TREE_CODE (func) == ADDR_EXPR && TREE_CODE (TREE_OPERAND (func, 0)) == FUNCTION_DECL ! && DECL_CONSTRUCTOR_P (TREE_OPERAND (func, 0))) { type = TYPE_POINTER_TO (type); diff -rc2H /usr/gnu/ftp/pub/g++-1.35.0-/g++.texinfo src-g++/g++.texinfo *** /usr/gnu/ftp/pub/g++-1.35.0-/g++.texinfo Fri May 5 12:20:50 1989 --- src-g++/g++.texinfo Tue May 9 13:36:32 1989 *************** *** 1355,1359 **** GNU CC} ! The GUN C++ compiler uses its own crt0.c because initialization for C++ is more involved than it is for C. Namely, constructors for static objects must be run before `main' is called, and destructors must be run --- 1355,1359 ---- GNU CC} ! The GNU C++ compiler uses its own crt0.c because initialization for C++ is more involved than it is for C. Namely, constructors for static objects must be run before `main' is called, and destructors must be run *************** *** 2931,2947 **** // Create a C++ equivalent of ``realloc''. inline void *__user_new (int new_size, void *old_ptr) ! { return (void *) realloc (old_ptr, new_size); ! } char *manipulate_string (char *string) ! { int len = strlen (string) + 1; char *s = strcpy (new char [len], string); // ... ! char *t = new {s} char [len * 2]; return strcat (t, string); ! } In this example, @code{__user_new} is defined to provide @code{realloc}-style --- 2931,2949 ---- // Create a C++ equivalent of ``realloc''. inline void *__user_new (int new_size, void *old_ptr) ! @{ return (void *) realloc (old_ptr, new_size); ! @} char *manipulate_string (char *string) ! @{ int len = strlen (string) + 1; char *s = strcpy (new char [len], string); // ... ! char *t = new @{s@} char [len * 2]; return strcat (t, string); ! @} ! @end example ! @end group In this example, @code{__user_new} is defined to provide @code{realloc}-style *************** *** 3069,3072 **** --- 3071,3075 ---- @node Switch Ranges,, Wrappers, Extensions + @section Switch Ranges A GNU C++ extension to the switch statement permits range specification *************** *** 3074,3090 **** a function parameter's ``character class:'' @example print_char_class (char c) ! { switch (c) ! { case 'a'..'z': printf ("lower case\n"); break; case 'A'..'Z': printf ("upper case\n"); break; case '0'..'9': printf ("digit\n"); break; ! default: printf ("other\n"); ! } ! } ! @end example ! Duplicate, overlapping case values and empty ranges are detected and rejected by the compiler. --- 3077,3095 ---- a function parameter's ``character class:'' + @group @example print_char_class (char c) ! @{ switch (c) ! @{ case 'a'..'z': printf ("lower case\n"); break; case 'A'..'Z': printf ("upper case\n"); break; case '0'..'9': printf ("digit\n"); break; ! default: printf ("other\n"); ! @} ! @} ! @end example ! @end group ! Duplicate, overlapping case values and empty ranges are detected and rejected by the compiler. *************** *** 3145,3162 **** @example struct A ! { A (); int operator+ (A&); operator int (); ! }; struct B ! { B (); operator int (); ! }; main () ! { A a; B b; --- 3150,3167 ---- @example struct A ! @{ A (); int operator+ (A&); operator int (); ! @}; struct B ! @{ B (); operator int (); ! @}; main () ! @{ A a; B b; *************** *** 3164,3168 **** int i = a + b; // some more stuff... ! } @end example --- 3169,3173 ---- int i = a + b; // some more stuff... ! @} @end example *************** *** 3176,3187 **** @example struct A ! { A (); A& operator *(); // The indirection operator A& operator *(A&); // The multiply operator ! }; main () ! { A a; A& (*pf)(A*, A&); --- 3181,3192 ---- @example struct A ! @{ A (); A& operator *(); // The indirection operator A& operator *(A&); // The multiply operator ! @}; main () ! @{ A a; A& (*pf)(A*, A&); *************** *** 3188,3192 **** pf = a.operator*; // Which operator?? ! } @end example --- 3193,3197 ---- pf = a.operator*; // Which operator?? ! @} @end example *************** *** 3224,3228 **** @section Avoid extra constructor call when returning classes from functions. ! Consider a function @code{m ()} with a return value of class @coce{X}. @example --- 3229,3233 ---- @section Avoid extra constructor call when returning classes from functions. ! Consider a function @code{m ()} with a return value of class @code{X}. @example diff -rc2H /usr/gnu/ftp/pub/g++-1.35.0-/integrate.c src-g++/integrate.c *** /usr/gnu/ftp/pub/g++-1.35.0-/integrate.c Sun May 7 00:21:44 1989 --- src-g++/integrate.c Sun May 7 08:50:11 1989 *************** *** 616,620 **** if (list_length (parms) != nargs) return (rtx)-1; - #if 0 /* Also check that the parms type match. Since the appropriate conversions or default promotions have already been applied, --- 616,619 ---- *************** *** 632,638 **** /* If they are block mode, the types should match exactly. */ if (mode == BLKmode && TREE_TYPE (arg) != TREE_TYPE (formal)) ! return (rtx)-1; } - #endif /* Make a binding contour to keep inline destructors called at --- 631,639 ---- /* If they are block mode, the types should match exactly. */ if (mode == BLKmode && TREE_TYPE (arg) != TREE_TYPE (formal)) ! { ! abort (); ! return (rtx)-1; ! } } /* Make a binding contour to keep inline destructors called at *************** *** 699,702 **** --- 700,707 ---- copy = copy_to_reg (copy); } + /* If passed mode != nominal mode, COPY is now the passed mode. + Convert it to the nominal mode (i.e. truncate it). */ + if (tmode != imode) + copy = convert_to_mode (imode, copy); arg_vec[i] = copy; } *************** *** 1928,1932 **** restore_reg_data (FIRST_PARM_INSN (head)); ! expand_function_end (); for (last = head; NEXT_INSN (last); last = NEXT_INSN (last)) --- 1933,1937 ---- restore_reg_data (FIRST_PARM_INSN (head)); ! expand_function_end (DECL_SOURCE_FILE (fndecl), DECL_SOURCE_LINE (fndecl)); for (last = head; NEXT_INSN (last); last = NEXT_INSN (last)) diff -rc2H /usr/gnu/ftp/pub/g++-1.35.0-/varasm.c src-g++/varasm.c *** /usr/gnu/ftp/pub/g++-1.35.0-/varasm.c Sun May 7 00:35:38 1989 --- src-g++/varasm.c Sun May 7 08:57:11 1989 *************** *** 144,148 **** int decode_reg_name (asmspec) ! tree asmspec; { if (asmspec != 0) --- 144,148 ---- int decode_reg_name (asmspec) ! char *asmspec; { if (asmspec != 0) *************** *** 151,159 **** extern char *reg_names[]; - if (TREE_CODE (asmspec) != STRING_CST) - abort (); for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) ! if (!strcmp (TREE_STRING_POINTER (asmspec), ! reg_names[i])) break; --- 151,156 ---- extern char *reg_names[]; for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) ! if (!strcmp (asmspec, reg_names[i])) break; *************** *** 176,180 **** make_decl_rtl (decl, asmspec, top_level) tree decl; ! tree asmspec; int top_level; { --- 173,177 ---- make_decl_rtl (decl, asmspec, top_level) tree decl; ! char *asmspec; int top_level; { *************** *** 184,191 **** if (reg_number == -2) { ! name = (char *) obstack_alloc (saveable_obstack, ! strlen (TREE_STRING_POINTER (asmspec)) + 2); name[0] = '*'; ! strcpy (&name[1], TREE_STRING_POINTER (asmspec)); } --- 181,187 ---- if (reg_number == -2) { ! name = (char *) obstack_alloc (saveable_obstack, strlen (asmspec) + 2); name[0] = '*'; ! strcpy (&name[1], asmspec); }